diff options
| author | Daniel Borkmann <daniel@iogearbox.net> | 2017-08-09 19:39:56 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-08-09 19:53:56 -0400 |
| commit | 52afc51e94b1c7a52d7e04fd81ea8b1c177436d0 (patch) | |
| tree | 5e709742c9b754a93dc68814ecbcbb27b15e98be | |
| parent | 92b31a9af73b3a3fc801899335d6c47966351830 (diff) | |
bpf, x86: implement jiting of BPF_J{LT,LE,SLT,SLE}
This work implements jiting of BPF_J{LT,LE,SLT,SLE} instructions
with BPF_X/BPF_K variants for the x86_64 eBPF JIT.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index e1324f280e06..8194696e2805 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
| @@ -94,7 +94,9 @@ static int bpf_size_to_x86_bytes(int bpf_size) | |||
| 94 | #define X86_JNE 0x75 | 94 | #define X86_JNE 0x75 |
| 95 | #define X86_JBE 0x76 | 95 | #define X86_JBE 0x76 |
| 96 | #define X86_JA 0x77 | 96 | #define X86_JA 0x77 |
| 97 | #define X86_JL 0x7C | ||
| 97 | #define X86_JGE 0x7D | 98 | #define X86_JGE 0x7D |
| 99 | #define X86_JLE 0x7E | ||
| 98 | #define X86_JG 0x7F | 100 | #define X86_JG 0x7F |
| 99 | 101 | ||
| 100 | static void bpf_flush_icache(void *start, void *end) | 102 | static void bpf_flush_icache(void *start, void *end) |
| @@ -888,9 +890,13 @@ xadd: if (is_imm8(insn->off)) | |||
| 888 | case BPF_JMP | BPF_JEQ | BPF_X: | 890 | case BPF_JMP | BPF_JEQ | BPF_X: |
| 889 | case BPF_JMP | BPF_JNE | BPF_X: | 891 | case BPF_JMP | BPF_JNE | BPF_X: |
| 890 | case BPF_JMP | BPF_JGT | BPF_X: | 892 | case BPF_JMP | BPF_JGT | BPF_X: |
| 893 | case BPF_JMP | BPF_JLT | BPF_X: | ||
| 891 | case BPF_JMP | BPF_JGE | BPF_X: | 894 | case BPF_JMP | BPF_JGE | BPF_X: |
| 895 | case BPF_JMP | BPF_JLE | BPF_X: | ||
| 892 | case BPF_JMP | BPF_JSGT | BPF_X: | 896 | case BPF_JMP | BPF_JSGT | BPF_X: |
| 897 | case BPF_JMP | BPF_JSLT | BPF_X: | ||
| 893 | case BPF_JMP | BPF_JSGE | BPF_X: | 898 | case BPF_JMP | BPF_JSGE | BPF_X: |
| 899 | case BPF_JMP | BPF_JSLE | BPF_X: | ||
| 894 | /* cmp dst_reg, src_reg */ | 900 | /* cmp dst_reg, src_reg */ |
| 895 | EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39, | 901 | EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39, |
| 896 | add_2reg(0xC0, dst_reg, src_reg)); | 902 | add_2reg(0xC0, dst_reg, src_reg)); |
| @@ -911,9 +917,13 @@ xadd: if (is_imm8(insn->off)) | |||
| 911 | case BPF_JMP | BPF_JEQ | BPF_K: | 917 | case BPF_JMP | BPF_JEQ | BPF_K: |
| 912 | case BPF_JMP | BPF_JNE | BPF_K: | 918 | case BPF_JMP | BPF_JNE | BPF_K: |
| 913 | case BPF_JMP | BPF_JGT | BPF_K: | 919 | case BPF_JMP | BPF_JGT | BPF_K: |
| 920 | case BPF_JMP | BPF_JLT | BPF_K: | ||
| 914 | case BPF_JMP | BPF_JGE | BPF_K: | 921 | case BPF_JMP | BPF_JGE | BPF_K: |
| 922 | case BPF_JMP | BPF_JLE | BPF_K: | ||
| 915 | case BPF_JMP | BPF_JSGT | BPF_K: | 923 | case BPF_JMP | BPF_JSGT | BPF_K: |
| 924 | case BPF_JMP | BPF_JSLT | BPF_K: | ||
| 916 | case BPF_JMP | BPF_JSGE | BPF_K: | 925 | case BPF_JMP | BPF_JSGE | BPF_K: |
| 926 | case BPF_JMP | BPF_JSLE | BPF_K: | ||
| 917 | /* cmp dst_reg, imm8/32 */ | 927 | /* cmp dst_reg, imm8/32 */ |
| 918 | EMIT1(add_1mod(0x48, dst_reg)); | 928 | EMIT1(add_1mod(0x48, dst_reg)); |
| 919 | 929 | ||
| @@ -935,18 +945,34 @@ emit_cond_jmp: /* convert BPF opcode to x86 */ | |||
| 935 | /* GT is unsigned '>', JA in x86 */ | 945 | /* GT is unsigned '>', JA in x86 */ |
| 936 | jmp_cond = X86_JA; | 946 | jmp_cond = X86_JA; |
| 937 | break; | 947 | break; |
| 948 | case BPF_JLT: | ||
| 949 | /* LT is unsigned '<', JB in x86 */ | ||
| 950 | jmp_cond = X86_JB; | ||
| 951 | break; | ||
| 938 | case BPF_JGE: | 952 | case BPF_JGE: |
| 939 | /* GE is unsigned '>=', JAE in x86 */ | 953 | /* GE is unsigned '>=', JAE in x86 */ |
| 940 | jmp_cond = X86_JAE; | 954 | jmp_cond = X86_JAE; |
| 941 | break; | 955 | break; |
| 956 | case BPF_JLE: | ||
| 957 | /* LE is unsigned '<=', JBE in x86 */ | ||
| 958 | jmp_cond = X86_JBE; | ||
| 959 | break; | ||
| 942 | case BPF_JSGT: | 960 | case BPF_JSGT: |
| 943 | /* signed '>', GT in x86 */ | 961 | /* signed '>', GT in x86 */ |
| 944 | jmp_cond = X86_JG; | 962 | jmp_cond = X86_JG; |
| 945 | break; | 963 | break; |
| 964 | case BPF_JSLT: | ||
| 965 | /* signed '<', LT in x86 */ | ||
| 966 | jmp_cond = X86_JL; | ||
| 967 | break; | ||
| 946 | case BPF_JSGE: | 968 | case BPF_JSGE: |
| 947 | /* signed '>=', GE in x86 */ | 969 | /* signed '>=', GE in x86 */ |
| 948 | jmp_cond = X86_JGE; | 970 | jmp_cond = X86_JGE; |
| 949 | break; | 971 | break; |
| 972 | case BPF_JSLE: | ||
| 973 | /* signed '<=', LE in x86 */ | ||
| 974 | jmp_cond = X86_JLE; | ||
| 975 | break; | ||
| 950 | default: /* to silence gcc warning */ | 976 | default: /* to silence gcc warning */ |
| 951 | return -EFAULT; | 977 | return -EFAULT; |
| 952 | } | 978 | } |
