diff options
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp.c')
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp.c | 37 |
1 files changed, 15 insertions, 22 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index ac3c2a1..2345bdb 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -17,8 +17,14 @@ #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(); @@ -187,26 +193,6 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, PPC_MUL(r_A, r_A, r_scratch1); } break; - case BPF_S_ALU_MOD_X: /* A %= X; */ - ctx->seen |= SEEN_XREG; - PPC_CMPWI(r_X, 0); - if (ctx->pc_ret0 != -1) { - PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]); - } else { - PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12); - PPC_LI(r_ret, 0); - PPC_JMP(exit_addr); - } - PPC_DIVWU(r_scratch1, r_A, r_X); - PPC_MUL(r_scratch1, r_X, r_scratch1); - PPC_SUB(r_A, r_A, r_scratch1); - break; - case BPF_S_ALU_MOD_K: /* A %= K; */ - PPC_LI32(r_scratch2, K); - PPC_DIVWU(r_scratch1, r_A, r_scratch2); - PPC_MUL(r_scratch1, r_scratch2, r_scratch1); - PPC_SUB(r_A, r_A, r_scratch1); - break; case BPF_S_ALU_DIV_X: /* A /= X; */ ctx->seen |= SEEN_XREG; PPC_CMPWI(r_X, 0); @@ -360,11 +346,18 @@ 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_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff, - protocol)); + PPC_LHZ_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, |