Skip to content

Commit 624e10a

Browse files
aspskKernel Patches Daemon
authored andcommitted
bpf, x86: allow indirect jumps to r8...r15
Currently the emit_indirect_jump() function only accepts one of the RAX, RCX, ..., RBP registers as the destination. Make it to accept R8, R9, ..., R15 as well, and make callers to pass BPF registers, not native registers. This is required to enable indirect jumps support in eBPF. Signed-off-by: Anton Protopopov <[email protected]> Acked-by: Eduard Zingerman <[email protected]>
1 parent ea3aac4 commit 624e10a

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

arch/x86/net/bpf_jit_comp.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -660,24 +660,38 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
660660

661661
#define EMIT_LFENCE() EMIT3(0x0F, 0xAE, 0xE8)
662662

663-
static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
663+
static void __emit_indirect_jump(u8 **pprog, int reg, bool ereg)
664664
{
665665
u8 *prog = *pprog;
666666

667+
if (ereg)
668+
EMIT1(0x41);
669+
670+
EMIT2(0xFF, 0xE0 + reg);
671+
672+
*pprog = prog;
673+
}
674+
675+
static void emit_indirect_jump(u8 **pprog, int bpf_reg, u8 *ip)
676+
{
677+
u8 *prog = *pprog;
678+
int reg = reg2hex[bpf_reg];
679+
bool ereg = is_ereg(bpf_reg);
680+
667681
if (cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
668682
OPTIMIZER_HIDE_VAR(reg);
669-
emit_jump(&prog, its_static_thunk(reg), ip);
683+
emit_jump(&prog, its_static_thunk(reg + 8*ereg), ip);
670684
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
671685
EMIT_LFENCE();
672-
EMIT2(0xFF, 0xE0 + reg);
686+
__emit_indirect_jump(&prog, reg, ereg);
673687
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
674688
OPTIMIZER_HIDE_VAR(reg);
675689
if (cpu_feature_enabled(X86_FEATURE_CALL_DEPTH))
676-
emit_jump(&prog, &__x86_indirect_jump_thunk_array[reg], ip);
690+
emit_jump(&prog, &__x86_indirect_jump_thunk_array[reg + 8*ereg], ip);
677691
else
678-
emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip);
692+
emit_jump(&prog, &__x86_indirect_thunk_array[reg + 8*ereg], ip);
679693
} else {
680-
EMIT2(0xFF, 0xE0 + reg); /* jmp *%\reg */
694+
__emit_indirect_jump(&prog, reg, ereg);
681695
if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) || IS_ENABLED(CONFIG_MITIGATION_SLS))
682696
EMIT1(0xCC); /* int3 */
683697
}
@@ -797,7 +811,7 @@ static void emit_bpf_tail_call_indirect(struct bpf_prog *bpf_prog,
797811
* rdi == ctx (1st arg)
798812
* rcx == prog->bpf_func + X86_TAIL_CALL_OFFSET
799813
*/
800-
emit_indirect_jump(&prog, 1 /* rcx */, ip + (prog - start));
814+
emit_indirect_jump(&prog, BPF_REG_4 /* R4 -> rcx */, ip + (prog - start));
801815

802816
/* out: */
803817
ctx->tail_call_indirect_label = prog - start;
@@ -3543,7 +3557,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs, u8 *image,
35433557
if (err)
35443558
return err;
35453559

3546-
emit_indirect_jump(&prog, 2 /* rdx */, image + (prog - buf));
3560+
emit_indirect_jump(&prog, BPF_REG_3 /* R3 -> rdx */, image + (prog - buf));
35473561

35483562
*pprog = prog;
35493563
return 0;

0 commit comments

Comments
 (0)