Skip to content

Commit 6cb395e

Browse files
image-dragonKernel Patches Daemon
authored andcommitted
bpf,x86: adjust the "jmp" mode for bpf trampoline
In the origin call case, if BPF_TRAMP_F_SKIP_FRAME is not set, it means that the trampoline is not called, but "jmp". Introduce the function bpf_trampoline_use_jmp() to check if the trampoline is in "jmp" mode. Do some adjustment on the "jmp" mode for the x86_64. The main adjustment that we make is for the stack parameter passing case, as the stack alignment logic changes in the "jmp" mode without the "rip". What's more, the location of the parameters on the stack also changes. Signed-off-by: Menglong Dong <[email protected]>
1 parent 5f208a9 commit 6cb395e

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

arch/x86/net/bpf_jit_comp.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2847,9 +2847,10 @@ static int get_nr_used_regs(const struct btf_func_model *m)
28472847
}
28482848

28492849
static void save_args(const struct btf_func_model *m, u8 **prog,
2850-
int stack_size, bool for_call_origin)
2850+
int stack_size, bool for_call_origin, u32 flags)
28512851
{
28522852
int arg_regs, first_off = 0, nr_regs = 0, nr_stack_slots = 0;
2853+
bool use_jmp = bpf_trampoline_use_jmp(flags);
28532854
int i, j;
28542855

28552856
/* Store function arguments to stack.
@@ -2890,7 +2891,7 @@ static void save_args(const struct btf_func_model *m, u8 **prog,
28902891
*/
28912892
for (j = 0; j < arg_regs; j++) {
28922893
emit_ldx(prog, BPF_DW, BPF_REG_0, BPF_REG_FP,
2893-
nr_stack_slots * 8 + 0x18);
2894+
nr_stack_slots * 8 + 16 + (!use_jmp) * 8);
28942895
emit_stx(prog, BPF_DW, BPF_REG_FP, BPF_REG_0,
28952896
-stack_size);
28962897

@@ -3284,7 +3285,12 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
32843285
* should be 16-byte aligned. Following code depend on
32853286
* that stack_size is already 8-byte aligned.
32863287
*/
3287-
stack_size += (stack_size % 16) ? 0 : 8;
3288+
if (bpf_trampoline_use_jmp(flags)) {
3289+
/* no rip in the "jmp" case */
3290+
stack_size += (stack_size % 16) ? 8 : 0;
3291+
} else {
3292+
stack_size += (stack_size % 16) ? 0 : 8;
3293+
}
32883294
}
32893295

32903296
arg_stack_off = stack_size;
@@ -3344,7 +3350,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
33443350
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off);
33453351
}
33463352

3347-
save_args(m, &prog, regs_off, false);
3353+
save_args(m, &prog, regs_off, false, flags);
33483354

33493355
if (flags & BPF_TRAMP_F_CALL_ORIG) {
33503356
/* arg1: mov rdi, im */
@@ -3377,7 +3383,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
33773383

33783384
if (flags & BPF_TRAMP_F_CALL_ORIG) {
33793385
restore_regs(m, &prog, regs_off);
3380-
save_args(m, &prog, arg_stack_off, true);
3386+
save_args(m, &prog, arg_stack_off, true, flags);
33813387

33823388
if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) {
33833389
/* Before calling the original function, load the

include/linux/bpf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,18 @@ typedef void (*bpf_trampoline_exit_t)(struct bpf_prog *prog, u64 start,
12641264
bpf_trampoline_enter_t bpf_trampoline_enter(const struct bpf_prog *prog);
12651265
bpf_trampoline_exit_t bpf_trampoline_exit(const struct bpf_prog *prog);
12661266

1267+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_JMP
1268+
static inline bool bpf_trampoline_use_jmp(u64 flags)
1269+
{
1270+
return flags & BPF_TRAMP_F_CALL_ORIG && !(flags & BPF_TRAMP_F_SKIP_FRAME);
1271+
}
1272+
#else
1273+
static inline bool bpf_trampoline_use_jmp(u64 flags)
1274+
{
1275+
return false;
1276+
}
1277+
#endif
1278+
12671279
struct bpf_ksym {
12681280
unsigned long start;
12691281
unsigned long end;

0 commit comments

Comments
 (0)