OSDN Git Service

bpf: interpreter support for JMP32
authorJiong Wang <jiong.wang@netronome.com>
Sat, 26 Jan 2019 17:26:04 +0000 (12:26 -0500)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 26 Jan 2019 21:33:01 +0000 (13:33 -0800)
This patch implements interpreting new JMP32 instructions.

Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/core.c

index 1e443ba..bba11c2 100644 (file)
@@ -1145,6 +1145,31 @@ EXPORT_SYMBOL_GPL(__bpf_call_base);
        INSN_2(JMP, CALL),                      \
        /* Exit instruction. */                 \
        INSN_2(JMP, EXIT),                      \
+       /* 32-bit Jump instructions. */         \
+       /*   Register based. */                 \
+       INSN_3(JMP32, JEQ,  X),                 \
+       INSN_3(JMP32, JNE,  X),                 \
+       INSN_3(JMP32, JGT,  X),                 \
+       INSN_3(JMP32, JLT,  X),                 \
+       INSN_3(JMP32, JGE,  X),                 \
+       INSN_3(JMP32, JLE,  X),                 \
+       INSN_3(JMP32, JSGT, X),                 \
+       INSN_3(JMP32, JSLT, X),                 \
+       INSN_3(JMP32, JSGE, X),                 \
+       INSN_3(JMP32, JSLE, X),                 \
+       INSN_3(JMP32, JSET, X),                 \
+       /*   Immediate based. */                \
+       INSN_3(JMP32, JEQ,  K),                 \
+       INSN_3(JMP32, JNE,  K),                 \
+       INSN_3(JMP32, JGT,  K),                 \
+       INSN_3(JMP32, JLT,  K),                 \
+       INSN_3(JMP32, JGE,  K),                 \
+       INSN_3(JMP32, JLE,  K),                 \
+       INSN_3(JMP32, JSGT, K),                 \
+       INSN_3(JMP32, JSLT, K),                 \
+       INSN_3(JMP32, JSGE, K),                 \
+       INSN_3(JMP32, JSLE, K),                 \
+       INSN_3(JMP32, JSET, K),                 \
        /* Jump instructions. */                \
        /*   Register based. */                 \
        INSN_3(JMP, JEQ,  X),                   \
@@ -1405,145 +1430,49 @@ select_insn:
 out:
                CONT;
        }
-       /* JMP */
        JMP_JA:
                insn += insn->off;
                CONT;
-       JMP_JEQ_X:
-               if (DST == SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JEQ_K:
-               if (DST == IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JNE_X:
-               if (DST != SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JNE_K:
-               if (DST != IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JGT_X:
-               if (DST > SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JGT_K:
-               if (DST > IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JLT_X:
-               if (DST < SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JLT_K:
-               if (DST < IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JGE_X:
-               if (DST >= SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JGE_K:
-               if (DST >= IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JLE_X:
-               if (DST <= SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JLE_K:
-               if (DST <= IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSGT_X:
-               if (((s64) DST) > ((s64) SRC)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSGT_K:
-               if (((s64) DST) > ((s64) IMM)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSLT_X:
-               if (((s64) DST) < ((s64) SRC)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSLT_K:
-               if (((s64) DST) < ((s64) IMM)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSGE_X:
-               if (((s64) DST) >= ((s64) SRC)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSGE_K:
-               if (((s64) DST) >= ((s64) IMM)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSLE_X:
-               if (((s64) DST) <= ((s64) SRC)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSLE_K:
-               if (((s64) DST) <= ((s64) IMM)) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSET_X:
-               if (DST & SRC) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
-       JMP_JSET_K:
-               if (DST & IMM) {
-                       insn += insn->off;
-                       CONT_JMP;
-               }
-               CONT;
        JMP_EXIT:
                return BPF_R0;
-
+       /* JMP */
+#define COND_JMP(SIGN, OPCODE, CMP_OP)                         \
+       JMP_##OPCODE##_X:                                       \
+               if ((SIGN##64) DST CMP_OP (SIGN##64) SRC) {     \
+                       insn += insn->off;                      \
+                       CONT_JMP;                               \
+               }                                               \
+               CONT;                                           \
+       JMP32_##OPCODE##_X:                                     \
+               if ((SIGN##32) DST CMP_OP (SIGN##32) SRC) {     \
+                       insn += insn->off;                      \
+                       CONT_JMP;                               \
+               }                                               \
+               CONT;                                           \
+       JMP_##OPCODE##_K:                                       \
+               if ((SIGN##64) DST CMP_OP (SIGN##64) IMM) {     \
+                       insn += insn->off;                      \
+                       CONT_JMP;                               \
+               }                                               \
+               CONT;                                           \
+       JMP32_##OPCODE##_K:                                     \
+               if ((SIGN##32) DST CMP_OP (SIGN##32) IMM) {     \
+                       insn += insn->off;                      \
+                       CONT_JMP;                               \
+               }                                               \
+               CONT;
+       COND_JMP(u, JEQ, ==)
+       COND_JMP(u, JNE, !=)
+       COND_JMP(u, JGT, >)
+       COND_JMP(u, JLT, <)
+       COND_JMP(u, JGE, >=)
+       COND_JMP(u, JLE, <=)
+       COND_JMP(u, JSET, &)
+       COND_JMP(s, JSGT, >)
+       COND_JMP(s, JSLT, <)
+       COND_JMP(s, JSGE, >=)
+       COND_JMP(s, JSLE, <=)
+#undef COND_JMP
        /* STX and ST and LDX*/
 #define LDST(SIZEOP, SIZE)                                             \
        STX_MEM_##SIZEOP:                                               \