diff options
Diffstat (limited to 'lib/test_bpf.c')
-rw-r--r-- | lib/test_bpf.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index aa8812ae6776..f369889e521d 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c | |||
@@ -435,6 +435,41 @@ loop: | |||
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
438 | static int bpf_fill_ld_abs_vlan_push_pop2(struct bpf_test *self) | ||
439 | { | ||
440 | struct bpf_insn *insn; | ||
441 | |||
442 | insn = kmalloc_array(16, sizeof(*insn), GFP_KERNEL); | ||
443 | if (!insn) | ||
444 | return -ENOMEM; | ||
445 | |||
446 | /* Due to func address being non-const, we need to | ||
447 | * assemble this here. | ||
448 | */ | ||
449 | insn[0] = BPF_MOV64_REG(R6, R1); | ||
450 | insn[1] = BPF_LD_ABS(BPF_B, 0); | ||
451 | insn[2] = BPF_LD_ABS(BPF_H, 0); | ||
452 | insn[3] = BPF_LD_ABS(BPF_W, 0); | ||
453 | insn[4] = BPF_MOV64_REG(R7, R6); | ||
454 | insn[5] = BPF_MOV64_IMM(R6, 0); | ||
455 | insn[6] = BPF_MOV64_REG(R1, R7); | ||
456 | insn[7] = BPF_MOV64_IMM(R2, 1); | ||
457 | insn[8] = BPF_MOV64_IMM(R3, 2); | ||
458 | insn[9] = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
459 | bpf_skb_vlan_push_proto.func - __bpf_call_base); | ||
460 | insn[10] = BPF_MOV64_REG(R6, R7); | ||
461 | insn[11] = BPF_LD_ABS(BPF_B, 0); | ||
462 | insn[12] = BPF_LD_ABS(BPF_H, 0); | ||
463 | insn[13] = BPF_LD_ABS(BPF_W, 0); | ||
464 | insn[14] = BPF_MOV64_IMM(R0, 42); | ||
465 | insn[15] = BPF_EXIT_INSN(); | ||
466 | |||
467 | self->u.ptr.insns = insn; | ||
468 | self->u.ptr.len = 16; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
438 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) | 473 | static int bpf_fill_jump_around_ld_abs(struct bpf_test *self) |
439 | { | 474 | { |
440 | unsigned int len = BPF_MAXINSNS; | 475 | unsigned int len = BPF_MAXINSNS; |
@@ -6066,6 +6101,14 @@ static struct bpf_test tests[] = { | |||
6066 | {}, | 6101 | {}, |
6067 | { {0x1, 0x42 } }, | 6102 | { {0x1, 0x42 } }, |
6068 | }, | 6103 | }, |
6104 | { | ||
6105 | "LD_ABS with helper changing skb data", | ||
6106 | { }, | ||
6107 | INTERNAL, | ||
6108 | { 0x34 }, | ||
6109 | { { ETH_HLEN, 42 } }, | ||
6110 | .fill_helper = bpf_fill_ld_abs_vlan_push_pop2, | ||
6111 | }, | ||
6069 | }; | 6112 | }; |
6070 | 6113 | ||
6071 | static struct net_device dev; | 6114 | static struct net_device dev; |
@@ -6207,9 +6250,8 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
6207 | return NULL; | 6250 | return NULL; |
6208 | } | 6251 | } |
6209 | } | 6252 | } |
6210 | /* We don't expect to fail. */ | ||
6211 | if (*err) { | 6253 | if (*err) { |
6212 | pr_cont("FAIL to attach err=%d len=%d\n", | 6254 | pr_cont("FAIL to prog_create err=%d len=%d\n", |
6213 | *err, fprog.len); | 6255 | *err, fprog.len); |
6214 | return NULL; | 6256 | return NULL; |
6215 | } | 6257 | } |
@@ -6233,6 +6275,10 @@ static struct bpf_prog *generate_filter(int which, int *err) | |||
6233 | * checks. | 6275 | * checks. |
6234 | */ | 6276 | */ |
6235 | fp = bpf_prog_select_runtime(fp, err); | 6277 | fp = bpf_prog_select_runtime(fp, err); |
6278 | if (*err) { | ||
6279 | pr_cont("FAIL to select_runtime err=%d\n", *err); | ||
6280 | return NULL; | ||
6281 | } | ||
6236 | break; | 6282 | break; |
6237 | } | 6283 | } |
6238 | 6284 | ||
@@ -6418,8 +6464,8 @@ static __init int test_bpf(void) | |||
6418 | pass_cnt++; | 6464 | pass_cnt++; |
6419 | continue; | 6465 | continue; |
6420 | } | 6466 | } |
6421 | 6467 | err_cnt++; | |
6422 | return err; | 6468 | continue; |
6423 | } | 6469 | } |
6424 | 6470 | ||
6425 | pr_cont("jited:%u ", fp->jited); | 6471 | pr_cont("jited:%u ", fp->jited); |