Skip to content

Commit e3aa56b

Browse files
AsphalttAlexei Starovoitov
authored andcommitted
bpf, arm64: Add fsession support
Implement fsession support in the arm64 BPF JIT trampoline. Extend the trampoline stack layout to store function metadata and session cookies, and pass the appropriate metadata to fentry and fexit programs. This mirrors the existing x86 behavior and enables session cookies on arm64. Acked-by: Puranjay Mohan <puranjay@kernel.org> Tested-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/r/20260131144950.16294-3-leon.hwang@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 8798902 commit e3aa56b

2 files changed

Lines changed: 68 additions & 10 deletions

File tree

arch/arm64/net/bpf_jit_comp.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,6 +2510,12 @@ static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
25102510
fentry_links->links[0]->link.type == BPF_LINK_TYPE_STRUCT_OPS;
25112511
}
25122512

2513+
static void store_func_meta(struct jit_ctx *ctx, u64 func_meta, int func_meta_off)
2514+
{
2515+
emit_a64_mov_i64(A64_R(10), func_meta, ctx);
2516+
emit(A64_STR64I(A64_R(10), A64_SP, func_meta_off), ctx);
2517+
}
2518+
25132519
/* Based on the x86's implementation of arch_prepare_bpf_trampoline().
25142520
*
25152521
* bpf prog and function entry before bpf trampoline hooked:
@@ -2533,7 +2539,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25332539
int regs_off;
25342540
int retval_off;
25352541
int bargs_off;
2536-
int nfuncargs_off;
2542+
int func_meta_off;
25372543
int ip_off;
25382544
int run_ctx_off;
25392545
int oargs_off;
@@ -2544,6 +2550,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25442550
bool save_ret;
25452551
__le32 **branches = NULL;
25462552
bool is_struct_ops = is_struct_ops_tramp(fentry);
2553+
int cookie_off, cookie_cnt, cookie_bargs_off;
2554+
int fsession_cnt = bpf_fsession_cnt(tlinks);
2555+
u64 func_meta;
25472556

25482557
/* trampoline stack layout:
25492558
* [ parent ip ]
@@ -2562,10 +2571,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25622571
* [ ... ]
25632572
* SP + bargs_off [ arg reg 1 ] for bpf
25642573
*
2565-
* SP + nfuncargs_off [ arg regs count ]
2574+
* SP + func_meta_off [ regs count, etc ]
25662575
*
25672576
* SP + ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag
25682577
*
2578+
* [ stack cookie N ]
2579+
* [ ... ]
2580+
* SP + cookie_off [ stack cookie 1 ]
2581+
*
25692582
* SP + run_ctx_off [ bpf_tramp_run_ctx ]
25702583
*
25712584
* [ stack arg N ]
@@ -2582,13 +2595,18 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25822595
/* room for bpf_tramp_run_ctx */
25832596
stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
25842597

2598+
cookie_off = stack_size;
2599+
/* room for session cookies */
2600+
cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
2601+
stack_size += cookie_cnt * 8;
2602+
25852603
ip_off = stack_size;
25862604
/* room for IP address argument */
25872605
if (flags & BPF_TRAMP_F_IP_ARG)
25882606
stack_size += 8;
25892607

2590-
nfuncargs_off = stack_size;
2591-
/* room for args count */
2608+
func_meta_off = stack_size;
2609+
/* room for function metadata, such as regs count */
25922610
stack_size += 8;
25932611

25942612
bargs_off = stack_size;
@@ -2646,9 +2664,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
26462664
emit(A64_STR64I(A64_R(10), A64_SP, ip_off), ctx);
26472665
}
26482666

2649-
/* save arg regs count*/
2650-
emit(A64_MOVZ(1, A64_R(10), nfuncargs, 0), ctx);
2651-
emit(A64_STR64I(A64_R(10), A64_SP, nfuncargs_off), ctx);
2667+
/* save function metadata */
2668+
func_meta = nfuncargs;
2669+
store_func_meta(ctx, func_meta, func_meta_off);
26522670

26532671
/* save args for bpf */
26542672
save_args(ctx, bargs_off, oargs_off, m, a, false);
@@ -2666,10 +2684,27 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
26662684
emit_call((const u64)__bpf_tramp_enter, ctx);
26672685
}
26682686

2669-
for (i = 0; i < fentry->nr_links; i++)
2687+
if (fsession_cnt) {
2688+
/* clear all the session cookies' value */
2689+
emit(A64_MOVZ(1, A64_R(10), 0, 0), ctx);
2690+
for (int i = 0; i < cookie_cnt; i++)
2691+
emit(A64_STR64I(A64_R(10), A64_SP, cookie_off + 8 * i), ctx);
2692+
/* clear the return value to make sure fentry always gets 0 */
2693+
emit(A64_STR64I(A64_R(10), A64_SP, retval_off), ctx);
2694+
}
2695+
2696+
cookie_bargs_off = (bargs_off - cookie_off) / 8;
2697+
for (i = 0; i < fentry->nr_links; i++) {
2698+
if (bpf_prog_calls_session_cookie(fentry->links[i])) {
2699+
u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
2700+
2701+
store_func_meta(ctx, meta, func_meta_off);
2702+
cookie_bargs_off--;
2703+
}
26702704
invoke_bpf_prog(ctx, fentry->links[i], bargs_off,
26712705
retval_off, run_ctx_off,
26722706
flags & BPF_TRAMP_F_RET_FENTRY_RET);
2707+
}
26732708

26742709
if (fmod_ret->nr_links) {
26752710
branches = kcalloc(fmod_ret->nr_links, sizeof(__le32 *),
@@ -2701,9 +2736,22 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
27012736
*branches[i] = cpu_to_le32(A64_CBNZ(1, A64_R(10), offset));
27022737
}
27032738

2704-
for (i = 0; i < fexit->nr_links; i++)
2739+
/* set the "is_return" flag for fsession */
2740+
func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
2741+
if (fsession_cnt)
2742+
store_func_meta(ctx, func_meta, func_meta_off);
2743+
2744+
cookie_bargs_off = (bargs_off - cookie_off) / 8;
2745+
for (i = 0; i < fexit->nr_links; i++) {
2746+
if (bpf_prog_calls_session_cookie(fexit->links[i])) {
2747+
u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
2748+
2749+
store_func_meta(ctx, meta, func_meta_off);
2750+
cookie_bargs_off--;
2751+
}
27052752
invoke_bpf_prog(ctx, fexit->links[i], bargs_off, retval_off,
27062753
run_ctx_off, false);
2754+
}
27072755

27082756
if (flags & BPF_TRAMP_F_CALL_ORIG) {
27092757
im->ip_epilogue = ctx->ro_image + ctx->idx;
@@ -2753,6 +2801,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
27532801
return ctx->idx;
27542802
}
27552803

2804+
bool bpf_jit_supports_fsession(void)
2805+
{
2806+
return true;
2807+
}
2808+
27562809
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
27572810
struct bpf_tramp_links *tlinks, void *func_addr)
27582811
{

include/linux/bpf.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2196,13 +2196,18 @@ static inline int bpf_fsession_cnt(struct bpf_tramp_links *links)
21962196
return cnt;
21972197
}
21982198

2199+
static inline bool bpf_prog_calls_session_cookie(struct bpf_tramp_link *link)
2200+
{
2201+
return link->link.prog->call_session_cookie;
2202+
}
2203+
21992204
static inline int bpf_fsession_cookie_cnt(struct bpf_tramp_links *links)
22002205
{
22012206
struct bpf_tramp_links fentries = links[BPF_TRAMP_FENTRY];
22022207
int cnt = 0;
22032208

22042209
for (int i = 0; i < links[BPF_TRAMP_FENTRY].nr_links; i++) {
2205-
if (fentries.links[i]->link.prog->call_session_cookie)
2210+
if (bpf_prog_calls_session_cookie(fentries.links[i]))
22062211
cnt++;
22072212
}
22082213

0 commit comments

Comments
 (0)