From 95df7307a77de5d28b4c81151a8dcc100be8172c Mon Sep 17 00:00:00 2001 From: Konstantin Ananyev Date: Thu, 8 Nov 2018 12:36:43 +0000 Subject: [PATCH] bpf: fix x86 JIT for immediate loads x86 jit can generate invalid code for (BPF_LD | BPF_IMM | EBPF_DW) instructions, when immediate value is bigger then INT32_MAX. Fixes: cc752e43e079 ("bpf: add JIT compilation for x86_64 ISA") Cc: stable@dpdk.org Signed-off-by: Konstantin Ananyev --- lib/librte_bpf/bpf_jit_x86.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/librte_bpf/bpf_jit_x86.c b/lib/librte_bpf/bpf_jit_x86.c index 68ea389f23..f70cd6be51 100644 --- a/lib/librte_bpf/bpf_jit_x86.c +++ b/lib/librte_bpf/bpf_jit_x86.c @@ -208,6 +208,19 @@ emit_sib(struct bpf_jit_state *st, uint32_t scale, uint32_t idx, uint32_t base) emit_bytes(st, &v, sizeof(v)); } +/* + * emit OPCODE+REGIDX byte + */ +static void +emit_opcode(struct bpf_jit_state *st, uint8_t ops, uint32_t reg) +{ + uint8_t v; + + v = ops | (reg & 7); + emit_bytes(st, &v, sizeof(v)); +} + + /* * emit xchg %, % */ @@ -472,19 +485,18 @@ static void emit_ld_imm64(struct bpf_jit_state *st, uint32_t dreg, uint32_t imm0, uint32_t imm1) { + uint32_t op; + const uint8_t ops = 0xB8; - if (imm1 == 0) { - emit_mov_imm(st, EBPF_ALU64 | EBPF_MOV | BPF_K, dreg, imm0); - return; - } + op = (imm1 == 0) ? BPF_ALU : EBPF_ALU64; - emit_rex(st, EBPF_ALU64, 0, dreg); - emit_bytes(st, &ops, sizeof(ops)); - emit_modregrm(st, MOD_DIRECT, 0, dreg); + emit_rex(st, op, 0, dreg); + emit_opcode(st, ops, dreg); emit_imm(st, imm0, sizeof(imm0)); - emit_imm(st, imm1, sizeof(imm1)); + if (imm1 != 0) + emit_imm(st, imm1, sizeof(imm1)); } /* -- 2.20.1