diff options
Diffstat (limited to 'arch/s390/net/bpf_jit_comp.c')
-rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 5e7c63033159..e636728ab452 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -299,9 +299,11 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) | |||
299 | 299 | ||
300 | #define EMIT_ZERO(b1) \ | 300 | #define EMIT_ZERO(b1) \ |
301 | ({ \ | 301 | ({ \ |
302 | /* llgfr %dst,%dst (zero extend to 64 bit) */ \ | 302 | if (!fp->aux->verifier_zext) { \ |
303 | EMIT4(0xb9160000, b1, b1); \ | 303 | /* llgfr %dst,%dst (zero extend to 64 bit) */ \ |
304 | REG_SET_SEEN(b1); \ | 304 | EMIT4(0xb9160000, b1, b1); \ |
305 | REG_SET_SEEN(b1); \ | ||
306 | } \ | ||
305 | }) | 307 | }) |
306 | 308 | ||
307 | /* | 309 | /* |
@@ -520,6 +522,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
520 | case BPF_ALU | BPF_MOV | BPF_X: /* dst = (u32) src */ | 522 | case BPF_ALU | BPF_MOV | BPF_X: /* dst = (u32) src */ |
521 | /* llgfr %dst,%src */ | 523 | /* llgfr %dst,%src */ |
522 | EMIT4(0xb9160000, dst_reg, src_reg); | 524 | EMIT4(0xb9160000, dst_reg, src_reg); |
525 | if (insn_is_zext(&insn[1])) | ||
526 | insn_count = 2; | ||
523 | break; | 527 | break; |
524 | case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ | 528 | case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ |
525 | /* lgr %dst,%src */ | 529 | /* lgr %dst,%src */ |
@@ -528,6 +532,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
528 | case BPF_ALU | BPF_MOV | BPF_K: /* dst = (u32) imm */ | 532 | case BPF_ALU | BPF_MOV | BPF_K: /* dst = (u32) imm */ |
529 | /* llilf %dst,imm */ | 533 | /* llilf %dst,imm */ |
530 | EMIT6_IMM(0xc00f0000, dst_reg, imm); | 534 | EMIT6_IMM(0xc00f0000, dst_reg, imm); |
535 | if (insn_is_zext(&insn[1])) | ||
536 | insn_count = 2; | ||
531 | break; | 537 | break; |
532 | case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = imm */ | 538 | case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = imm */ |
533 | /* lgfi %dst,imm */ | 539 | /* lgfi %dst,imm */ |
@@ -639,6 +645,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
639 | EMIT4(0xb9970000, REG_W0, src_reg); | 645 | EMIT4(0xb9970000, REG_W0, src_reg); |
640 | /* llgfr %dst,%rc */ | 646 | /* llgfr %dst,%rc */ |
641 | EMIT4(0xb9160000, dst_reg, rc_reg); | 647 | EMIT4(0xb9160000, dst_reg, rc_reg); |
648 | if (insn_is_zext(&insn[1])) | ||
649 | insn_count = 2; | ||
642 | break; | 650 | break; |
643 | } | 651 | } |
644 | case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */ | 652 | case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */ |
@@ -676,6 +684,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
676 | EMIT_CONST_U32(imm)); | 684 | EMIT_CONST_U32(imm)); |
677 | /* llgfr %dst,%rc */ | 685 | /* llgfr %dst,%rc */ |
678 | EMIT4(0xb9160000, dst_reg, rc_reg); | 686 | EMIT4(0xb9160000, dst_reg, rc_reg); |
687 | if (insn_is_zext(&insn[1])) | ||
688 | insn_count = 2; | ||
679 | break; | 689 | break; |
680 | } | 690 | } |
681 | case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */ | 691 | case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */ |
@@ -864,10 +874,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
864 | case 16: /* dst = (u16) cpu_to_be16(dst) */ | 874 | case 16: /* dst = (u16) cpu_to_be16(dst) */ |
865 | /* llghr %dst,%dst */ | 875 | /* llghr %dst,%dst */ |
866 | EMIT4(0xb9850000, dst_reg, dst_reg); | 876 | EMIT4(0xb9850000, dst_reg, dst_reg); |
877 | if (insn_is_zext(&insn[1])) | ||
878 | insn_count = 2; | ||
867 | break; | 879 | break; |
868 | case 32: /* dst = (u32) cpu_to_be32(dst) */ | 880 | case 32: /* dst = (u32) cpu_to_be32(dst) */ |
869 | /* llgfr %dst,%dst */ | 881 | if (!fp->aux->verifier_zext) |
870 | EMIT4(0xb9160000, dst_reg, dst_reg); | 882 | /* llgfr %dst,%dst */ |
883 | EMIT4(0xb9160000, dst_reg, dst_reg); | ||
871 | break; | 884 | break; |
872 | case 64: /* dst = (u64) cpu_to_be64(dst) */ | 885 | case 64: /* dst = (u64) cpu_to_be64(dst) */ |
873 | break; | 886 | break; |
@@ -882,12 +895,15 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
882 | EMIT4_DISP(0x88000000, dst_reg, REG_0, 16); | 895 | EMIT4_DISP(0x88000000, dst_reg, REG_0, 16); |
883 | /* llghr %dst,%dst */ | 896 | /* llghr %dst,%dst */ |
884 | EMIT4(0xb9850000, dst_reg, dst_reg); | 897 | EMIT4(0xb9850000, dst_reg, dst_reg); |
898 | if (insn_is_zext(&insn[1])) | ||
899 | insn_count = 2; | ||
885 | break; | 900 | break; |
886 | case 32: /* dst = (u32) cpu_to_le32(dst) */ | 901 | case 32: /* dst = (u32) cpu_to_le32(dst) */ |
887 | /* lrvr %dst,%dst */ | 902 | /* lrvr %dst,%dst */ |
888 | EMIT4(0xb91f0000, dst_reg, dst_reg); | 903 | EMIT4(0xb91f0000, dst_reg, dst_reg); |
889 | /* llgfr %dst,%dst */ | 904 | if (!fp->aux->verifier_zext) |
890 | EMIT4(0xb9160000, dst_reg, dst_reg); | 905 | /* llgfr %dst,%dst */ |
906 | EMIT4(0xb9160000, dst_reg, dst_reg); | ||
891 | break; | 907 | break; |
892 | case 64: /* dst = (u64) cpu_to_le64(dst) */ | 908 | case 64: /* dst = (u64) cpu_to_le64(dst) */ |
893 | /* lrvgr %dst,%dst */ | 909 | /* lrvgr %dst,%dst */ |
@@ -968,16 +984,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i | |||
968 | /* llgc %dst,0(off,%src) */ | 984 | /* llgc %dst,0(off,%src) */ |
969 | EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg, REG_0, off); | 985 | EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg, REG_0, off); |
970 | jit->seen |= SEEN_MEM; | 986 | jit->seen |= SEEN_MEM; |
987 | if (insn_is_zext(&insn[1])) | ||
988 | insn_count = 2; | ||
971 | break; | 989 | break; |
972 | case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */ | 990 | case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */ |
973 | /* llgh %dst,0(off,%src) */ | 991 | /* llgh %dst,0(off,%src) */ |
974 | EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg, REG_0, off); | 992 | EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg, REG_0, off); |
975 | jit->seen |= SEEN_MEM; | 993 | jit->seen |= SEEN_MEM; |
994 | if (insn_is_zext(&insn[1])) | ||
995 | insn_count = 2; | ||
976 | break; | 996 | break; |
977 | case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */ | 997 | case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */ |
978 | /* llgf %dst,off(%src) */ | 998 | /* llgf %dst,off(%src) */ |
979 | jit->seen |= SEEN_MEM; | 999 | jit->seen |= SEEN_MEM; |
980 | EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg, REG_0, off); | 1000 | EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg, REG_0, off); |
1001 | if (insn_is_zext(&insn[1])) | ||
1002 | insn_count = 2; | ||
981 | break; | 1003 | break; |
982 | case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */ | 1004 | case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */ |
983 | /* lg %dst,0(off,%src) */ | 1005 | /* lg %dst,0(off,%src) */ |
@@ -1282,6 +1304,11 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp) | |||
1282 | return 0; | 1304 | return 0; |
1283 | } | 1305 | } |
1284 | 1306 | ||
1307 | bool bpf_jit_needs_zext(void) | ||
1308 | { | ||
1309 | return true; | ||
1310 | } | ||
1311 | |||
1285 | /* | 1312 | /* |
1286 | * Compile eBPF program "fp" | 1313 | * Compile eBPF program "fp" |
1287 | */ | 1314 | */ |