mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-09 15:24:32 +08:00
bpf, x64: Factor out emission of REX byte in more cases
commit 6364d7d75a
upstream.
Introduce a single reg version of maybe_emit_mod() and factor out
common code in more cases.
Signed-off-by: Jie Meng <jmeng@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20211006194135.608932-1-jmeng@fb.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7e83a6577d
commit
eea5a58d86
@ -721,6 +721,20 @@ static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
|
||||
*pprog = prog;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar version of maybe_emit_mod() for a single register
|
||||
*/
|
||||
static void maybe_emit_1mod(u8 **pprog, u32 reg, bool is64)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
|
||||
if (is64)
|
||||
EMIT1(add_1mod(0x48, reg));
|
||||
else if (is_ereg(reg))
|
||||
EMIT1(add_1mod(0x40, reg));
|
||||
*pprog = prog;
|
||||
}
|
||||
|
||||
/* LDX: dst_reg = *(u8*)(src_reg + off) */
|
||||
static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
{
|
||||
@ -951,10 +965,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||
/* neg dst */
|
||||
case BPF_ALU | BPF_NEG:
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
if (BPF_CLASS(insn->code) == BPF_ALU64)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_ALU64);
|
||||
EMIT2(0xF7, add_1reg(0xD8, dst_reg));
|
||||
break;
|
||||
|
||||
@ -968,10 +980,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||
case BPF_ALU64 | BPF_AND | BPF_K:
|
||||
case BPF_ALU64 | BPF_OR | BPF_K:
|
||||
case BPF_ALU64 | BPF_XOR | BPF_K:
|
||||
if (BPF_CLASS(insn->code) == BPF_ALU64)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_ALU64);
|
||||
|
||||
/*
|
||||
* b3 holds 'normal' opcode, b2 short form only valid
|
||||
@ -1112,10 +1122,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||
case BPF_ALU64 | BPF_LSH | BPF_K:
|
||||
case BPF_ALU64 | BPF_RSH | BPF_K:
|
||||
case BPF_ALU64 | BPF_ARSH | BPF_K:
|
||||
if (BPF_CLASS(insn->code) == BPF_ALU64)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_ALU64);
|
||||
|
||||
b3 = simple_alu_opcodes[BPF_OP(insn->code)];
|
||||
if (imm32 == 1)
|
||||
@ -1146,10 +1154,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||
}
|
||||
|
||||
/* shl %rax, %cl | shr %rax, %cl | sar %rax, %cl */
|
||||
if (BPF_CLASS(insn->code) == BPF_ALU64)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_ALU64);
|
||||
|
||||
b3 = simple_alu_opcodes[BPF_OP(insn->code)];
|
||||
EMIT2(0xD3, add_1reg(b3, dst_reg));
|
||||
@ -1459,10 +1465,8 @@ st: if (is_imm8(insn->off))
|
||||
case BPF_JMP | BPF_JSET | BPF_K:
|
||||
case BPF_JMP32 | BPF_JSET | BPF_K:
|
||||
/* test dst_reg, imm32 */
|
||||
if (BPF_CLASS(insn->code) == BPF_JMP)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_JMP);
|
||||
EMIT2_off32(0xF7, add_1reg(0xC0, dst_reg), imm32);
|
||||
goto emit_cond_jmp;
|
||||
|
||||
@ -1495,10 +1499,8 @@ st: if (is_imm8(insn->off))
|
||||
}
|
||||
|
||||
/* cmp dst_reg, imm8/32 */
|
||||
if (BPF_CLASS(insn->code) == BPF_JMP)
|
||||
EMIT1(add_1mod(0x48, dst_reg));
|
||||
else if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
maybe_emit_1mod(&prog, dst_reg,
|
||||
BPF_CLASS(insn->code) == BPF_JMP);
|
||||
|
||||
if (is_imm8(imm32))
|
||||
EMIT3(0x83, add_1reg(0xF8, dst_reg), imm32);
|
||||
|
Loading…
Reference in New Issue
Block a user