bpf, x86: implement jiting of BPF_J{LT,LE,SLT,SLE}
authorDaniel Borkmann <daniel@iogearbox.net>
Wed, 9 Aug 2017 23:39:56 +0000 (01:39 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Aug 2017 23:53:56 +0000 (16:53 -0700)
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>
arch/x86/net/bpf_jit_comp.c

index e1324f280e06eb86c9aa9c2249cdba6b6c036c4b..8194696e2805852a8246bf1db2a5862d5758f76b 100644 (file)
@@ -94,7 +94,9 @@ static int bpf_size_to_x86_bytes(int bpf_size)
 #define X86_JNE 0x75
 #define X86_JBE 0x76
 #define X86_JA  0x77
+#define X86_JL  0x7C
 #define X86_JGE 0x7D
+#define X86_JLE 0x7E
 #define X86_JG  0x7F
 
 static void bpf_flush_icache(void *start, void *end)
@@ -888,9 +890,13 @@ xadd:                      if (is_imm8(insn->off))
                case BPF_JMP | BPF_JEQ | BPF_X:
                case BPF_JMP | BPF_JNE | 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_JLE | 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_JSLE | BPF_X:
                        /* cmp dst_reg, src_reg */
                        EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39,
                              add_2reg(0xC0, dst_reg, src_reg));
@@ -911,9 +917,13 @@ xadd:                      if (is_imm8(insn->off))
                case BPF_JMP | BPF_JEQ | BPF_K:
                case BPF_JMP | BPF_JNE | 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_JLE | 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_JSLE | BPF_K:
                        /* cmp dst_reg, imm8/32 */
                        EMIT1(add_1mod(0x48, dst_reg));
 
@@ -935,18 +945,34 @@ emit_cond_jmp:            /* convert BPF opcode to x86 */
                                /* GT is unsigned '>', JA in x86 */
                                jmp_cond = X86_JA;
                                break;
+                       case BPF_JLT:
+                               /* LT is unsigned '<', JB in x86 */
+                               jmp_cond = X86_JB;
+                               break;
                        case BPF_JGE:
                                /* GE is unsigned '>=', JAE in x86 */
                                jmp_cond = X86_JAE;
                                break;
+                       case BPF_JLE:
+                               /* LE is unsigned '<=', JBE in x86 */
+                               jmp_cond = X86_JBE;
+                               break;
                        case BPF_JSGT:
                                /* signed '>', GT in x86 */
                                jmp_cond = X86_JG;
                                break;
+                       case BPF_JSLT:
+                               /* signed '<', LT in x86 */
+                               jmp_cond = X86_JL;
+                               break;
                        case BPF_JSGE:
                                /* signed '>=', GE in x86 */
                                jmp_cond = X86_JGE;
                                break;
+                       case BPF_JSLE:
+                               /* signed '<=', LE in x86 */
+                               jmp_cond = X86_JLE;
+                               break;
                        default: /* to silence gcc warning */
                                return -EFAULT;
                        }