Message ID | 4F75D2A5.7060407@googlemail.com |
---|---|
State | Deferred, archived |
Delegated to: | David Miller |
Headers | show |
From: Jan Seiffert <kaffeemonster@googlemail.com> Date: Fri, 30 Mar 2012 17:35:01 +0200 > Now the helper function from filter.c for negative offsets is exported, > it can be used it in the jit to handle negative offsets. > > First modify the asm load helper functions to handle: > - know positive offsets > - know negative offsets > - any offset > > then the compiler can be modified to explicitly use these helper > when appropriate. > > This fixes the case of a negative X register and allows to lift > the restriction that bpf programs with negative offsets can't > be jited. > > Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com> > > I have only compile tested this, -ENOHARDWARE. > Can someone with more powerpc kung-fu review and maybe test this? > Esp. powerpc asm is not my strong point. I think i botched the > stack frame in the call setup. Help? I'm not applying this until a powerpc person tests it. Also, we have an ARM JIT in the tree which probably needs to be fixed similarly. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 2012-04-03 at 18:03 -0400, David Miller wrote: > > Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com> > > > > I have only compile tested this, -ENOHARDWARE. > > Can someone with more powerpc kung-fu review and maybe test this? > > Esp. powerpc asm is not my strong point. I think i botched the > > stack frame in the call setup. Help? > > I'm not applying this until a powerpc person tests it. > > Also, we have an ARM JIT in the tree which probably needs to > be fixed similarly. Matt's having a look at powerpc Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Miller schrieb: [snip - my patch description] > > I'm not applying this until a powerpc person tests it. > As Benjamin already said, Matt is having a look, so i expected nothing else. > Also, we have an ARM JIT in the tree which probably needs to > be fixed similarly. > ??? Oh, in which tree is it? I was working against net-next. Greetings Jan
From: Jan Seiffert <kaffeemonster@googlemail.com> Date: Wed, 4 Apr 2012 00:31:53 +0200 > David Miller schrieb: > [snip - my patch description] >> >> I'm not applying this until a powerpc person tests it. >> > > As Benjamin already said, Matt is having a look, so i expected nothing else. > >> Also, we have an ARM JIT in the tree which probably needs to >> be fixed similarly. >> > > ??? > Oh, in which tree is it? > I was working against net-next. It's been in Linus's tree for several days now. net-next is stale during the merge window and doesn't get updated until the merge window closes. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 2012-04-04 at 08:11 +1000, Benjamin Herrenschmidt wrote: > On Tue, 2012-04-03 at 18:03 -0400, David Miller wrote: > > > > Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com> > > > > > > I have only compile tested this, -ENOHARDWARE. > > > Can someone with more powerpc kung-fu review and maybe test this? > > > Esp. powerpc asm is not my strong point. I think i botched the > > > stack frame in the call setup. Help? > > > > I'm not applying this until a powerpc person tests it. > > > > Also, we have an ARM JIT in the tree which probably needs to > > be fixed similarly. > > Matt's having a look at powerpc Ok, he hasn't so I'll dig a bit. No obvious wrongness (but I'm not very familiar with bpf), though I do have a comment: sk_negative_common() and bpf_slow_path_common() should be made one and single macro which takes the fallback function as an argument. I'll mess around & try to test using Jan test case & will come back with an updated patch. Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2012-04-30 at 12:43 +1000, Benjamin Herrenschmidt wrote: > Ok, he hasn't so I'll dig a bit. > > No obvious wrongness (but I'm not very familiar with bpf), though I do > have a comment: sk_negative_common() and bpf_slow_path_common() should > be made one and single macro which takes the fallback function as an > argument. > > I'll mess around & try to test using Jan test case & will come back > with an updated patch. Wow, hit that nasty along the way: The test program will not work on big endian machines because of a nasty difference between the kernel struct sock_fprog and libpcap struct bpf_program: Kernel expects: struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ unsigned short len; /* Number of filter blocks */ struct sock_filter __user *filter; }; libpcap provides: struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; Note the unsigned short vs. unsigned int there ? This totally breaks it here. Is it expected that one can pass a struct bpf_program directly to the kernel or should it be "converted" by the library in which case it's just a bug in Jan's test program ? Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Benjamin Herrenschmidt schrieb: > On Wed, 2012-04-04 at 08:11 +1000, Benjamin Herrenschmidt wrote: >> On Tue, 2012-04-03 at 18:03 -0400, David Miller wrote: >> >>>> Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com> >>>> >>>> I have only compile tested this, -ENOHARDWARE. Can someone with >>>> more powerpc kung-fu review and maybe test this? Esp. powerpc >>>> asm is not my strong point. I think i botched the stack frame >>>> in the call setup. Help? >>> >>> I'm not applying this until a powerpc person tests it. >>> >>> Also, we have an ARM JIT in the tree which probably needs to be >>> fixed similarly. >> >> Matt's having a look at powerpc > > Ok, he hasn't so I'll dig a bit. > That would be great Benjamin! > No obvious wrongness (but I'm not very familiar with bpf), As long as you know PPC ASM you are my man ;-) > though I do have a comment: sk_negative_common() and > bpf_slow_path_common() should be made one and single macro which > takes the fallback function as an argument. > I don't know if this is possible. The return value is different (one returns 0 on success, the other != 0, the return value of != is needed). I didn't wanted to change to much, because i'm not fluent in ppc. > I'll mess around & try to test using Jan test case & will come back > with an updated patch. > Would be great! > Cheers, Ben. > Greetings Jan
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S index ff4506e..e590aa5 100644 --- a/arch/powerpc/net/bpf_jit_64.S +++ b/arch/powerpc/net/bpf_jit_64.S @@ -31,14 +31,13 @@ * then branch directly to slow_path_XXX if required. (In fact, could * load a spare GPR with the address of slow_path_generic and pass size * as an argument, making the call site a mtlr, li and bllr.) - * - * Technically, the "is addr < 0" check is unnecessary & slowing down - * the ABS path, as it's statically checked on generation. */ .globl sk_load_word sk_load_word: cmpdi r_addr, 0 - blt bpf_error + blt bpf_slow_path_word_neg + .globl sk_load_word_positive_offset +sk_load_word_positive_offset: /* Are we accessing past headlen? */ subi r_scratch1, r_HL, 4 cmpd r_scratch1, r_addr @@ -51,7 +50,9 @@ sk_load_word: .globl sk_load_half sk_load_half: cmpdi r_addr, 0 - blt bpf_error + blt bpf_slow_path_half_neg + .globl sk_load_half_positive_offset +sk_load_half_positive_offset: subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half @@ -61,7 +62,9 @@ sk_load_half: .globl sk_load_byte sk_load_byte: cmpdi r_addr, 0 - blt bpf_error + blt bpf_slow_path_byte_neg + .globl sk_load_byte_positive_offset +sk_load_byte_positive_offset: cmpd r_HL, r_addr ble bpf_slow_path_byte lbzx r_A, r_D, r_addr @@ -69,22 +72,20 @@ sk_load_byte: /* * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) - * r_addr is the offset value, already known positive + * r_addr is the offset value */ .globl sk_load_byte_msh sk_load_byte_msh: + cmpdi r_addr, 0 + blt bpf_slow_path_byte_msh_neg + .globl sk_load_byte_msh_positive_offset +sk_load_byte_msh_positive_offset: cmpd r_HL, r_addr ble bpf_slow_path_byte_msh lbzx r_X, r_D, r_addr rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr -bpf_error: - /* Entered with cr0 = lt */ - li r3, 0 - /* Generated code will 'blt epilogue', returning 0. */ - blr - /* Call out to skb_copy_bits: * We'll need to back up our volatile regs first; we have * local variable space at r1+(BPF_PPC_STACK_BASIC). @@ -136,3 +137,85 @@ bpf_slow_path_byte_msh: lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr + +/* Call out to bpf_internal_load_pointer_neg_helper: + * We'll need to back up our volatile regs first; we have + * local variable space at r1+(BPF_PPC_STACK_BASIC). + * Allocate a new stack frame here to remain ABI-compliant in + * stashing LR. + */ +#define sk_negative_common(SIZE) \ + mflr r0; \ + std r0, 16(r1); \ + /* R3 goes in parameter space of caller's frame */ \ + std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ + std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ + std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ + stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ + /* R3 = r_skb, as passed */ \ + mr r4, r_addr; \ + li r5, SIZE; \ + bl bpf_internal_load_pointer_neg_helper; \ + /* R3 != 0 on success */ \ + addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ + ld r0, 16(r1); \ + ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ + ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ + mtlr r0; \ + cmpldi r3, 0; \ + beq bpf_error_slow; /* cr0 = EQ */ \ + mr r_addr, r3; \ + ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ + /* Great success! */ + +bpf_slow_path_word_neg: + lis r_scratch1,-32 /* SKF_LL_OFF */ + cmpd r_addr, r_scratch1 /* addr < SKF_* */ + blt bpf_error /* cr0 = LT */ + .globl sk_load_word_negative_offset +sk_load_word_negative_offset: + sk_negative_common(4) + lwz r_A, 0(r_addr) + blr + +bpf_slow_path_half_neg: + lis r_scratch1,-32 /* SKF_LL_OFF */ + cmpd r_addr, r_scratch1 /* addr < SKF_* */ + blt bpf_error /* cr0 = LT */ + .globl sk_load_half_negative_offset +sk_load_half_negative_offset: + sk_negative_common(2) + lhz r_A, 0(r_addr) + blr + +bpf_slow_path_byte_neg: + lis r_scratch1,-32 /* SKF_LL_OFF */ + cmpd r_addr, r_scratch1 /* addr < SKF_* */ + blt bpf_error /* cr0 = LT */ + .globl sk_load_byte_negative_offset +sk_load_byte_negative_offset: + sk_negative_common(1) + lbz r_A, 0(r_addr) + blr + +bpf_slow_path_byte_msh_neg: + lis r_scratch1,-32 /* SKF_LL_OFF */ + cmpd r_addr, r_scratch1 /* addr < SKF_* */ + blt bpf_error /* cr0 = LT */ + .globl sk_load_byte_msh_negative_offset +sk_load_byte_msh_negative_offset: + sk_negative_common(1) + lbz r_X, 0(r_addr) + rlwinm r_X, r_X, 2, 32-4-2, 31-2 + blr + +bpf_error_slow: + /* fabricate a cr0 = lt */ + li r_scratch1, -1 + cmpdi r_scratch1, 0 +bpf_error: + /* Entered with cr0 = lt */ + li r3, 0 + /* Generated code will 'blt epilogue', returning 0. */ + blr + diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 73619d3..2dc8b14 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) PPC_BLR(); } +#define CHOOSE_LOAD_FUNC(K, func) \ + ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) + /* Assemble the body code between the prologue & epilogue. */ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, struct codegen_context *ctx, @@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, /*** Absolute loads from packet header/data ***/ case BPF_S_LD_W_ABS: - func = sk_load_word; + func = CHOOSE_LOAD_FUNC(K, sk_load_word); goto common_load; case BPF_S_LD_H_ABS: - func = sk_load_half; + func = CHOOSE_LOAD_FUNC(K, sk_load_half); goto common_load; case BPF_S_LD_B_ABS: - func = sk_load_byte; + func = CHOOSE_LOAD_FUNC(K, sk_load_byte); common_load: - /* - * Load from [K]. Reference with the (negative) - * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported. - */ + /* Load from [K]. */ ctx->seen |= SEEN_DATAREF; - if ((int)K < 0) - return -ENOTSUPP; PPC_LI64(r_scratch1, func); PPC_MTLR(r_scratch1); PPC_LI32(r_addr, K); @@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, common_load_ind: /* * Load from [X + K]. Negative offsets are tested for - * in the helper functions, and result in a 'ret 0'. + * in the helper functions. */ ctx->seen |= SEEN_DATAREF | SEEN_XREG; PPC_LI64(r_scratch1, func); @@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; case BPF_S_LDX_B_MSH: - /* - * x86 version drops packet (RET 0) when K<0, whereas - * interpreter does allow K<0 (__load_pointer, special - * ancillary data). common_load returns ENOTSUPP if K<0, - * so we fall back to interpreter & filter works. - */ - func = sk_load_byte_msh; + func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh); goto common_load; break;
Now the helper function from filter.c for negative offsets is exported, it can be used it in the jit to handle negative offsets. First modify the asm load helper functions to handle: - know positive offsets - know negative offsets - any offset then the compiler can be modified to explicitly use these helper when appropriate. This fixes the case of a negative X register and allows to lift the restriction that bpf programs with negative offsets can't be jited. Signed-off-by: Jan Seiffert <kaffeemonster@googlemail.com> I have only compile tested this, -ENOHARDWARE. Can someone with more powerpc kung-fu review and maybe test this? Esp. powerpc asm is not my strong point. I think i botched the stack frame in the call setup. Help? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html