123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- From: Johan Almbladh <[email protected]>
- Date: Tue, 5 Oct 2021 18:54:08 +0200
- Subject: [PATCH] mips: bpf: Remove old BPF JIT implementations
- This patch removes the old 32-bit cBPF and 64-bit eBPF JIT implementations.
- They are replaced by a new eBPF implementation that supports both 32-bit
- and 64-bit MIPS CPUs.
- Signed-off-by: Johan Almbladh <[email protected]>
- ---
- delete mode 100644 arch/mips/net/bpf_jit.c
- delete mode 100644 arch/mips/net/bpf_jit.h
- delete mode 100644 arch/mips/net/bpf_jit_asm.S
- delete mode 100644 arch/mips/net/ebpf_jit.c
- --- a/arch/mips/net/bpf_jit.h
- +++ /dev/null
- @@ -1,81 +0,0 @@
- -/* SPDX-License-Identifier: GPL-2.0-only */
- -/*
- - * Just-In-Time compiler for BPF filters on MIPS
- - *
- - * Copyright (c) 2014 Imagination Technologies Ltd.
- - * Author: Markos Chandras <[email protected]>
- - */
- -
- -#ifndef BPF_JIT_MIPS_OP_H
- -#define BPF_JIT_MIPS_OP_H
- -
- -/* Registers used by JIT */
- -#define MIPS_R_ZERO 0
- -#define MIPS_R_V0 2
- -#define MIPS_R_A0 4
- -#define MIPS_R_A1 5
- -#define MIPS_R_T4 12
- -#define MIPS_R_T5 13
- -#define MIPS_R_T6 14
- -#define MIPS_R_T7 15
- -#define MIPS_R_S0 16
- -#define MIPS_R_S1 17
- -#define MIPS_R_S2 18
- -#define MIPS_R_S3 19
- -#define MIPS_R_S4 20
- -#define MIPS_R_S5 21
- -#define MIPS_R_S6 22
- -#define MIPS_R_S7 23
- -#define MIPS_R_SP 29
- -#define MIPS_R_RA 31
- -
- -/* Conditional codes */
- -#define MIPS_COND_EQ 0x1
- -#define MIPS_COND_GE (0x1 << 1)
- -#define MIPS_COND_GT (0x1 << 2)
- -#define MIPS_COND_NE (0x1 << 3)
- -#define MIPS_COND_ALL (0x1 << 4)
- -/* Conditionals on X register or K immediate */
- -#define MIPS_COND_X (0x1 << 5)
- -#define MIPS_COND_K (0x1 << 6)
- -
- -#define r_ret MIPS_R_V0
- -
- -/*
- - * Use 2 scratch registers to avoid pipeline interlocks.
- - * There is no overhead during epilogue and prologue since
- - * any of the $s0-$s6 registers will only be preserved if
- - * they are going to actually be used.
- - */
- -#define r_skb_hl MIPS_R_S0 /* skb header length */
- -#define r_skb_data MIPS_R_S1 /* skb actual data */
- -#define r_off MIPS_R_S2
- -#define r_A MIPS_R_S3
- -#define r_X MIPS_R_S4
- -#define r_skb MIPS_R_S5
- -#define r_M MIPS_R_S6
- -#define r_skb_len MIPS_R_S7
- -#define r_s0 MIPS_R_T4 /* scratch reg 1 */
- -#define r_s1 MIPS_R_T5 /* scratch reg 2 */
- -#define r_tmp_imm MIPS_R_T6 /* No need to preserve this */
- -#define r_tmp MIPS_R_T7 /* No need to preserve this */
- -#define r_zero MIPS_R_ZERO
- -#define r_sp MIPS_R_SP
- -#define r_ra MIPS_R_RA
- -
- -#ifndef __ASSEMBLY__
- -
- -/* Declare ASM helpers */
- -
- -#define DECLARE_LOAD_FUNC(func) \
- - extern u8 func(unsigned long *skb, int offset); \
- - extern u8 func##_negative(unsigned long *skb, int offset); \
- - extern u8 func##_positive(unsigned long *skb, int offset)
- -
- -DECLARE_LOAD_FUNC(sk_load_word);
- -DECLARE_LOAD_FUNC(sk_load_half);
- -DECLARE_LOAD_FUNC(sk_load_byte);
- -
- -#endif
- -
- -#endif /* BPF_JIT_MIPS_OP_H */
- --- a/arch/mips/net/bpf_jit_asm.S
- +++ /dev/null
- @@ -1,285 +0,0 @@
- -/*
- - * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF
- - * compiler.
- - *
- - * Copyright (C) 2015 Imagination Technologies Ltd.
- - * Author: Markos Chandras <[email protected]>
- - *
- - * This program is free software; you can redistribute it and/or modify it
- - * under the terms of the GNU General Public License as published by the
- - * Free Software Foundation; version 2 of the License.
- - */
- -
- -#include <asm/asm.h>
- -#include <asm/isa-rev.h>
- -#include <asm/regdef.h>
- -#include "bpf_jit.h"
- -
- -/* ABI
- - *
- - * r_skb_hl skb header length
- - * r_skb_data skb data
- - * r_off(a1) offset register
- - * r_A BPF register A
- - * r_X PF register X
- - * r_skb(a0) *skb
- - * r_M *scratch memory
- - * r_skb_le skb length
- - * r_s0 Scratch register 0
- - * r_s1 Scratch register 1
- - *
- - * On entry:
- - * a0: *skb
- - * a1: offset (imm or imm + X)
- - *
- - * All non-BPF-ABI registers are free for use. On return, we only
- - * care about r_ret. The BPF-ABI registers are assumed to remain
- - * unmodified during the entire filter operation.
- - */
- -
- -#define skb a0
- -#define offset a1
- -#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */
- -
- - /* We know better :) so prevent assembler reordering etc */
- - .set noreorder
- -
- -#define is_offset_negative(TYPE) \
- - /* If offset is negative we have more work to do */ \
- - slti t0, offset, 0; \
- - bgtz t0, bpf_slow_path_##TYPE##_neg; \
- - /* Be careful what follows in DS. */
- -
- -#define is_offset_in_header(SIZE, TYPE) \
- - /* Reading from header? */ \
- - addiu $r_s0, $r_skb_hl, -SIZE; \
- - slt t0, $r_s0, offset; \
- - bgtz t0, bpf_slow_path_##TYPE; \
- -
- -LEAF(sk_load_word)
- - is_offset_negative(word)
- -FEXPORT(sk_load_word_positive)
- - is_offset_in_header(4, word)
- - /* Offset within header boundaries */
- - PTR_ADDU t1, $r_skb_data, offset
- - .set reorder
- - lw $r_A, 0(t1)
- - .set noreorder
- -#ifdef CONFIG_CPU_LITTLE_ENDIAN
- -# if MIPS_ISA_REV >= 2
- - wsbh t0, $r_A
- - rotr $r_A, t0, 16
- -# else
- - sll t0, $r_A, 24
- - srl t1, $r_A, 24
- - srl t2, $r_A, 8
- - or t0, t0, t1
- - andi t2, t2, 0xff00
- - andi t1, $r_A, 0xff00
- - or t0, t0, t2
- - sll t1, t1, 8
- - or $r_A, t0, t1
- -# endif
- -#endif
- - jr $r_ra
- - move $r_ret, zero
- - END(sk_load_word)
- -
- -LEAF(sk_load_half)
- - is_offset_negative(half)
- -FEXPORT(sk_load_half_positive)
- - is_offset_in_header(2, half)
- - /* Offset within header boundaries */
- - PTR_ADDU t1, $r_skb_data, offset
- - lhu $r_A, 0(t1)
- -#ifdef CONFIG_CPU_LITTLE_ENDIAN
- -# if MIPS_ISA_REV >= 2
- - wsbh $r_A, $r_A
- -# else
- - sll t0, $r_A, 8
- - srl t1, $r_A, 8
- - andi t0, t0, 0xff00
- - or $r_A, t0, t1
- -# endif
- -#endif
- - jr $r_ra
- - move $r_ret, zero
- - END(sk_load_half)
- -
- -LEAF(sk_load_byte)
- - is_offset_negative(byte)
- -FEXPORT(sk_load_byte_positive)
- - is_offset_in_header(1, byte)
- - /* Offset within header boundaries */
- - PTR_ADDU t1, $r_skb_data, offset
- - lbu $r_A, 0(t1)
- - jr $r_ra
- - move $r_ret, zero
- - END(sk_load_byte)
- -
- -/*
- - * call skb_copy_bits:
- - * (prototype in linux/skbuff.h)
- - *
- - * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len)
- - *
- - * o32 mandates we leave 4 spaces for argument registers in case
- - * the callee needs to use them. Even though we don't care about
- - * the argument registers ourselves, we need to allocate that space
- - * to remain ABI compliant since the callee may want to use that space.
- - * We also allocate 2 more spaces for $r_ra and our return register (*to).
- - *
- - * n64 is a bit different. The *caller* will allocate the space to preserve
- - * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no
- - * good reason but it does not matter that much really.
- - *
- - * (void *to) is returned in r_s0
- - *
- - */
- -#ifdef CONFIG_CPU_LITTLE_ENDIAN
- -#define DS_OFFSET(SIZE) (4 * SZREG)
- -#else
- -#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE))
- -#endif
- -#define bpf_slow_path_common(SIZE) \
- - /* Quick check. Are we within reasonable boundaries? */ \
- - LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \
- - sltu $r_s0, offset, $r_s1; \
- - beqz $r_s0, fault; \
- - /* Load 4th argument in DS */ \
- - LONG_ADDIU a3, zero, SIZE; \
- - PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
- - PTR_LA t0, skb_copy_bits; \
- - PTR_S $r_ra, (5 * SZREG)($r_sp); \
- - /* Assign low slot to a2 */ \
- - PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \
- - jalr t0; \
- - /* Reset our destination slot (DS but it's ok) */ \
- - INT_S zero, (4 * SZREG)($r_sp); \
- - /* \
- - * skb_copy_bits returns 0 on success and -EFAULT \
- - * on error. Our data live in a2. Do not bother with \
- - * our data if an error has been returned. \
- - */ \
- - /* Restore our frame */ \
- - PTR_L $r_ra, (5 * SZREG)($r_sp); \
- - INT_L $r_s0, (4 * SZREG)($r_sp); \
- - bltz v0, fault; \
- - PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
- - move $r_ret, zero; \
- -
- -NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
- - bpf_slow_path_common(4)
- -#ifdef CONFIG_CPU_LITTLE_ENDIAN
- -# if MIPS_ISA_REV >= 2
- - wsbh t0, $r_s0
- - jr $r_ra
- - rotr $r_A, t0, 16
- -# else
- - sll t0, $r_s0, 24
- - srl t1, $r_s0, 24
- - srl t2, $r_s0, 8
- - or t0, t0, t1
- - andi t2, t2, 0xff00
- - andi t1, $r_s0, 0xff00
- - or t0, t0, t2
- - sll t1, t1, 8
- - jr $r_ra
- - or $r_A, t0, t1
- -# endif
- -#else
- - jr $r_ra
- - move $r_A, $r_s0
- -#endif
- -
- - END(bpf_slow_path_word)
- -
- -NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
- - bpf_slow_path_common(2)
- -#ifdef CONFIG_CPU_LITTLE_ENDIAN
- -# if MIPS_ISA_REV >= 2
- - jr $r_ra
- - wsbh $r_A, $r_s0
- -# else
- - sll t0, $r_s0, 8
- - andi t1, $r_s0, 0xff00
- - andi t0, t0, 0xff00
- - srl t1, t1, 8
- - jr $r_ra
- - or $r_A, t0, t1
- -# endif
- -#else
- - jr $r_ra
- - move $r_A, $r_s0
- -#endif
- -
- - END(bpf_slow_path_half)
- -
- -NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp)
- - bpf_slow_path_common(1)
- - jr $r_ra
- - move $r_A, $r_s0
- -
- - END(bpf_slow_path_byte)
- -
- -/*
- - * Negative entry points
- - */
- - .macro bpf_is_end_of_data
- - li t0, SKF_LL_OFF
- - /* Reading link layer data? */
- - slt t1, offset, t0
- - bgtz t1, fault
- - /* Be careful what follows in DS. */
- - .endm
- -/*
- - * call skb_copy_bits:
- - * (prototype in linux/filter.h)
- - *
- - * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb,
- - * int k, unsigned int size)
- - *
- - * see above (bpf_slow_path_common) for ABI restrictions
- - */
- -#define bpf_negative_common(SIZE) \
- - PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
- - PTR_LA t0, bpf_internal_load_pointer_neg_helper; \
- - PTR_S $r_ra, (5 * SZREG)($r_sp); \
- - jalr t0; \
- - li a2, SIZE; \
- - PTR_L $r_ra, (5 * SZREG)($r_sp); \
- - /* Check return pointer */ \
- - beqz v0, fault; \
- - PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
- - /* Preserve our pointer */ \
- - move $r_s0, v0; \
- - /* Set return value */ \
- - move $r_ret, zero; \
- -
- -bpf_slow_path_word_neg:
- - bpf_is_end_of_data
- -NESTED(sk_load_word_negative, (6 * SZREG), $r_sp)
- - bpf_negative_common(4)
- - jr $r_ra
- - lw $r_A, 0($r_s0)
- - END(sk_load_word_negative)
- -
- -bpf_slow_path_half_neg:
- - bpf_is_end_of_data
- -NESTED(sk_load_half_negative, (6 * SZREG), $r_sp)
- - bpf_negative_common(2)
- - jr $r_ra
- - lhu $r_A, 0($r_s0)
- - END(sk_load_half_negative)
- -
- -bpf_slow_path_byte_neg:
- - bpf_is_end_of_data
- -NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp)
- - bpf_negative_common(1)
- - jr $r_ra
- - lbu $r_A, 0($r_s0)
- - END(sk_load_byte_negative)
- -
- -fault:
- - jr $r_ra
- - addiu $r_ret, zero, 1
|