Cc: Wang YanQing <udkni...@gmail.com>
Signed-off-by: Jiong Wang <jiong.w...@netronome.com>
---
 arch/x86/net/bpf_jit_comp32.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
index 0d9cdff..8b2576e 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -567,7 +567,7 @@ static inline void emit_ia32_alu_r(const bool is64, const 
bool hi, const u8 op,
 static inline void emit_ia32_alu_r64(const bool is64, const u8 op,
                                     const u8 dst[], const u8 src[],
                                     bool dstk,  bool sstk,
-                                    u8 **pprog)
+                                    u8 **pprog, const struct bpf_prog_aux *aux)
 {
        u8 *prog = *pprog;
 
@@ -575,7 +575,7 @@ static inline void emit_ia32_alu_r64(const bool is64, const 
u8 op,
        if (is64)
                emit_ia32_alu_r(is64, true, op, dst_hi, src_hi, dstk, sstk,
                                &prog);
-       else
+       else if (!aux->verifier_zext)
                emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
        *pprog = prog;
 }
@@ -666,7 +666,8 @@ static inline void emit_ia32_alu_i(const bool is64, const 
bool hi, const u8 op,
 /* ALU operation (64 bit) */
 static inline void emit_ia32_alu_i64(const bool is64, const u8 op,
                                     const u8 dst[], const u32 val,
-                                    bool dstk, u8 **pprog)
+                                    bool dstk, u8 **pprog,
+                                    const struct bpf_prog_aux *aux)
 {
        u8 *prog = *pprog;
        u32 hi = 0;
@@ -677,7 +678,7 @@ static inline void emit_ia32_alu_i64(const bool is64, const 
u8 op,
        emit_ia32_alu_i(is64, false, op, dst_lo, val, dstk, &prog);
        if (is64)
                emit_ia32_alu_i(is64, true, op, dst_hi, hi, dstk, &prog);
-       else
+       else if (!aux->verifier_zext)
                emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
 
        *pprog = prog;
@@ -1642,6 +1643,10 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
 
                switch (code) {
                /* ALU operations */
+               /* Explicit zero extension */
+               case BPF_ALU | BPF_ZEXT:
+                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       break;
                /* dst = src */
                case BPF_ALU | BPF_MOV | BPF_K:
                case BPF_ALU | BPF_MOV | BPF_X:
@@ -1690,11 +1695,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int 
*addrs, u8 *image,
                        switch (BPF_SRC(code)) {
                        case BPF_X:
                                emit_ia32_alu_r64(is64, BPF_OP(code), dst,
-                                                 src, dstk, sstk, &prog);
+                                                 src, dstk, sstk, &prog,
+                                                 bpf_prog->aux);
                                break;
                        case BPF_K:
                                emit_ia32_alu_i64(is64, BPF_OP(code), dst,
-                                                 imm32, dstk, &prog);
+                                                 imm32, dstk, &prog,
+                                                 bpf_prog->aux);
                                break;
                        }
                        break;
@@ -1713,7 +1720,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
                                                false, &prog);
                                break;
                        }
-                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       if (!bpf_prog->aux->verifier_zext)
+                               emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
                        break;
                case BPF_ALU | BPF_LSH | BPF_X:
                case BPF_ALU | BPF_RSH | BPF_X:
@@ -1733,7 +1741,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
                                                  &prog);
                                break;
                        }
-                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       if (!bpf_prog->aux->verifier_zext)
+                               emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
                        break;
                /* dst = dst / src(imm) */
                /* dst = dst % src(imm) */
@@ -1755,7 +1764,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
                                                    &prog);
                                break;
                        }
-                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       if (!bpf_prog->aux->verifier_zext)
+                               emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
                        break;
                case BPF_ALU64 | BPF_DIV | BPF_K:
                case BPF_ALU64 | BPF_DIV | BPF_X:
@@ -1772,7 +1782,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
                        EMIT2_off32(0xC7, add_1reg(0xC0, IA32_ECX), imm32);
                        emit_ia32_shift_r(BPF_OP(code), dst_lo, IA32_ECX, dstk,
                                          false, &prog);
-                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       if (!bpf_prog->aux->verifier_zext)
+                               emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
                        break;
                /* dst = dst << imm */
                case BPF_ALU64 | BPF_LSH | BPF_K:
@@ -1808,7 +1819,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
                case BPF_ALU | BPF_NEG:
                        emit_ia32_alu_i(is64, false, BPF_OP(code),
                                        dst_lo, 0, dstk, &prog);
-                       emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
+                       if (!bpf_prog->aux->verifier_zext)
+                               emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
                        break;
                /* dst = ~dst (64 bit) */
                case BPF_ALU64 | BPF_NEG:
@@ -2367,6 +2379,11 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, 
u8 *image,
        return proglen;
 }
 
+bool bpf_jit_hardware_zext(void)
+{
+       return false;
+}
+
 struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 {
        struct bpf_binary_header *header = NULL;
-- 
2.7.4

Reply via email to