aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/net/bpf_jit_comp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp.c')
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 73619d3aeb6c..2dc8b1484845 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)
127 PPC_BLR(); 127 PPC_BLR();
128} 128}
129 129
130#define CHOOSE_LOAD_FUNC(K, func) \
131 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
132
130/* Assemble the body code between the prologue & epilogue. */ 133/* Assemble the body code between the prologue & epilogue. */
131static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, 134static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
132 struct codegen_context *ctx, 135 struct codegen_context *ctx,
@@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
391 394
392 /*** Absolute loads from packet header/data ***/ 395 /*** Absolute loads from packet header/data ***/
393 case BPF_S_LD_W_ABS: 396 case BPF_S_LD_W_ABS:
394 func = sk_load_word; 397 func = CHOOSE_LOAD_FUNC(K, sk_load_word);
395 goto common_load; 398 goto common_load;
396 case BPF_S_LD_H_ABS: 399 case BPF_S_LD_H_ABS:
397 func = sk_load_half; 400 func = CHOOSE_LOAD_FUNC(K, sk_load_half);
398 goto common_load; 401 goto common_load;
399 case BPF_S_LD_B_ABS: 402 case BPF_S_LD_B_ABS:
400 func = sk_load_byte; 403 func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
401 common_load: 404 common_load:
402 /* 405 /* Load from [K]. */
403 * Load from [K]. Reference with the (negative)
404 * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
405 */
406 ctx->seen |= SEEN_DATAREF; 406 ctx->seen |= SEEN_DATAREF;
407 if ((int)K < 0)
408 return -ENOTSUPP;
409 PPC_LI64(r_scratch1, func); 407 PPC_LI64(r_scratch1, func);
410 PPC_MTLR(r_scratch1); 408 PPC_MTLR(r_scratch1);
411 PPC_LI32(r_addr, K); 409 PPC_LI32(r_addr, K);
@@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
429 common_load_ind: 427 common_load_ind:
430 /* 428 /*
431 * Load from [X + K]. Negative offsets are tested for 429 * Load from [X + K]. Negative offsets are tested for
432 * in the helper functions, and result in a 'ret 0'. 430 * in the helper functions.
433 */ 431 */
434 ctx->seen |= SEEN_DATAREF | SEEN_XREG; 432 ctx->seen |= SEEN_DATAREF | SEEN_XREG;
435 PPC_LI64(r_scratch1, func); 433 PPC_LI64(r_scratch1, func);
@@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
443 break; 441 break;
444 442
445 case BPF_S_LDX_B_MSH: 443 case BPF_S_LDX_B_MSH:
446 /* 444 func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
447 * x86 version drops packet (RET 0) when K<0, whereas
448 * interpreter does allow K<0 (__load_pointer, special
449 * ancillary data). common_load returns ENOTSUPP if K<0,
450 * so we fall back to interpreter & filter works.
451 */
452 func = sk_load_byte_msh;
453 goto common_load; 445 goto common_load;
454 break; 446 break;
455 447