Commit 52afc51e authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

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: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 92b31a9a
...@@ -94,7 +94,9 @@ static int bpf_size_to_x86_bytes(int bpf_size) ...@@ -94,7 +94,9 @@ static int bpf_size_to_x86_bytes(int bpf_size)
#define X86_JNE 0x75 #define X86_JNE 0x75
#define X86_JBE 0x76 #define X86_JBE 0x76
#define X86_JA 0x77 #define X86_JA 0x77
#define X86_JL 0x7C
#define X86_JGE 0x7D #define X86_JGE 0x7D
#define X86_JLE 0x7E
#define X86_JG 0x7F #define X86_JG 0x7F
static void bpf_flush_icache(void *start, void *end) static void bpf_flush_icache(void *start, void *end)
...@@ -888,9 +890,13 @@ xadd: if (is_imm8(insn->off)) ...@@ -888,9 +890,13 @@ xadd: if (is_imm8(insn->off))
case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JEQ | BPF_X:
case BPF_JMP | BPF_JNE | BPF_X: case BPF_JMP | BPF_JNE | BPF_X:
case BPF_JMP | BPF_JGT | BPF_X: case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X: case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JSGT | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
/* cmp dst_reg, src_reg */ /* cmp dst_reg, src_reg */
EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39, EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39,
add_2reg(0xC0, dst_reg, src_reg)); add_2reg(0xC0, dst_reg, src_reg));
...@@ -911,9 +917,13 @@ xadd: if (is_imm8(insn->off)) ...@@ -911,9 +917,13 @@ xadd: if (is_imm8(insn->off))
case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JNE | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K: case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K: case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
case BPF_JMP | BPF_JSGT | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_K:
/* cmp dst_reg, imm8/32 */ /* cmp dst_reg, imm8/32 */
EMIT1(add_1mod(0x48, dst_reg)); EMIT1(add_1mod(0x48, dst_reg));
...@@ -935,18 +945,34 @@ xadd: if (is_imm8(insn->off)) ...@@ -935,18 +945,34 @@ xadd: if (is_imm8(insn->off))
/* GT is unsigned '>', JA in x86 */ /* GT is unsigned '>', JA in x86 */
jmp_cond = X86_JA; jmp_cond = X86_JA;
break; break;
case BPF_JLT:
/* LT is unsigned '<', JB in x86 */
jmp_cond = X86_JB;
break;
case BPF_JGE: case BPF_JGE:
/* GE is unsigned '>=', JAE in x86 */ /* GE is unsigned '>=', JAE in x86 */
jmp_cond = X86_JAE; jmp_cond = X86_JAE;
break; break;
case BPF_JLE:
/* LE is unsigned '<=', JBE in x86 */
jmp_cond = X86_JBE;
break;
case BPF_JSGT: case BPF_JSGT:
/* signed '>', GT in x86 */ /* signed '>', GT in x86 */
jmp_cond = X86_JG; jmp_cond = X86_JG;
break; break;
case BPF_JSLT:
/* signed '<', LT in x86 */
jmp_cond = X86_JL;
break;
case BPF_JSGE: case BPF_JSGE:
/* signed '>=', GE in x86 */ /* signed '>=', GE in x86 */
jmp_cond = X86_JGE; jmp_cond = X86_JGE;
break; break;
case BPF_JSLE:
/* signed '<=', LE in x86 */
jmp_cond = X86_JLE;
break;
default: /* to silence gcc warning */ default: /* to silence gcc warning */
return -EFAULT; return -EFAULT;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment