Loading arch/powerpc/include/asm/ppc-opcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,7 @@ /* Misc instructions for BPF compiler */ #define PPC_INST_LD 0xe8000000 #define PPC_INST_LHZ 0xa0000000 #define PPC_INST_LHBRX 0x7c00062c #define PPC_INST_LWZ 0x80000000 #define PPC_INST_STD 0xf8000000 #define PPC_INST_STDU 0xf8000001 Loading arch/powerpc/net/bpf_jit.h +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); ___PPC_RA(base) | IMM_L(i)) #define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ ___PPC_RA(base) | ___PPC_RB(b)) /* Convenience helpers for the above with 'far' offsets: */ #define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \ else { PPC_ADDIS(r, base, IMM_HA(i)); \ Loading Loading @@ -186,6 +188,14 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ } } while (0); #define PPC_LHBRX_OFFS(r, base, i) \ do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) #ifdef __LITTLE_ENDIAN__ #define PPC_NTOHS_OFFS(r, base, i) PPC_LHBRX_OFFS(r, base, i) #else #define PPC_NTOHS_OFFS(r, base, i) PPC_LHZ_OFFS(r, base, i) #endif static inline bool is_nearbranch(int offset) { return (offset < 32768) && (offset >= -32768); Loading arch/powerpc/net/bpf_jit_64.S +8 −1 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ sk_load_word_positive_offset: cmpd r_scratch1, r_addr blt bpf_slow_path_word /* Nope, just hitting the header. cr0 here is eq or gt! */ #ifdef __LITTLE_ENDIAN__ lwbrx r_A, r_D, r_addr #else lwzx r_A, r_D, r_addr /* When big endian we don't need to byteswap. */ #endif blr /* Return success, cr0 != LT */ .globl sk_load_half Loading @@ -56,7 +59,11 @@ sk_load_half_positive_offset: subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half #ifdef __LITTLE_ENDIAN__ lhbrx r_A, r_D, r_addr #else lhzx r_A, r_D, r_addr #endif blr .globl sk_load_byte Loading arch/powerpc/net/bpf_jit_comp.c +2 −15 Original line number Diff line number Diff line Loading @@ -17,14 +17,8 @@ #include "bpf_jit.h" #ifndef __BIG_ENDIAN /* There are endianness assumptions herein. */ #error "Little-endian PPC not supported in BPF compiler" #endif int bpf_jit_enable __read_mostly; static inline void bpf_flush_icache(void *start, void *end) { smp_wmb(); Loading Loading @@ -346,18 +340,11 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; /*** Ancillary info loads ***/ /* None of the BPF_S_ANC* codes appear to be passed by * sk_chk_filter(). The interpreter and the x86 BPF * compiler implement them so we do too -- they may be * planted in future. */ case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2); PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff, protocol)); /* ntohs is a NOP with BE loads. */ break; case BPF_S_ANC_IFINDEX: PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, Loading Loading
arch/powerpc/include/asm/ppc-opcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,7 @@ /* Misc instructions for BPF compiler */ #define PPC_INST_LD 0xe8000000 #define PPC_INST_LHZ 0xa0000000 #define PPC_INST_LHBRX 0x7c00062c #define PPC_INST_LWZ 0x80000000 #define PPC_INST_STD 0xf8000000 #define PPC_INST_STDU 0xf8000001 Loading
arch/powerpc/net/bpf_jit.h +10 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,8 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); ___PPC_RA(base) | IMM_L(i)) #define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ ___PPC_RA(base) | ___PPC_RB(b)) /* Convenience helpers for the above with 'far' offsets: */ #define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \ else { PPC_ADDIS(r, base, IMM_HA(i)); \ Loading Loading @@ -186,6 +188,14 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ } } while (0); #define PPC_LHBRX_OFFS(r, base, i) \ do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) #ifdef __LITTLE_ENDIAN__ #define PPC_NTOHS_OFFS(r, base, i) PPC_LHBRX_OFFS(r, base, i) #else #define PPC_NTOHS_OFFS(r, base, i) PPC_LHZ_OFFS(r, base, i) #endif static inline bool is_nearbranch(int offset) { return (offset < 32768) && (offset >= -32768); Loading
arch/powerpc/net/bpf_jit_64.S +8 −1 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ sk_load_word_positive_offset: cmpd r_scratch1, r_addr blt bpf_slow_path_word /* Nope, just hitting the header. cr0 here is eq or gt! */ #ifdef __LITTLE_ENDIAN__ lwbrx r_A, r_D, r_addr #else lwzx r_A, r_D, r_addr /* When big endian we don't need to byteswap. */ #endif blr /* Return success, cr0 != LT */ .globl sk_load_half Loading @@ -56,7 +59,11 @@ sk_load_half_positive_offset: subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half #ifdef __LITTLE_ENDIAN__ lhbrx r_A, r_D, r_addr #else lhzx r_A, r_D, r_addr #endif blr .globl sk_load_byte Loading
arch/powerpc/net/bpf_jit_comp.c +2 −15 Original line number Diff line number Diff line Loading @@ -17,14 +17,8 @@ #include "bpf_jit.h" #ifndef __BIG_ENDIAN /* There are endianness assumptions herein. */ #error "Little-endian PPC not supported in BPF compiler" #endif int bpf_jit_enable __read_mostly; static inline void bpf_flush_icache(void *start, void *end) { smp_wmb(); Loading Loading @@ -346,18 +340,11 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; /*** Ancillary info loads ***/ /* None of the BPF_S_ANC* codes appear to be passed by * sk_chk_filter(). The interpreter and the x86 BPF * compiler implement them so we do too -- they may be * planted in future. */ case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */ BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2); PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff, protocol)); /* ntohs is a NOP with BE loads. */ break; case BPF_S_ANC_IFINDEX: PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, Loading