Skip to content

Commit acf8726

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-trampoline-support-jmp-mode'
Menglong Dong says: ==================== bpf trampoline support "jmp" mode For now, the bpf trampoline is called by the "call" instruction. However, it break the RSB and introduce extra overhead in x86_64 arch. For example, we hook the function "foo" with fexit, the call and return logic will be like this: call foo -> call trampoline -> call foo-body -> return foo-body -> return foo As we can see above, there are 3 call, but 2 return, which break the RSB balance. We can pseudo a "return" here, but it's not the best choice, as it will still cause once RSB miss: call foo -> call trampoline -> call foo-body -> return foo-body -> return dummy -> return foo The "return dummy" doesn't pair the "call trampoline", which can also cause the RSB miss. Therefore, we introduce the "jmp" mode for bpf trampoline, as advised by Alexei in [1]. And the logic will become this: call foo -> jmp trampoline -> call foo-body -> return foo-body -> return foo As we can see above, the RSB is totally balanced after this series. In this series, we introduce the FTRACE_OPS_FL_JMP for ftrace to make it use the "jmp" instruction instead of "call". And we also do some adjustment to bpf_arch_text_poke() to allow us specify the old and new poke_type. For the BPF_TRAMP_F_SHARE_IPMODIFY case, we will fallback to the "call" mode, as it need to get the function address from the stack, which is not supported in "jmp" mode. Before this series, we have the following performance with the bpf benchmark: $ cd tools/testing/selftests/bpf $ ./benchs/run_bench_trigger.sh usermode-count : 890.171 ± 1.522M/s kernel-count : 409.184 ± 0.330M/s syscall-count : 26.792 ± 0.010M/s fentry : 171.242 ± 0.322M/s fexit : 80.544 ± 0.045M/s fmodret : 78.301 ± 0.065M/s rawtp : 192.906 ± 0.900M/s tp : 81.883 ± 0.209M/s kprobe : 52.029 ± 0.113M/s kprobe-multi : 62.237 ± 0.060M/s kprobe-multi-all: 4.761 ± 0.014M/s kretprobe : 23.779 ± 0.046M/s kretprobe-multi: 29.134 ± 0.012M/s kretprobe-multi-all: 3.822 ± 0.003M/ And after this series, we have the following performance: usermode-count : 890.443 ± 0.307M/s kernel-count : 416.139 ± 0.055M/s syscall-count : 31.037 ± 0.813M/s fentry : 169.549 ± 0.519M/s fexit : 136.540 ± 0.518M/s fmodret : 159.248 ± 0.188M/s rawtp : 194.475 ± 0.144M/s tp : 84.505 ± 0.041M/s kprobe : 59.951 ± 0.071M/s kprobe-multi : 63.153 ± 0.177M/s kprobe-multi-all: 4.699 ± 0.012M/s kretprobe : 23.740 ± 0.015M/s kretprobe-multi: 29.301 ± 0.022M/s kretprobe-multi-all: 3.869 ± 0.005M/s As we can see above, the performance of fexit increase from 80.544M/s to 136.540M/s, and the "fmodret" increase from 78.301M/s to 159.248M/s. Link: https://lore.kernel.org/bpf/20251117034906.32036-1-dongml2@chinatelecom.cn/ Changes since v2: * reject if the addr is already "jmp" in register_ftrace_direct() and __modify_ftrace_direct() in the 1st patch. * fix compile error in powerpc in the 5th patch. * changes in the 6th patch: - fix the compile error by wrapping the write to tr->fops->flags with CONFIG_DYNAMIC_FTRACE_WITH_JMP - reset BPF_TRAMP_F_SKIP_FRAME when the second try of modify_fentry in bpf_trampoline_update() Link: https://lore.kernel.org/bpf/20251114092450.172024-1-dongml2@chinatelecom.cn/ Changes since v1: * change the bool parameter that we add to save_args() to "u32 flags" * rename bpf_trampoline_need_jmp() to bpf_trampoline_use_jmp() * add new function parameter to bpf_arch_text_poke instead of introduce bpf_arch_text_poke_type() * rename bpf_text_poke to bpf_trampoline_update_fentry * remove the BPF_TRAMP_F_JMPED and check the current mode with the origin flags instead. Link: https://lore.kernel.org/bpf/CAADnVQLX54sVi1oaHrkSiLqjJaJdm3TQjoVrgU-LZimK6iDcSA@mail.gmail.com/[1] ==================== Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org> Link: https://patch.msgid.link/20251118123639.688444-1-dongml2@chinatelecom.cn Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents fad8040 + 402e44b commit acf8726

File tree

15 files changed

+225
-65
lines changed

15 files changed

+225
-65
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2934,8 +2934,9 @@ static int gen_branch_or_nop(enum aarch64_insn_branch_type type, void *ip,
29342934
* The dummy_tramp is used to prevent another CPU from jumping to unknown
29352935
* locations during the patching process, making the patching process easier.
29362936
*/
2937-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
2938-
void *old_addr, void *new_addr)
2937+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
2938+
enum bpf_text_poke_type new_t, void *old_addr,
2939+
void *new_addr)
29392940
{
29402941
int ret;
29412942
u32 old_insn;
@@ -2979,14 +2980,13 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
29792980
!poking_bpf_entry))
29802981
return -EINVAL;
29812982

2982-
if (poke_type == BPF_MOD_CALL)
2983-
branch_type = AARCH64_INSN_BRANCH_LINK;
2984-
else
2985-
branch_type = AARCH64_INSN_BRANCH_NOLINK;
2986-
2983+
branch_type = old_t == BPF_MOD_CALL ? AARCH64_INSN_BRANCH_LINK :
2984+
AARCH64_INSN_BRANCH_NOLINK;
29872985
if (gen_branch_or_nop(branch_type, ip, old_addr, plt, &old_insn) < 0)
29882986
return -EFAULT;
29892987

2988+
branch_type = new_t == BPF_MOD_CALL ? AARCH64_INSN_BRANCH_LINK :
2989+
AARCH64_INSN_BRANCH_NOLINK;
29902990
if (gen_branch_or_nop(branch_type, ip, new_addr, plt, &new_insn) < 0)
29912991
return -EFAULT;
29922992

arch/loongarch/net/bpf_jit.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,11 +1284,12 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len)
12841284
return ret ? ERR_PTR(-EINVAL) : dst;
12851285
}
12861286

1287-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
1288-
void *old_addr, void *new_addr)
1287+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
1288+
enum bpf_text_poke_type new_t, void *old_addr,
1289+
void *new_addr)
12891290
{
12901291
int ret;
1291-
bool is_call = (poke_type == BPF_MOD_CALL);
1292+
bool is_call;
12921293
u32 old_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
12931294
u32 new_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
12941295

@@ -1298,13 +1299,15 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
12981299
if (!is_bpf_text_address((unsigned long)ip))
12991300
return -ENOTSUPP;
13001301

1302+
is_call = old_t == BPF_MOD_CALL;
13011303
ret = emit_jump_or_nops(old_addr, ip, old_insns, is_call);
13021304
if (ret)
13031305
return ret;
13041306

13051307
if (memcmp(ip, old_insns, LOONGARCH_LONG_JUMP_NBYTES))
13061308
return -EFAULT;
13071309

1310+
is_call = new_t == BPF_MOD_CALL;
13081311
ret = emit_jump_or_nops(new_addr, ip, new_insns, is_call);
13091312
if (ret)
13101313
return ret;

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,8 +1107,9 @@ static void do_isync(void *info __maybe_unused)
11071107
* execute isync (or some CSI) so that they don't go back into the
11081108
* trampoline again.
11091109
*/
1110-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
1111-
void *old_addr, void *new_addr)
1110+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
1111+
enum bpf_text_poke_type new_t, void *old_addr,
1112+
void *new_addr)
11121113
{
11131114
unsigned long bpf_func, bpf_func_end, size, offset;
11141115
ppc_inst_t old_inst, new_inst;
@@ -1119,7 +1120,6 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
11191120
return -EOPNOTSUPP;
11201121

11211122
bpf_func = (unsigned long)ip;
1122-
branch_flags = poke_type == BPF_MOD_CALL ? BRANCH_SET_LINK : 0;
11231123

11241124
/* We currently only support poking bpf programs */
11251125
if (!__bpf_address_lookup(bpf_func, &size, &offset, name)) {
@@ -1132,7 +1132,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
11321132
* an unconditional branch instruction at im->ip_after_call
11331133
*/
11341134
if (offset) {
1135-
if (poke_type != BPF_MOD_JUMP) {
1135+
if (old_t == BPF_MOD_CALL || new_t == BPF_MOD_CALL) {
11361136
pr_err("%s (0x%lx): calls are not supported in bpf prog body\n", __func__,
11371137
bpf_func);
11381138
return -EOPNOTSUPP;
@@ -1166,6 +1166,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
11661166
}
11671167

11681168
old_inst = ppc_inst(PPC_RAW_NOP());
1169+
branch_flags = old_t == BPF_MOD_CALL ? BRANCH_SET_LINK : 0;
11691170
if (old_addr) {
11701171
if (is_offset_in_branch_range(ip - old_addr))
11711172
create_branch(&old_inst, ip, (unsigned long)old_addr, branch_flags);
@@ -1174,6 +1175,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
11741175
branch_flags);
11751176
}
11761177
new_inst = ppc_inst(PPC_RAW_NOP());
1178+
branch_flags = new_t == BPF_MOD_CALL ? BRANCH_SET_LINK : 0;
11771179
if (new_addr) {
11781180
if (is_offset_in_branch_range(ip - new_addr))
11791181
create_branch(&new_inst, ip, (unsigned long)new_addr, branch_flags);

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -852,24 +852,27 @@ static int gen_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
852852
return emit_jump_and_link(is_call ? RV_REG_T0 : RV_REG_ZERO, rvoff, false, &ctx);
853853
}
854854

855-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
856-
void *old_addr, void *new_addr)
855+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
856+
enum bpf_text_poke_type new_t, void *old_addr,
857+
void *new_addr)
857858
{
858859
u32 old_insns[RV_FENTRY_NINSNS], new_insns[RV_FENTRY_NINSNS];
859-
bool is_call = poke_type == BPF_MOD_CALL;
860+
bool is_call;
860861
int ret;
861862

862863
if (!is_kernel_text((unsigned long)ip) &&
863864
!is_bpf_text_address((unsigned long)ip))
864865
return -ENOTSUPP;
865866

867+
is_call = old_t == BPF_MOD_CALL;
866868
ret = gen_jump_or_nops(old_addr, ip, old_insns, is_call);
867869
if (ret)
868870
return ret;
869871

870872
if (memcmp(ip, old_insns, RV_FENTRY_NBYTES))
871873
return -EFAULT;
872874

875+
is_call = new_t == BPF_MOD_CALL;
873876
ret = gen_jump_or_nops(new_addr, ip, new_insns, is_call);
874877
if (ret)
875878
return ret;
@@ -1131,7 +1134,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
11311134
store_args(nr_arg_slots, args_off, ctx);
11321135

11331136
/* skip to actual body of traced function */
1134-
if (flags & BPF_TRAMP_F_SKIP_FRAME)
1137+
if (flags & BPF_TRAMP_F_ORIG_STACK)
11351138
orig_call += RV_FENTRY_NINSNS * 4;
11361139

11371140
if (flags & BPF_TRAMP_F_CALL_ORIG) {

arch/s390/net/bpf_jit_comp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,8 +2413,9 @@ bool bpf_jit_supports_far_kfunc_call(void)
24132413
return true;
24142414
}
24152415

2416-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
2417-
void *old_addr, void *new_addr)
2416+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
2417+
enum bpf_text_poke_type new_t, void *old_addr,
2418+
void *new_addr)
24182419
{
24192420
struct bpf_plt expected_plt, current_plt, new_plt, *plt;
24202421
struct {
@@ -2431,7 +2432,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
24312432
if (insn.opc != (0xc004 | (old_addr ? 0xf0 : 0)))
24322433
return -EINVAL;
24332434

2434-
if (t == BPF_MOD_JUMP &&
2435+
if ((new_t == BPF_MOD_JUMP || old_t == BPF_MOD_JUMP) &&
24352436
insn.disp == ((char *)new_addr - (char *)ip) >> 1) {
24362437
/*
24372438
* The branch already points to the destination,

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ config X86
230230
select HAVE_DYNAMIC_FTRACE_WITH_ARGS if X86_64
231231
select HAVE_FTRACE_REGS_HAVING_PT_REGS if X86_64
232232
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
233+
select HAVE_DYNAMIC_FTRACE_WITH_JMP if X86_64
233234
select HAVE_SAMPLE_FTRACE_DIRECT if X86_64
234235
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if X86_64
235236
select HAVE_EBPF_JIT

arch/x86/kernel/ftrace.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ static const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
7474
* No need to translate into a callthunk. The trampoline does
7575
* the depth accounting itself.
7676
*/
77-
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
77+
if (ftrace_is_jmp(addr)) {
78+
addr = ftrace_jmp_get(addr);
79+
return text_gen_insn(JMP32_INSN_OPCODE, (void *)ip, (void *)addr);
80+
} else {
81+
return text_gen_insn(CALL_INSN_OPCODE, (void *)ip, (void *)addr);
82+
}
7883
}
7984

8085
static int ftrace_verify_code(unsigned long ip, const char *old_code)

arch/x86/kernel/ftrace_64.S

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,18 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
285285
ANNOTATE_NOENDBR
286286
RET
287287

288+
1:
289+
testb $1, %al
290+
jz 2f
291+
andq $0xfffffffffffffffe, %rax
292+
movq %rax, MCOUNT_REG_SIZE+8(%rsp)
293+
restore_mcount_regs
294+
/* Restore flags */
295+
popfq
296+
RET
297+
288298
/* Swap the flags with orig_rax */
289-
1: movq MCOUNT_REG_SIZE(%rsp), %rdi
299+
2: movq MCOUNT_REG_SIZE(%rsp), %rdi
290300
movq %rdi, MCOUNT_REG_SIZE-8(%rsp)
291301
movq %rax, MCOUNT_REG_SIZE(%rsp)
292302

arch/x86/net/bpf_jit_comp.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,8 @@ static int emit_jump(u8 **pprog, void *func, void *ip)
597597
return emit_patch(pprog, func, ip, 0xE9);
598598
}
599599

600-
static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
600+
static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
601+
enum bpf_text_poke_type new_t,
601602
void *old_addr, void *new_addr)
602603
{
603604
const u8 *nop_insn = x86_nops[5];
@@ -607,19 +608,19 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
607608
int ret;
608609

609610
memcpy(old_insn, nop_insn, X86_PATCH_SIZE);
610-
if (old_addr) {
611+
if (old_t != BPF_MOD_NOP && old_addr) {
611612
prog = old_insn;
612-
ret = t == BPF_MOD_CALL ?
613+
ret = old_t == BPF_MOD_CALL ?
613614
emit_call(&prog, old_addr, ip) :
614615
emit_jump(&prog, old_addr, ip);
615616
if (ret)
616617
return ret;
617618
}
618619

619620
memcpy(new_insn, nop_insn, X86_PATCH_SIZE);
620-
if (new_addr) {
621+
if (new_t != BPF_MOD_NOP && new_addr) {
621622
prog = new_insn;
622-
ret = t == BPF_MOD_CALL ?
623+
ret = new_t == BPF_MOD_CALL ?
623624
emit_call(&prog, new_addr, ip) :
624625
emit_jump(&prog, new_addr, ip);
625626
if (ret)
@@ -640,8 +641,9 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
640641
return ret;
641642
}
642643

643-
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
644-
void *old_addr, void *new_addr)
644+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
645+
enum bpf_text_poke_type new_t, void *old_addr,
646+
void *new_addr)
645647
{
646648
if (!is_kernel_text((long)ip) &&
647649
!is_bpf_text_address((long)ip))
@@ -655,7 +657,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
655657
if (is_endbr(ip))
656658
ip += ENDBR_INSN_SIZE;
657659

658-
return __bpf_arch_text_poke(ip, t, old_addr, new_addr);
660+
return __bpf_arch_text_poke(ip, old_t, new_t, old_addr, new_addr);
659661
}
660662

661663
#define EMIT_LFENCE() EMIT3(0x0F, 0xAE, 0xE8)
@@ -897,12 +899,13 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog)
897899
target = array->ptrs[poke->tail_call.key];
898900
if (target) {
899901
ret = __bpf_arch_text_poke(poke->tailcall_target,
900-
BPF_MOD_JUMP, NULL,
902+
BPF_MOD_NOP, BPF_MOD_JUMP,
903+
NULL,
901904
(u8 *)target->bpf_func +
902905
poke->adj_off);
903906
BUG_ON(ret < 0);
904907
ret = __bpf_arch_text_poke(poke->tailcall_bypass,
905-
BPF_MOD_JUMP,
908+
BPF_MOD_JUMP, BPF_MOD_NOP,
906909
(u8 *)poke->tailcall_target +
907910
X86_PATCH_SIZE, NULL);
908911
BUG_ON(ret < 0);
@@ -2847,9 +2850,10 @@ static int get_nr_used_regs(const struct btf_func_model *m)
28472850
}
28482851

28492852
static void save_args(const struct btf_func_model *m, u8 **prog,
2850-
int stack_size, bool for_call_origin)
2853+
int stack_size, bool for_call_origin, u32 flags)
28512854
{
28522855
int arg_regs, first_off = 0, nr_regs = 0, nr_stack_slots = 0;
2856+
bool use_jmp = bpf_trampoline_use_jmp(flags);
28532857
int i, j;
28542858

28552859
/* Store function arguments to stack.
@@ -2890,7 +2894,7 @@ static void save_args(const struct btf_func_model *m, u8 **prog,
28902894
*/
28912895
for (j = 0; j < arg_regs; j++) {
28922896
emit_ldx(prog, BPF_DW, BPF_REG_0, BPF_REG_FP,
2893-
nr_stack_slots * 8 + 0x18);
2897+
nr_stack_slots * 8 + 16 + (!use_jmp) * 8);
28942898
emit_stx(prog, BPF_DW, BPF_REG_FP, BPF_REG_0,
28952899
-stack_size);
28962900

@@ -3284,12 +3288,17 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
32843288
* should be 16-byte aligned. Following code depend on
32853289
* that stack_size is already 8-byte aligned.
32863290
*/
3287-
stack_size += (stack_size % 16) ? 0 : 8;
3291+
if (bpf_trampoline_use_jmp(flags)) {
3292+
/* no rip in the "jmp" case */
3293+
stack_size += (stack_size % 16) ? 8 : 0;
3294+
} else {
3295+
stack_size += (stack_size % 16) ? 0 : 8;
3296+
}
32883297
}
32893298

32903299
arg_stack_off = stack_size;
32913300

3292-
if (flags & BPF_TRAMP_F_SKIP_FRAME) {
3301+
if (flags & BPF_TRAMP_F_CALL_ORIG) {
32933302
/* skip patched call instruction and point orig_call to actual
32943303
* body of the kernel function.
32953304
*/
@@ -3344,7 +3353,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
33443353
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off);
33453354
}
33463355

3347-
save_args(m, &prog, regs_off, false);
3356+
save_args(m, &prog, regs_off, false, flags);
33483357

33493358
if (flags & BPF_TRAMP_F_CALL_ORIG) {
33503359
/* arg1: mov rdi, im */
@@ -3377,7 +3386,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
33773386

33783387
if (flags & BPF_TRAMP_F_CALL_ORIG) {
33793388
restore_regs(m, &prog, regs_off);
3380-
save_args(m, &prog, arg_stack_off, true);
3389+
save_args(m, &prog, arg_stack_off, true, flags);
33813390

33823391
if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) {
33833392
/* Before calling the original function, load the
@@ -3979,6 +3988,7 @@ void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
39793988
struct bpf_prog *new, struct bpf_prog *old)
39803989
{
39813990
u8 *old_addr, *new_addr, *old_bypass_addr;
3991+
enum bpf_text_poke_type t;
39823992
int ret;
39833993

39843994
old_bypass_addr = old ? NULL : poke->bypass_addr;
@@ -3991,21 +4001,22 @@ void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
39914001
* the kallsyms check.
39924002
*/
39934003
if (new) {
4004+
t = old_addr ? BPF_MOD_JUMP : BPF_MOD_NOP;
39944005
ret = __bpf_arch_text_poke(poke->tailcall_target,
3995-
BPF_MOD_JUMP,
4006+
t, BPF_MOD_JUMP,
39964007
old_addr, new_addr);
39974008
BUG_ON(ret < 0);
39984009
if (!old) {
39994010
ret = __bpf_arch_text_poke(poke->tailcall_bypass,
4000-
BPF_MOD_JUMP,
4011+
BPF_MOD_JUMP, BPF_MOD_NOP,
40014012
poke->bypass_addr,
40024013
NULL);
40034014
BUG_ON(ret < 0);
40044015
}
40054016
} else {
4017+
t = old_bypass_addr ? BPF_MOD_JUMP : BPF_MOD_NOP;
40064018
ret = __bpf_arch_text_poke(poke->tailcall_bypass,
4007-
BPF_MOD_JUMP,
4008-
old_bypass_addr,
4019+
t, BPF_MOD_JUMP, old_bypass_addr,
40094020
poke->bypass_addr);
40104021
BUG_ON(ret < 0);
40114022
/* let other CPUs finish the execution of program
@@ -4014,9 +4025,9 @@ void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
40144025
*/
40154026
if (!ret)
40164027
synchronize_rcu();
4028+
t = old_addr ? BPF_MOD_JUMP : BPF_MOD_NOP;
40174029
ret = __bpf_arch_text_poke(poke->tailcall_target,
4018-
BPF_MOD_JUMP,
4019-
old_addr, NULL);
4030+
t, BPF_MOD_NOP, old_addr, NULL);
40204031
BUG_ON(ret < 0);
40214032
}
40224033
}

0 commit comments

Comments
 (0)