diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2015-07-29 15:15:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-29 17:59:58 -0400 |
commit | cde66c2d88da1d73d755109c80ce4c34b917596b (patch) | |
tree | 888437f97f8dd86ce7dc02a2a607c97e46b4fdbc /arch/s390/net/bpf_jit_comp.c | |
parent | ce2b6ad9c1856fac5d5e8d3351b3dd5392e09b7a (diff) |
s390/bpf: Only clear A and X for converted BPF programs
Only classic BPF programs that have been converted to eBPF need to clear
the A and X registers. We can check for converted programs with:
bpf_prog->type == BPF_PROG_TYPE_UNSPEC
So add the check and skip initialization for real eBPF programs.
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/s390/net/bpf_jit_comp.c')
-rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 04af36728a18..3dd01637f83a 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -387,7 +387,7 @@ static void save_restore_regs(struct bpf_jit *jit, int op) | |||
387 | * Save registers and create stack frame if necessary. | 387 | * Save registers and create stack frame if necessary. |
388 | * See stack frame layout desription in "bpf_jit.h"! | 388 | * See stack frame layout desription in "bpf_jit.h"! |
389 | */ | 389 | */ |
390 | static void bpf_jit_prologue(struct bpf_jit *jit) | 390 | static void bpf_jit_prologue(struct bpf_jit *jit, bool is_classic) |
391 | { | 391 | { |
392 | if (jit->seen & SEEN_TAIL_CALL) { | 392 | if (jit->seen & SEEN_TAIL_CALL) { |
393 | /* xc STK_OFF_TCCNT(4,%r15),STK_OFF_TCCNT(%r15) */ | 393 | /* xc STK_OFF_TCCNT(4,%r15),STK_OFF_TCCNT(%r15) */ |
@@ -440,13 +440,15 @@ static void bpf_jit_prologue(struct bpf_jit *jit) | |||
440 | EMIT6_DISP_LH(0xe3000000, 0x0004, REG_SKB_DATA, REG_0, | 440 | EMIT6_DISP_LH(0xe3000000, 0x0004, REG_SKB_DATA, REG_0, |
441 | BPF_REG_1, offsetof(struct sk_buff, data)); | 441 | BPF_REG_1, offsetof(struct sk_buff, data)); |
442 | } | 442 | } |
443 | /* BPF compatibility: clear A (%b0) and X (%b7) registers */ | 443 | /* Clear A (%b0) and X (%b7) registers for converted BPF programs */ |
444 | if (REG_SEEN(BPF_REG_A)) | 444 | if (is_classic) { |
445 | /* lghi %ba,0 */ | 445 | if (REG_SEEN(BPF_REG_A)) |
446 | EMIT4_IMM(0xa7090000, BPF_REG_A, 0); | 446 | /* lghi %ba,0 */ |
447 | if (REG_SEEN(BPF_REG_X)) | 447 | EMIT4_IMM(0xa7090000, BPF_REG_A, 0); |
448 | /* lghi %bx,0 */ | 448 | if (REG_SEEN(BPF_REG_X)) |
449 | EMIT4_IMM(0xa7090000, BPF_REG_X, 0); | 449 | /* lghi %bx,0 */ |
450 | EMIT4_IMM(0xa7090000, BPF_REG_X, 0); | ||
451 | } | ||
450 | } | 452 | } |
451 | 453 | ||
452 | /* | 454 | /* |
@@ -1232,7 +1234,7 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp) | |||
1232 | jit->lit = jit->lit_start; | 1234 | jit->lit = jit->lit_start; |
1233 | jit->prg = 0; | 1235 | jit->prg = 0; |
1234 | 1236 | ||
1235 | bpf_jit_prologue(jit); | 1237 | bpf_jit_prologue(jit, fp->type == BPF_PROG_TYPE_UNSPEC); |
1236 | for (i = 0; i < fp->len; i += insn_count) { | 1238 | for (i = 0; i < fp->len; i += insn_count) { |
1237 | insn_count = bpf_jit_insn(jit, fp, i); | 1239 | insn_count = bpf_jit_insn(jit, fp, i); |
1238 | if (insn_count < 0) | 1240 | if (insn_count < 0) |