public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v10 00/12] bpf: fsession support
@ 2026-01-15 11:22 Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 01/12] bpf: add " Menglong Dong
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Hi, all.

In this version, I followed Andrii's suggestions in v9, and did many
adjustment.

overall
-------
Sometimes, we need to hook both the entry and exit of a function with
TRACING. Therefore, we need define a FENTRY and a FEXIT for the target
function, which is not convenient.

Therefore, we add a tracing session support for TRACING. Generally
speaking, it's similar to kprobe session, which can hook both the entry
and exit of a function with a single BPF program.

We allow the usage of bpf_get_func_ret() to get the return value in the
fentry of the tracing session, as it will always get "0", which is safe
enough and is OK.

Session cookie is also supported with the kfunc bpf_session_cookie().
In order to limit the stack usage, we limit the maximum number of cookies
to 4.

kfunc design
------------
In order to keep consistency with existing kfunc, we don't introduce new
kfunc for fsession. Instead, we reuse the existing kfunc
bpf_session_cookie() and bpf_session_is_return().

The prototype of bpf_session_cookie() and bpf_session_is_return() don't
satisfy our needs, so we change their prototype by adding the argument
"void *ctx" to them.

We inline bpf_session_cookie() and bpf_session_is_return() for fsession
in the verifier directly. Therefore, we don't need to introduce new
functions for them.

architecture
------------
The fsession stuff is arch related, so the -EOPNOTSUPP will be returned if
it is not supported yet by the arch. In this series, we only support
x86_64. And later, other arch will be implemented.

Changes v9 -> v10:
* 1st patch: some small adjustment, such as use switch in
  bpf_prog_has_trampoline()
* 2nd patch: some adjustment to the commit log and comment
* 3rd patch:
  - drop the declaration of bpf_session_is_return() and
    bpf_session_cookie()
  - use vmlinux.h instead of bpf_kfuncs.h in uprobe_multi_session.c,
    kprobe_multi_session_cookie.c and uprobe_multi_session_cookie.c
* 4th patch:
  - some adjustment to the comment and commit log
  - rename the prefix from BPF_TRAMP_M_ tp BPF_TRAMP_SHIFT_
  - remove the definition of BPF_TRAMP_M_NR_ARGS
  - check the program type in bpf_session_filter()
* 5th patch: some adjustment to the commit log
* 6th patch:
  - add the "reg" to the function arguments of emit_store_stack_imm64()
  - use the positive offset in emit_store_stack_imm64()
* 7th patch:
  - use "|" for func_meta instead of "+"
  - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
    computing it with "stack_size + 8"
  - pass the "cookie_off" to invoke_bpf() instead of computing the current
    cookie index with "func_meta"
* 8th patch:
  - split the modification to bpftool to a separate patch
* v9: https://lore.kernel.org/bpf/20260110141115.537055-1-dongml2@chinatelecom.cn/

Changes v8 -> v9:
* remove the definition of bpf_fsession_cookie and bpf_fsession_is_return
  in the 4th and 5th patch
* rename emit_st_r0_imm64() to emit_store_stack_imm64() in the 6th patch
* v8: https://lore.kernel.org/bpf/20260108022450.88086-1-dongml2@chinatelecom.cn/

Changes v7 -> v8:
* use the last byte of nr_args for bpf_get_func_arg_cnt() in the 2nd patch
* v7: https://lore.kernel.org/bpf/20260107064352.291069-1-dongml2@chinatelecom.cn/

Changes v6 -> v7:
* change the prototype of bpf_session_cookie() and bpf_session_is_return(),
  and reuse them instead of introduce new kfunc for fsession.
* v6: https://lore.kernel.org/bpf/20260104122814.183732-1-dongml2@chinatelecom.cn/

Changes v5 -> v6:
* No changes in this version, just a rebase to deal with conflicts.
* v5: https://lore.kernel.org/bpf/20251224130735.201422-1-dongml2@chinatelecom.cn/

Changes v4 -> v5:
* use fsession terminology consistently in all patches
* 1st patch:
  - use more explicit way in __bpf_trampoline_link_prog()
* 4th patch:
  - remove "cookie_cnt" in struct bpf_trampoline
* 6th patch:
  - rename nr_regs to func_md
  - define cookie_off in a new line
* 7th patch:
  - remove the handling of BPF_TRACE_SESSION in legacy fallback path for
    BPF_RAW_TRACEPOINT_OPEN
* v4: https://lore.kernel.org/bpf/20251217095445.218428-1-dongml2@chinatelecom.cn/

Changes v3 -> v4:
* instead of adding a new hlist to progs_hlist in trampoline, add the bpf
  program to both the fentry hlist and the fexit hlist.
* introduce the 2nd patch to reuse the nr_args field in the stack to
  store all the information we need(except the session cookies).
* limit the maximum number of cookies to 4.
* remove the logic to skip fexit if the fentry return non-zero.
* v3: https://lore.kernel.org/bpf/20251026030143.23807-1-dongml2@chinatelecom.cn/

Changes v2 -> v3:
* squeeze some patches:
  - the 2 patches for the kfunc bpf_tracing_is_exit() and
    bpf_fsession_cookie() are merged into the second patch.
  - the testcases for fsession are also squeezed.
* fix the CI error by move the testcase for bpf_get_func_ip to
  fsession_test.c
* v2: https://lore.kernel.org/bpf/20251022080159.553805-1-dongml2@chinatelecom.cn/

Changes v1 -> v2:
* session cookie support.
  In this version, session cookie is implemented, and the kfunc
  bpf_fsession_cookie() is added.
* restructure the layout of the stack.
  In this version, the session stuff that stored in the stack is changed,
  and we locate them after the return value to not break
  bpf_get_func_ip().
* testcase enhancement.
  Some nits in the testcase that suggested by Jiri is fixed. Meanwhile,
  the testcase for get_func_ip and session cookie is added too.
* v1: https://lore.kernel.org/bpf/20251018142124.783206-1-dongml2@chinatelecom.cn/

Menglong Dong (12):
  bpf: add fsession support
  bpf: use the least significant byte for the nr_args in trampoline
  bpf: change prototype of bpf_session_{cookie,is_return}
  bpf: support fsession for bpf_session_is_return
  bpf: support fsession for bpf_session_cookie
  bpf,x86: introduce emit_store_stack_imm64() for trampoline
  bpf,x86: add fsession support for x86_64
  libbpf: add fsession support
  bpftool: add fsession support
  selftests/bpf: add testcases for fsession
  selftests/bpf: add testcases for fsession cookie
  selftests/bpf: test fsession mixed with fentry and fexit

 arch/x86/net/bpf_jit_comp.c                   |  71 +++++--
 include/linux/bpf.h                           |  36 ++++
 include/uapi/linux/bpf.h                      |   1 +
 kernel/bpf/btf.c                              |   2 +
 kernel/bpf/syscall.c                          |  18 +-
 kernel/bpf/trampoline.c                       |  53 +++++-
 kernel/bpf/verifier.c                         |  86 +++++++--
 kernel/trace/bpf_trace.c                      |  49 +++--
 net/bpf/test_run.c                            |   1 +
 net/core/bpf_sk_storage.c                     |   1 +
 tools/bpf/bpftool/common.c                    |   1 +
 tools/include/uapi/linux/bpf.h                |   1 +
 tools/lib/bpf/bpf.c                           |   1 +
 tools/lib/bpf/libbpf.c                        |   3 +
 tools/testing/selftests/bpf/bpf_kfuncs.h      |   3 -
 .../selftests/bpf/prog_tests/fsession_test.c  |  90 +++++++++
 .../bpf/prog_tests/tracing_failure.c          |   2 +-
 .../selftests/bpf/progs/fsession_test.c       | 179 ++++++++++++++++++
 .../bpf/progs/kprobe_multi_session_cookie.c   |  15 +-
 .../bpf/progs/uprobe_multi_session.c          |   7 +-
 .../bpf/progs/uprobe_multi_session_cookie.c   |  15 +-
 .../progs/uprobe_multi_session_recursive.c    |  11 +-
 22 files changed, 550 insertions(+), 96 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/fsession_test.c
 create mode 100644 tools/testing/selftests/bpf/progs/fsession_test.c

-- 
2.52.0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 01/12] bpf: add fsession support
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 02/12] bpf: use the least significant byte for the nr_args in trampoline Menglong Dong
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

The fsession is something that similar to kprobe session. It allow to
attach a single BPF program to both the entry and the exit of the target
functions.

Introduce the struct bpf_fsession_link, which allows to add the link to
both the fentry and fexit progs_hlist of the trampoline.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
v10:
- use switch in bpf_prog_has_trampoline()
- some nits adjustment

v5:
- unify the name to "fsession"
- use more explicit way in __bpf_trampoline_link_prog()

v4:
- instead of adding a new hlist to progs_hlist in trampoline, add the bpf
  program to both the fentry hlist and the fexit hlist.
---
 include/linux/bpf.h                           | 19 +++++++
 include/uapi/linux/bpf.h                      |  1 +
 kernel/bpf/btf.c                              |  2 +
 kernel/bpf/syscall.c                          | 18 ++++++-
 kernel/bpf/trampoline.c                       | 53 ++++++++++++++++---
 kernel/bpf/verifier.c                         | 12 +++--
 net/bpf/test_run.c                            |  1 +
 net/core/bpf_sk_storage.c                     |  1 +
 tools/include/uapi/linux/bpf.h                |  1 +
 .../bpf/prog_tests/tracing_failure.c          |  2 +-
 10 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 5936f8e2996f..41228b0add52 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1309,6 +1309,7 @@ enum bpf_tramp_prog_type {
 	BPF_TRAMP_MODIFY_RETURN,
 	BPF_TRAMP_MAX,
 	BPF_TRAMP_REPLACE, /* more than MAX */
+	BPF_TRAMP_FSESSION,
 };
 
 struct bpf_tramp_image {
@@ -1875,6 +1876,11 @@ struct bpf_tracing_link {
 	struct bpf_prog *tgt_prog;
 };
 
+struct bpf_fsession_link {
+	struct bpf_tracing_link link;
+	struct bpf_tramp_link fexit;
+};
+
 struct bpf_raw_tp_link {
 	struct bpf_link link;
 	struct bpf_raw_event_map *btp;
@@ -2169,6 +2175,19 @@ static inline void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_op
 
 #endif
 
+static inline int bpf_fsession_cnt(struct bpf_tramp_links *links)
+{
+	struct bpf_tramp_links fentries = links[BPF_TRAMP_FENTRY];
+	int cnt = 0;
+
+	for (int i = 0; i < links[BPF_TRAMP_FENTRY].nr_links; i++) {
+		if (fentries.links[i]->link.prog->expected_attach_type == BPF_TRACE_FSESSION)
+			cnt++;
+	}
+
+	return cnt;
+}
+
 int bpf_prog_ctx_arg_info_init(struct bpf_prog *prog,
 			       const struct bpf_ctx_arg_aux *info, u32 cnt);
 
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 2a2ade4be60f..44e7dbc278e3 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1145,6 +1145,7 @@ enum bpf_attach_type {
 	BPF_NETKIT_PEER,
 	BPF_TRACE_KPROBE_SESSION,
 	BPF_TRACE_UPROBE_SESSION,
+	BPF_TRACE_FSESSION,
 	__MAX_BPF_ATTACH_TYPE
 };
 
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 364dd84bfc5a..c820ac79efe0 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6219,6 +6219,7 @@ static int btf_validate_prog_ctx_type(struct bpf_verifier_log *log, const struct
 		case BPF_TRACE_FENTRY:
 		case BPF_TRACE_FEXIT:
 		case BPF_MODIFY_RETURN:
+		case BPF_TRACE_FSESSION:
 			/* allow u64* as ctx */
 			if (btf_is_int(t) && t->size == 8)
 				return 0;
@@ -6820,6 +6821,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 			fallthrough;
 		case BPF_LSM_CGROUP:
 		case BPF_TRACE_FEXIT:
+		case BPF_TRACE_FSESSION:
 			/* When LSM programs are attached to void LSM hooks
 			 * they use FEXIT trampolines and when attached to
 			 * int LSM hooks, they use MODIFY_RETURN trampolines.
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index ecc0929ce462..c65e7a70cb78 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3577,6 +3577,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	case BPF_PROG_TYPE_TRACING:
 		if (prog->expected_attach_type != BPF_TRACE_FENTRY &&
 		    prog->expected_attach_type != BPF_TRACE_FEXIT &&
+		    prog->expected_attach_type != BPF_TRACE_FSESSION &&
 		    prog->expected_attach_type != BPF_MODIFY_RETURN) {
 			err = -EINVAL;
 			goto out_put_prog;
@@ -3626,7 +3627,21 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 		key = bpf_trampoline_compute_key(tgt_prog, NULL, btf_id);
 	}
 
-	link = kzalloc(sizeof(*link), GFP_USER);
+	if (prog->expected_attach_type == BPF_TRACE_FSESSION) {
+		struct bpf_fsession_link *fslink;
+
+		fslink = kzalloc(sizeof(*fslink), GFP_USER);
+		if (fslink) {
+			bpf_link_init(&fslink->fexit.link, BPF_LINK_TYPE_TRACING,
+				      &bpf_tracing_link_lops, prog, attach_type);
+			fslink->fexit.cookie = bpf_cookie;
+			link = &fslink->link;
+		} else {
+			link = NULL;
+		}
+	} else {
+		link = kzalloc(sizeof(*link), GFP_USER);
+	}
 	if (!link) {
 		err = -ENOMEM;
 		goto out_put_prog;
@@ -4350,6 +4365,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
 	case BPF_TRACE_RAW_TP:
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
+	case BPF_TRACE_FSESSION:
 	case BPF_MODIFY_RETURN:
 		return BPF_PROG_TYPE_TRACING;
 	case BPF_LSM_MAC:
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 2a125d063e62..edf9da43762d 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -109,10 +109,17 @@ bool bpf_prog_has_trampoline(const struct bpf_prog *prog)
 	enum bpf_attach_type eatype = prog->expected_attach_type;
 	enum bpf_prog_type ptype = prog->type;
 
-	return (ptype == BPF_PROG_TYPE_TRACING &&
-		(eatype == BPF_TRACE_FENTRY || eatype == BPF_TRACE_FEXIT ||
-		 eatype == BPF_MODIFY_RETURN)) ||
-		(ptype == BPF_PROG_TYPE_LSM && eatype == BPF_LSM_MAC);
+	switch (ptype) {
+	case BPF_PROG_TYPE_TRACING:
+		if (eatype == BPF_TRACE_FENTRY || eatype == BPF_TRACE_FEXIT ||
+		    eatype == BPF_MODIFY_RETURN || eatype == BPF_TRACE_FSESSION)
+			return true;
+		return false;
+	case BPF_PROG_TYPE_LSM:
+		return eatype == BPF_LSM_MAC;
+	default:
+		return false;
+	}
 }
 
 void bpf_image_ksym_init(void *data, unsigned int size, struct bpf_ksym *ksym)
@@ -559,6 +566,8 @@ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
 		return BPF_TRAMP_MODIFY_RETURN;
 	case BPF_TRACE_FEXIT:
 		return BPF_TRAMP_FEXIT;
+	case BPF_TRACE_FSESSION:
+		return BPF_TRAMP_FSESSION;
 	case BPF_LSM_MAC:
 		if (!prog->aux->attach_func_proto->type)
 			/* The function returns void, we cannot modify its
@@ -594,8 +603,10 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
 				      struct bpf_trampoline *tr,
 				      struct bpf_prog *tgt_prog)
 {
+	struct bpf_fsession_link *fslink = NULL;
 	enum bpf_tramp_prog_type kind;
 	struct bpf_tramp_link *link_exiting;
+	struct hlist_head *prog_list;
 	int err = 0;
 	int cnt = 0, i;
 
@@ -621,24 +632,43 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
 					  BPF_MOD_JUMP, NULL,
 					  link->link.prog->bpf_func);
 	}
+	if (kind == BPF_TRAMP_FSESSION) {
+		prog_list = &tr->progs_hlist[BPF_TRAMP_FENTRY];
+		cnt++;
+	} else {
+		prog_list = &tr->progs_hlist[kind];
+	}
 	if (cnt >= BPF_MAX_TRAMP_LINKS)
 		return -E2BIG;
 	if (!hlist_unhashed(&link->tramp_hlist))
 		/* prog already linked */
 		return -EBUSY;
-	hlist_for_each_entry(link_exiting, &tr->progs_hlist[kind], tramp_hlist) {
+	hlist_for_each_entry(link_exiting, prog_list, tramp_hlist) {
 		if (link_exiting->link.prog != link->link.prog)
 			continue;
 		/* prog already linked */
 		return -EBUSY;
 	}
 
-	hlist_add_head(&link->tramp_hlist, &tr->progs_hlist[kind]);
-	tr->progs_cnt[kind]++;
+	hlist_add_head(&link->tramp_hlist, prog_list);
+	if (kind == BPF_TRAMP_FSESSION) {
+		tr->progs_cnt[BPF_TRAMP_FENTRY]++;
+		fslink = container_of(link, struct bpf_fsession_link, link.link);
+		hlist_add_head(&fslink->fexit.tramp_hlist, &tr->progs_hlist[BPF_TRAMP_FEXIT]);
+		tr->progs_cnt[BPF_TRAMP_FEXIT]++;
+	} else {
+		tr->progs_cnt[kind]++;
+	}
 	err = bpf_trampoline_update(tr, true /* lock_direct_mutex */);
 	if (err) {
 		hlist_del_init(&link->tramp_hlist);
-		tr->progs_cnt[kind]--;
+		if (kind == BPF_TRAMP_FSESSION) {
+			tr->progs_cnt[BPF_TRAMP_FENTRY]--;
+			hlist_del_init(&fslink->fexit.tramp_hlist);
+			tr->progs_cnt[BPF_TRAMP_FEXIT]--;
+		} else {
+			tr->progs_cnt[kind]--;
+		}
 	}
 	return err;
 }
@@ -672,6 +702,13 @@ static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
 		guard(mutex)(&tgt_prog->aux->ext_mutex);
 		tgt_prog->aux->is_extended = false;
 		return err;
+	} else if (kind == BPF_TRAMP_FSESSION) {
+		struct bpf_fsession_link *fslink =
+			container_of(link, struct bpf_fsession_link, link.link);
+
+		hlist_del_init(&fslink->fexit.tramp_hlist);
+		tr->progs_cnt[BPF_TRAMP_FEXIT]--;
+		kind = BPF_TRAMP_FENTRY;
 	}
 	hlist_del_init(&link->tramp_hlist);
 	tr->progs_cnt[kind]--;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index faa1ecc1fe9d..db935eaddc2d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -17450,6 +17450,7 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
 		switch (env->prog->expected_attach_type) {
 		case BPF_TRACE_FENTRY:
 		case BPF_TRACE_FEXIT:
+		case BPF_TRACE_FSESSION:
 			range = retval_range(0, 0);
 			break;
 		case BPF_TRACE_RAW_TP:
@@ -23342,6 +23343,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 		if (prog_type == BPF_PROG_TYPE_TRACING &&
 		    insn->imm == BPF_FUNC_get_func_ret) {
 			if (eatype == BPF_TRACE_FEXIT ||
+			    eatype == BPF_TRACE_FSESSION ||
 			    eatype == BPF_MODIFY_RETURN) {
 				/* Load nr_args from ctx - 8 */
 				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
@@ -24286,7 +24288,8 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 		if (tgt_prog->type == BPF_PROG_TYPE_TRACING &&
 		    prog_extension &&
 		    (tgt_prog->expected_attach_type == BPF_TRACE_FENTRY ||
-		     tgt_prog->expected_attach_type == BPF_TRACE_FEXIT)) {
+		     tgt_prog->expected_attach_type == BPF_TRACE_FEXIT ||
+		     tgt_prog->expected_attach_type == BPF_TRACE_FSESSION)) {
 			/* Program extensions can extend all program types
 			 * except fentry/fexit. The reason is the following.
 			 * The fentry/fexit programs are used for performance
@@ -24301,7 +24304,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 			 * beyond reasonable stack size. Hence extending fentry
 			 * is not allowed.
 			 */
-			bpf_log(log, "Cannot extend fentry/fexit\n");
+			bpf_log(log, "Cannot extend fentry/fexit/fsession\n");
 			return -EINVAL;
 		}
 	} else {
@@ -24385,6 +24388,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 	case BPF_LSM_CGROUP:
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
+	case BPF_TRACE_FSESSION:
 		if (!btf_type_is_func(t)) {
 			bpf_log(log, "attach_btf_id %u is not a function\n",
 				btf_id);
@@ -24551,6 +24555,7 @@ static bool can_be_sleepable(struct bpf_prog *prog)
 		case BPF_TRACE_FEXIT:
 		case BPF_MODIFY_RETURN:
 		case BPF_TRACE_ITER:
+		case BPF_TRACE_FSESSION:
 			return true;
 		default:
 			return false;
@@ -24632,9 +24637,10 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
 			tgt_info.tgt_name);
 		return -EINVAL;
 	} else if ((prog->expected_attach_type == BPF_TRACE_FEXIT ||
+		   prog->expected_attach_type == BPF_TRACE_FSESSION ||
 		   prog->expected_attach_type == BPF_MODIFY_RETURN) &&
 		   btf_id_set_contains(&noreturn_deny, btf_id)) {
-		verbose(env, "Attaching fexit/fmod_ret to __noreturn function '%s' is rejected.\n",
+		verbose(env, "Attaching fexit/fsession/fmod_ret to __noreturn function '%s' is rejected.\n",
 			tgt_info.tgt_name);
 		return -EINVAL;
 	}
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 655efac6f133..3b0d9bd039de 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -685,6 +685,7 @@ int bpf_prog_test_run_tracing(struct bpf_prog *prog,
 	switch (prog->expected_attach_type) {
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
+	case BPF_TRACE_FSESSION:
 		if (bpf_fentry_test1(1) != 2 ||
 		    bpf_fentry_test2(2, 3) != 5 ||
 		    bpf_fentry_test3(4, 5, 6) != 15 ||
diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
index 850dd736ccd1..de111818f3a0 100644
--- a/net/core/bpf_sk_storage.c
+++ b/net/core/bpf_sk_storage.c
@@ -365,6 +365,7 @@ static bool bpf_sk_storage_tracing_allowed(const struct bpf_prog *prog)
 		return true;
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
+	case BPF_TRACE_FSESSION:
 		return !!strncmp(prog->aux->attach_func_name, "bpf_sk_storage",
 				 strlen("bpf_sk_storage"));
 	default:
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index b816bc53d2e1..3ca7d76e05f0 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1145,6 +1145,7 @@ enum bpf_attach_type {
 	BPF_NETKIT_PEER,
 	BPF_TRACE_KPROBE_SESSION,
 	BPF_TRACE_UPROBE_SESSION,
+	BPF_TRACE_FSESSION,
 	__MAX_BPF_ATTACH_TYPE
 };
 
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
index 10e231965589..f9f9e1cb87bf 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
@@ -73,7 +73,7 @@ static void test_tracing_deny(void)
 static void test_fexit_noreturns(void)
 {
 	test_tracing_fail_prog("fexit_noreturns",
-			       "Attaching fexit/fmod_ret to __noreturn function 'do_exit' is rejected.");
+			       "Attaching fexit/fsession/fmod_ret to __noreturn function 'do_exit' is rejected.");
 }
 
 void test_tracing_failure(void)
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 02/12] bpf: use the least significant byte for the nr_args in trampoline
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 01/12] bpf: add " Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 03/12] bpf: change prototype of bpf_session_{cookie,is_return} Menglong Dong
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

For now, ((u64 *)ctx)[-1] is used to store the nr_args in the trampoline.
However, 1 byte is enough to store such information. Therefore, we use
only the least significant byte of ((u64 *)ctx)[-1] to store the nr_args,
and reserve the rest for other usages.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v10:
- some adjustment to the subject and commit log to make the description
  more precise.

v8:
- fix the missed get_func_arg_cnt
---
 kernel/bpf/verifier.c    | 35 +++++++++++++++++++----------------
 kernel/trace/bpf_trace.c |  6 +++---
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index db935eaddc2d..f7eec19df803 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -23319,15 +23319,16 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 		    insn->imm == BPF_FUNC_get_func_arg) {
 			/* Load nr_args from ctx - 8 */
 			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
-			insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
-			insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
-			insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
-			insn_buf[4] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0);
-			insn_buf[5] = BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0);
-			insn_buf[6] = BPF_MOV64_IMM(BPF_REG_0, 0);
-			insn_buf[7] = BPF_JMP_A(1);
-			insn_buf[8] = BPF_MOV64_IMM(BPF_REG_0, -EINVAL);
-			cnt = 9;
+			insn_buf[1] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xFF);
+			insn_buf[2] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
+			insn_buf[3] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
+			insn_buf[4] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
+			insn_buf[5] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0);
+			insn_buf[6] = BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0);
+			insn_buf[7] = BPF_MOV64_IMM(BPF_REG_0, 0);
+			insn_buf[8] = BPF_JMP_A(1);
+			insn_buf[9] = BPF_MOV64_IMM(BPF_REG_0, -EINVAL);
+			cnt = 10;
 
 			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
 			if (!new_prog)
@@ -23347,12 +23348,13 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 			    eatype == BPF_MODIFY_RETURN) {
 				/* Load nr_args from ctx - 8 */
 				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
-				insn_buf[1] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3);
-				insn_buf[2] = BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1);
-				insn_buf[3] = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0);
-				insn_buf[4] = BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0);
-				insn_buf[5] = BPF_MOV64_IMM(BPF_REG_0, 0);
-				cnt = 6;
+				insn_buf[1] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xFF);
+				insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3);
+				insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1);
+				insn_buf[4] = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0);
+				insn_buf[5] = BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0);
+				insn_buf[6] = BPF_MOV64_IMM(BPF_REG_0, 0);
+				cnt = 7;
 			} else {
 				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, -EOPNOTSUPP);
 				cnt = 1;
@@ -23373,8 +23375,9 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 		    insn->imm == BPF_FUNC_get_func_arg_cnt) {
 			/* Load nr_args from ctx - 8 */
 			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+			insn_buf[1] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xFF);
 
-			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
+			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 2);
 			if (!new_prog)
 				return -ENOMEM;
 
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 6e076485bf70..5f621f0403f8 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1194,7 +1194,7 @@ const struct bpf_func_proto bpf_get_branch_snapshot_proto = {
 BPF_CALL_3(get_func_arg, void *, ctx, u32, n, u64 *, value)
 {
 	/* This helper call is inlined by verifier. */
-	u64 nr_args = ((u64 *)ctx)[-1];
+	u64 nr_args = ((u64 *)ctx)[-1] & 0xFF;
 
 	if ((u64) n >= nr_args)
 		return -EINVAL;
@@ -1214,7 +1214,7 @@ static const struct bpf_func_proto bpf_get_func_arg_proto = {
 BPF_CALL_2(get_func_ret, void *, ctx, u64 *, value)
 {
 	/* This helper call is inlined by verifier. */
-	u64 nr_args = ((u64 *)ctx)[-1];
+	u64 nr_args = ((u64 *)ctx)[-1] & 0xFF;
 
 	*value = ((u64 *)ctx)[nr_args];
 	return 0;
@@ -1231,7 +1231,7 @@ static const struct bpf_func_proto bpf_get_func_ret_proto = {
 BPF_CALL_1(get_func_arg_cnt, void *, ctx)
 {
 	/* This helper call is inlined by verifier. */
-	return ((u64 *)ctx)[-1];
+	return ((u64 *)ctx)[-1] & 0xFF;
 }
 
 static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 03/12] bpf: change prototype of bpf_session_{cookie,is_return}
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 01/12] bpf: add " Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 02/12] bpf: use the least significant byte for the nr_args in trampoline Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 04/12] bpf: support fsession for bpf_session_is_return Menglong Dong
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Add the function argument of "void *ctx" to bpf_session_cookie() and
bpf_session_is_return(), which is a preparation of the next patch.

The two kfunc is seldom used now, so it will not introduce much effect
to change their function prototype.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
---
v10:
- drop the declaration of bpf_session_is_return() and bpf_session_cookie()
---
 kernel/bpf/verifier.c                             |  6 +++++-
 kernel/trace/bpf_trace.c                          |  4 ++--
 tools/testing/selftests/bpf/bpf_kfuncs.h          |  3 ---
 .../bpf/progs/kprobe_multi_session_cookie.c       | 15 +++++++--------
 .../selftests/bpf/progs/uprobe_multi_session.c    |  7 +++----
 .../bpf/progs/uprobe_multi_session_cookie.c       | 15 +++++++--------
 .../bpf/progs/uprobe_multi_session_recursive.c    | 11 +++++------
 7 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index f7eec19df803..1ed41ba8b54c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12370,6 +12370,7 @@ enum special_kfunc_type {
 	KF_bpf_arena_alloc_pages,
 	KF_bpf_arena_free_pages,
 	KF_bpf_arena_reserve_pages,
+	KF_bpf_session_is_return,
 };
 
 BTF_ID_LIST(special_kfunc_list)
@@ -12447,6 +12448,7 @@ BTF_ID(func, bpf_task_work_schedule_resume_impl)
 BTF_ID(func, bpf_arena_alloc_pages)
 BTF_ID(func, bpf_arena_free_pages)
 BTF_ID(func, bpf_arena_reserve_pages)
+BTF_ID(func, bpf_session_is_return)
 
 static bool is_task_work_add_kfunc(u32 func_id)
 {
@@ -12501,7 +12503,9 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env,
 	struct bpf_reg_state *reg = &regs[regno];
 	bool arg_mem_size = false;
 
-	if (meta->func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx])
+	if (meta->func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx] ||
+	    meta->func_id == special_kfunc_list[KF_bpf_session_is_return] ||
+	    meta->func_id == special_kfunc_list[KF_bpf_session_cookie])
 		return KF_ARG_PTR_TO_CTX;
 
 	if (argno + 1 < nargs &&
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 5f621f0403f8..297dcafb2c55 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -3316,7 +3316,7 @@ static u64 bpf_uprobe_multi_entry_ip(struct bpf_run_ctx *ctx)
 
 __bpf_kfunc_start_defs();
 
-__bpf_kfunc bool bpf_session_is_return(void)
+__bpf_kfunc bool bpf_session_is_return(void *ctx)
 {
 	struct bpf_session_run_ctx *session_ctx;
 
@@ -3324,7 +3324,7 @@ __bpf_kfunc bool bpf_session_is_return(void)
 	return session_ctx->is_return;
 }
 
-__bpf_kfunc __u64 *bpf_session_cookie(void)
+__bpf_kfunc __u64 *bpf_session_cookie(void *ctx)
 {
 	struct bpf_session_run_ctx *session_ctx;
 
diff --git a/tools/testing/selftests/bpf/bpf_kfuncs.h b/tools/testing/selftests/bpf/bpf_kfuncs.h
index e0189254bb6e..7dad01439391 100644
--- a/tools/testing/selftests/bpf/bpf_kfuncs.h
+++ b/tools/testing/selftests/bpf/bpf_kfuncs.h
@@ -79,9 +79,6 @@ extern int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_ptr,
 				      struct bpf_dynptr *sig_ptr,
 				      struct bpf_key *trusted_keyring) __ksym;
 
-extern bool bpf_session_is_return(void) __ksym __weak;
-extern __u64 *bpf_session_cookie(void) __ksym __weak;
-
 struct dentry;
 /* Description
  *  Returns xattr of a dentry
diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi_session_cookie.c b/tools/testing/selftests/bpf/progs/kprobe_multi_session_cookie.c
index 0835b5edf685..ad627016e3e5 100644
--- a/tools/testing/selftests/bpf/progs/kprobe_multi_session_cookie.c
+++ b/tools/testing/selftests/bpf/progs/kprobe_multi_session_cookie.c
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bpf.h>
+#include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include <stdbool.h>
-#include "bpf_kfuncs.h"
 
 char _license[] SEC("license") = "GPL";
 
@@ -23,16 +22,16 @@ int BPF_PROG(trigger)
 	return 0;
 }
 
-static int check_cookie(__u64 val, __u64 *result)
+static int check_cookie(struct pt_regs *ctx, __u64 val, __u64 *result)
 {
 	__u64 *cookie;
 
 	if (bpf_get_current_pid_tgid() >> 32 != pid)
 		return 1;
 
-	cookie = bpf_session_cookie();
+	cookie = bpf_session_cookie(ctx);
 
-	if (bpf_session_is_return())
+	if (bpf_session_is_return(ctx))
 		*result = *cookie == val ? val : 0;
 	else
 		*cookie = val;
@@ -42,17 +41,17 @@ static int check_cookie(__u64 val, __u64 *result)
 SEC("kprobe.session/bpf_fentry_test1")
 int test_kprobe_1(struct pt_regs *ctx)
 {
-	return check_cookie(1, &test_kprobe_1_result);
+	return check_cookie(ctx, 1, &test_kprobe_1_result);
 }
 
 SEC("kprobe.session/bpf_fentry_test1")
 int test_kprobe_2(struct pt_regs *ctx)
 {
-	return check_cookie(2, &test_kprobe_2_result);
+	return check_cookie(ctx, 2, &test_kprobe_2_result);
 }
 
 SEC("kprobe.session/bpf_fentry_test1")
 int test_kprobe_3(struct pt_regs *ctx)
 {
-	return check_cookie(3, &test_kprobe_3_result);
+	return check_cookie(ctx, 3, &test_kprobe_3_result);
 }
diff --git a/tools/testing/selftests/bpf/progs/uprobe_multi_session.c b/tools/testing/selftests/bpf/progs/uprobe_multi_session.c
index 30bff90b68dc..6e46bb00ff58 100644
--- a/tools/testing/selftests/bpf/progs/uprobe_multi_session.c
+++ b/tools/testing/selftests/bpf/progs/uprobe_multi_session.c
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bpf.h>
+#include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include <stdbool.h>
-#include "bpf_kfuncs.h"
 #include "bpf_misc.h"
 
 char _license[] SEC("license") = "GPL";
@@ -51,7 +50,7 @@ static int uprobe_multi_check(void *ctx, bool is_return)
 SEC("uprobe.session//proc/self/exe:uprobe_multi_func_*")
 int uprobe(struct pt_regs *ctx)
 {
-	return uprobe_multi_check(ctx, bpf_session_is_return());
+	return uprobe_multi_check(ctx, bpf_session_is_return(ctx));
 }
 
 static __always_inline bool verify_sleepable_user_copy(void)
@@ -67,5 +66,5 @@ int uprobe_sleepable(struct pt_regs *ctx)
 {
 	if (verify_sleepable_user_copy())
 		uprobe_multi_sleep_result++;
-	return uprobe_multi_check(ctx, bpf_session_is_return());
+	return uprobe_multi_check(ctx, bpf_session_is_return(ctx));
 }
diff --git a/tools/testing/selftests/bpf/progs/uprobe_multi_session_cookie.c b/tools/testing/selftests/bpf/progs/uprobe_multi_session_cookie.c
index 5befdf944dc6..b5db196614a9 100644
--- a/tools/testing/selftests/bpf/progs/uprobe_multi_session_cookie.c
+++ b/tools/testing/selftests/bpf/progs/uprobe_multi_session_cookie.c
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bpf.h>
+#include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include <stdbool.h>
-#include "bpf_kfuncs.h"
 
 char _license[] SEC("license") = "GPL";
 
@@ -13,16 +12,16 @@ __u64 test_uprobe_1_result = 0;
 __u64 test_uprobe_2_result = 0;
 __u64 test_uprobe_3_result = 0;
 
-static int check_cookie(__u64 val, __u64 *result)
+static int check_cookie(struct pt_regs *ctx, __u64 val, __u64 *result)
 {
 	__u64 *cookie;
 
 	if (bpf_get_current_pid_tgid() >> 32 != pid)
 		return 1;
 
-	cookie = bpf_session_cookie();
+	cookie = bpf_session_cookie(ctx);
 
-	if (bpf_session_is_return())
+	if (bpf_session_is_return(ctx))
 		*result = *cookie == val ? val : 0;
 	else
 		*cookie = val;
@@ -32,17 +31,17 @@ static int check_cookie(__u64 val, __u64 *result)
 SEC("uprobe.session//proc/self/exe:uprobe_multi_func_1")
 int uprobe_1(struct pt_regs *ctx)
 {
-	return check_cookie(1, &test_uprobe_1_result);
+	return check_cookie(ctx, 1, &test_uprobe_1_result);
 }
 
 SEC("uprobe.session//proc/self/exe:uprobe_multi_func_2")
 int uprobe_2(struct pt_regs *ctx)
 {
-	return check_cookie(2, &test_uprobe_2_result);
+	return check_cookie(ctx, 2, &test_uprobe_2_result);
 }
 
 SEC("uprobe.session//proc/self/exe:uprobe_multi_func_3")
 int uprobe_3(struct pt_regs *ctx)
 {
-	return check_cookie(3, &test_uprobe_3_result);
+	return check_cookie(ctx, 3, &test_uprobe_3_result);
 }
diff --git a/tools/testing/selftests/bpf/progs/uprobe_multi_session_recursive.c b/tools/testing/selftests/bpf/progs/uprobe_multi_session_recursive.c
index 8fbcd69fae22..3ce309248a04 100644
--- a/tools/testing/selftests/bpf/progs/uprobe_multi_session_recursive.c
+++ b/tools/testing/selftests/bpf/progs/uprobe_multi_session_recursive.c
@@ -1,9 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-#include <linux/bpf.h>
+#include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include <stdbool.h>
-#include "bpf_kfuncs.h"
 #include "bpf_misc.h"
 
 char _license[] SEC("license") = "GPL";
@@ -16,11 +15,11 @@ int idx_return = 0;
 __u64 test_uprobe_cookie_entry[6];
 __u64 test_uprobe_cookie_return[3];
 
-static int check_cookie(void)
+static int check_cookie(struct pt_regs *ctx)
 {
-	__u64 *cookie = bpf_session_cookie();
+	__u64 *cookie = bpf_session_cookie(ctx);
 
-	if (bpf_session_is_return()) {
+	if (bpf_session_is_return(ctx)) {
 		if (idx_return >= ARRAY_SIZE(test_uprobe_cookie_return))
 			return 1;
 		test_uprobe_cookie_return[idx_return++] = *cookie;
@@ -40,5 +39,5 @@ int uprobe_recursive(struct pt_regs *ctx)
 	if (bpf_get_current_pid_tgid() >> 32 != pid)
 		return 1;
 
-	return check_cookie();
+	return check_cookie(ctx);
 }
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 04/12] bpf: support fsession for bpf_session_is_return
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (2 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 03/12] bpf: change prototype of bpf_session_{cookie,is_return} Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 05/12] bpf: support fsession for bpf_session_cookie Menglong Dong
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

If fsession exists, we will use the bit (1 << BPF_TRAMP_SHIFT_IS_RETURN)
in ((u64 *)ctx)[-1] to store the "is_return" flag.

The logic of bpf_session_is_return() for fsession is implemented in the
verifier by inline following code:

  bool bpf_session_is_return(void *ctx)
  {
      return (((u64 *)ctx)[-1] >> BPF_TRAMP_SHIFT_IS_RETURN) & 1;
  }

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
v10:
- fix the wrong description of bpf_session_is_return() in commit log and
  comment
- rename the prefix from BPF_TRAMP_M_ tp BPF_TRAMP_SHIFT_
- remove the definition of BPF_TRAMP_M_NR_ARGS
- use 63 for the shift of BPF_TRAMP_SHIFT_IS_RETURN
- check the program type in bpf_session_filter()

v9:
- remove the definition of bpf_fsession_is_return()

v7:
- reuse the kfunc bpf_session_is_return() instead of introduce new kfunc

v4:
- split out the bpf_fsession_cookie() to another patch

v3:
- merge the bpf_tracing_is_exit and bpf_fsession_cookie into a single
  patch

v2:
- store the session flags after return value, instead of before nr_args
- inline the bpf_tracing_is_exit, as Jiri suggested
---
 include/linux/bpf.h      |  2 ++
 kernel/bpf/verifier.c    | 13 +++++++++++++
 kernel/trace/bpf_trace.c | 39 ++++++++++++++++++++++++++-------------
 3 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 41228b0add52..4f72d553f52b 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1229,6 +1229,8 @@ enum {
 #endif
 };
 
+#define BPF_TRAMP_SHIFT_IS_RETURN	63
+
 struct bpf_tramp_links {
 	struct bpf_tramp_link *links[BPF_MAX_TRAMP_LINKS];
 	int nr_links;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1ed41ba8b54c..2efe458f9bad 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -22604,6 +22604,19 @@ static int fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
 		   desc->func_id == special_kfunc_list[KF_bpf_rdonly_cast]) {
 		insn_buf[0] = BPF_MOV64_REG(BPF_REG_0, BPF_REG_1);
 		*cnt = 1;
+	} else if (desc->func_id == special_kfunc_list[KF_bpf_session_is_return] &&
+		   env->prog->expected_attach_type == BPF_TRACE_FSESSION) {
+		/*
+		 * inline the bpf_session_is_return() for fsession:
+		 *   bool bpf_session_is_return(void *ctx)
+		 *   {
+		 *       return (((u64 *)ctx)[-1] >> BPF_TRAMP_SHIFT_IS_RETURN) & 1;
+		 *   }
+		 */
+		insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+		insn_buf[1] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, BPF_TRAMP_SHIFT_IS_RETURN);
+		insn_buf[2] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1);
+		*cnt = 3;
 	}
 
 	if (env->insn_aux_data[insn_idx].arg_prog) {
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 297dcafb2c55..3f5460a6da47 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1286,7 +1286,8 @@ static bool is_kprobe_multi(const struct bpf_prog *prog)
 
 static inline bool is_kprobe_session(const struct bpf_prog *prog)
 {
-	return prog->expected_attach_type == BPF_TRACE_KPROBE_SESSION;
+	return prog->type == BPF_PROG_TYPE_KPROBE &&
+	       prog->expected_attach_type == BPF_TRACE_KPROBE_SESSION;
 }
 
 static inline bool is_uprobe_multi(const struct bpf_prog *prog)
@@ -1297,7 +1298,14 @@ static inline bool is_uprobe_multi(const struct bpf_prog *prog)
 
 static inline bool is_uprobe_session(const struct bpf_prog *prog)
 {
-	return prog->expected_attach_type == BPF_TRACE_UPROBE_SESSION;
+	return prog->type == BPF_PROG_TYPE_KPROBE &&
+	       prog->expected_attach_type == BPF_TRACE_UPROBE_SESSION;
+}
+
+static inline bool is_trace_fsession(const struct bpf_prog *prog)
+{
+	return prog->type == BPF_PROG_TYPE_TRACING &&
+	       prog->expected_attach_type == BPF_TRACE_FSESSION;
 }
 
 static const struct bpf_func_proto *
@@ -3334,34 +3342,39 @@ __bpf_kfunc __u64 *bpf_session_cookie(void *ctx)
 
 __bpf_kfunc_end_defs();
 
-BTF_KFUNCS_START(kprobe_multi_kfunc_set_ids)
+BTF_KFUNCS_START(session_kfunc_set_ids)
 BTF_ID_FLAGS(func, bpf_session_is_return)
 BTF_ID_FLAGS(func, bpf_session_cookie)
-BTF_KFUNCS_END(kprobe_multi_kfunc_set_ids)
+BTF_KFUNCS_END(session_kfunc_set_ids)
 
-static int bpf_kprobe_multi_filter(const struct bpf_prog *prog, u32 kfunc_id)
+static int bpf_session_filter(const struct bpf_prog *prog, u32 kfunc_id)
 {
-	if (!btf_id_set8_contains(&kprobe_multi_kfunc_set_ids, kfunc_id))
+	if (!btf_id_set8_contains(&session_kfunc_set_ids, kfunc_id))
 		return 0;
 
-	if (!is_kprobe_session(prog) && !is_uprobe_session(prog))
+	if (!is_kprobe_session(prog) && !is_uprobe_session(prog) && !is_trace_fsession(prog))
 		return -EACCES;
 
 	return 0;
 }
 
-static const struct btf_kfunc_id_set bpf_kprobe_multi_kfunc_set = {
+static const struct btf_kfunc_id_set bpf_session_kfunc_set = {
 	.owner = THIS_MODULE,
-	.set = &kprobe_multi_kfunc_set_ids,
-	.filter = bpf_kprobe_multi_filter,
+	.set = &session_kfunc_set_ids,
+	.filter = bpf_session_filter,
 };
 
-static int __init bpf_kprobe_multi_kfuncs_init(void)
+static int __init bpf_trace_kfuncs_init(void)
 {
-	return register_btf_kfunc_id_set(BPF_PROG_TYPE_KPROBE, &bpf_kprobe_multi_kfunc_set);
+	int err = 0;
+
+	err = err ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_KPROBE, &bpf_session_kfunc_set);
+	err = err ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_session_kfunc_set);
+
+	return err;
 }
 
-late_initcall(bpf_kprobe_multi_kfuncs_init);
+late_initcall(bpf_trace_kfuncs_init);
 
 typedef int (*copy_fn_t)(void *dst, const void *src, u32 size, struct task_struct *tsk);
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 05/12] bpf: support fsession for bpf_session_cookie
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (3 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 04/12] bpf: support fsession for bpf_session_is_return Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 06/12] bpf,x86: introduce emit_store_stack_imm64() for trampoline Menglong Dong
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Implement session cookie for fsession. The session cookies will be stored
in the stack, and the layout of the stack will look like this:
  return value	-> 8 bytes
  argN		-> 8 bytes
  ...
  arg1		-> 8 bytes
  nr_args	-> 8 bytes
  ip (optional)	-> 8 bytes
  cookie2	-> 8 bytes
  cookie1	-> 8 bytes

The offset of the cookie for the current bpf program, which is in 8-byte
units, is stored in the "(((u64 *)ctx)[-1] >> BPF_TRAMP_M_COOKIE) & 0xFF".
Therefore, we can get the session cookie with ((u64 *)ctx)[-offset].

Implement and inline the bpf_session_cookie() for the fsession in the
verifier.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v10:
- describe the offset of the session cookie more explicit
- make 8 as the bit shift of session cookie
- remove the session cookie count limitation

v9:
- remove the definition of bpf_fsession_cookie()

v7:
- reuse bpf_session_cookie() instead of introduce new kfunc

v5:
- remove "cookie_cnt" in struct bpf_trampoline

v4:
- limit the maximum of the cookie count to 4
- store the session cookies before nr_regs in stack
---
 include/linux/bpf.h   | 15 +++++++++++++++
 kernel/bpf/verifier.c | 20 ++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 4f72d553f52b..551d2cb0ec7d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1229,6 +1229,7 @@ enum {
 #endif
 };
 
+#define BPF_TRAMP_SHIFT_COOKIE		8
 #define BPF_TRAMP_SHIFT_IS_RETURN	63
 
 struct bpf_tramp_links {
@@ -1782,6 +1783,7 @@ struct bpf_prog {
 				enforce_expected_attach_type:1, /* Enforce expected_attach_type checking at attach time */
 				call_get_stack:1, /* Do we call bpf_get_stack() or bpf_get_stackid() */
 				call_get_func_ip:1, /* Do we call get_func_ip() */
+				call_session_cookie:1, /* Do we call bpf_session_cookie() */
 				tstamp_type_access:1, /* Accessed __sk_buff->tstamp_type */
 				sleepable:1;	/* BPF program is sleepable */
 	enum bpf_prog_type	type;		/* Type of BPF program */
@@ -2190,6 +2192,19 @@ static inline int bpf_fsession_cnt(struct bpf_tramp_links *links)
 	return cnt;
 }
 
+static inline int bpf_fsession_cookie_cnt(struct bpf_tramp_links *links)
+{
+	struct bpf_tramp_links fentries = links[BPF_TRAMP_FENTRY];
+	int cnt = 0;
+
+	for (int i = 0; i < links[BPF_TRAMP_FENTRY].nr_links; i++) {
+		if (fentries.links[i]->link.prog->call_session_cookie)
+			cnt++;
+	}
+
+	return cnt;
+}
+
 int bpf_prog_ctx_arg_info_init(struct bpf_prog *prog,
 			       const struct bpf_ctx_arg_aux *info, u32 cnt);
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2efe458f9bad..3ab2da5f8165 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14303,6 +14303,9 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
 			return err;
 	}
 
+	if (meta.func_id == special_kfunc_list[KF_bpf_session_cookie])
+		env->prog->call_session_cookie = true;
+
 	return 0;
 }
 
@@ -22617,6 +22620,23 @@ static int fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
 		insn_buf[1] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, BPF_TRAMP_SHIFT_IS_RETURN);
 		insn_buf[2] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1);
 		*cnt = 3;
+	} else if (desc->func_id == special_kfunc_list[KF_bpf_session_cookie] &&
+		   env->prog->expected_attach_type == BPF_TRACE_FSESSION) {
+		/*
+		 * inline bpf_session_cookie() for fsession:
+		 *   __u64 *bpf_session_cookie(void *ctx)
+		 *   {
+		 *       u64 off = (((u64 *)ctx)[-1] >> BPF_TRAMP_SHIFT_COOKIE) & 0xFF;
+		 *       return &((u64 *)ctx)[-off];
+		 *   }
+		 */
+		insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+		insn_buf[1] = BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, BPF_TRAMP_SHIFT_COOKIE);
+		insn_buf[2] = BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xFF);
+		insn_buf[3] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3);
+		insn_buf[4] = BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1);
+		insn_buf[5] = BPF_ALU64_IMM(BPF_NEG, BPF_REG_0, 0);
+		*cnt = 6;
 	}
 
 	if (env->insn_aux_data[insn_idx].arg_prog) {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 06/12] bpf,x86: introduce emit_store_stack_imm64() for trampoline
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (4 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 05/12] bpf: support fsession for bpf_session_cookie Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64 Menglong Dong
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Introduce the helper emit_store_stack_imm64(), which is used to store a
imm64 to the stack with the help of a register.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v10:
- add the "reg" to the function arguments of emit_store_stack_imm64()
- use the positive offset in emit_store_stack_imm64()
- remove some unnecessary comment, as we already have proper comment in
  emit_store_stack_imm64()

v9:
- rename emit_st_r0_imm64() to emit_store_stack_imm64()
---
 arch/x86/net/bpf_jit_comp.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index e3b1c4b1d550..2f31331955b5 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -1300,6 +1300,16 @@ static void emit_st_r12(u8 **pprog, u32 size, u32 dst_reg, int off, int imm)
 	emit_st_index(pprog, size, dst_reg, X86_REG_R12, off, imm);
 }
 
+static void emit_store_stack_imm64(u8 **pprog, int reg, int stack_off, u64 imm64)
+{
+	/*
+	 * mov reg, imm64
+	 * mov QWORD PTR [rbp + stack_off], reg
+	 */
+	emit_mov_imm64(pprog, reg, imm64 >> 32, (u32) imm64);
+	emit_stx(pprog, BPF_DW, BPF_REG_FP, reg, stack_off);
+}
+
 static int emit_atomic_rmw(u8 **pprog, u32 atomic_op,
 			   u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size)
 {
@@ -3348,20 +3358,12 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 	/* mov QWORD PTR [rbp - rbx_off], rbx */
 	emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_6, -rbx_off);
 
-	/* Store number of argument registers of the traced function:
-	 *   mov rax, nr_regs
-	 *   mov QWORD PTR [rbp - nregs_off], rax
-	 */
-	emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_regs);
-	emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -nregs_off);
+	/* Store number of argument registers of the traced function */
+	emit_store_stack_imm64(&prog, BPF_REG_0, -nregs_off, nr_regs);
 
 	if (flags & BPF_TRAMP_F_IP_ARG) {
-		/* Store IP address of the traced function:
-		 * movabsq rax, func_addr
-		 * mov QWORD PTR [rbp - ip_off], rax
-		 */
-		emit_mov_imm64(&prog, BPF_REG_0, (long) func_addr >> 32, (u32) (long) func_addr);
-		emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off);
+		/* Store IP address of the traced function */
+		emit_store_stack_imm64(&prog, BPF_REG_0, -ip_off, (long)func_addr);
 	}
 
 	save_args(m, &prog, regs_off, false, flags);
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (5 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 06/12] bpf,x86: introduce emit_store_stack_imm64() for trampoline Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-22  0:06   ` Andrii Nakryiko
  2026-01-15 11:22 ` [PATCH bpf-next v10 08/12] libbpf: add fsession support Menglong Dong
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Add BPF_TRACE_FSESSION supporting to x86_64, including:

1. clear the return value in the stack before fentry to make the fentry
   of the fsession can only get 0 with bpf_get_func_ret().

2. clear all the session cookies' value in the stack.

2. store the index of the cookie to ctx[-1] before the calling to fsession

3. store the "is_return" flag to ctx[-1] before the calling to fexit of
   the fsession.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
v10:
- use "|" for func_meta instead of "+"
- pass the "func_meta_off" to invoke_bpf() explicitly, instead of
  computing it with "stack_size + 8"
- pass the "cookie_off" to invoke_bpf() instead of computing the current
  cookie index with "func_meta"

v5:
- add the variable "func_meta"
- define cookie_off in a new line

v4:
- some adjustment to the 1st patch, such as we get the fsession prog from
  fentry and fexit hlist
- remove the supporting of skipping fexit with fentry return non-zero

v2:
- add session cookie support
- add the session stuff after return value, instead of before nr_args
---
 arch/x86/net/bpf_jit_comp.c | 52 ++++++++++++++++++++++++++++---------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 2f31331955b5..16720f2be16c 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -3094,13 +3094,19 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
 
 static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
 		      struct bpf_tramp_links *tl, int stack_size,
-		      int run_ctx_off, bool save_ret,
-		      void *image, void *rw_image)
+		      int run_ctx_off, int func_meta_off, bool save_ret,
+		      void *image, void *rw_image, u64 func_meta,
+		      int cookie_off)
 {
-	int i;
+	int i, cur_cookie = (cookie_off - stack_size) / 8;
 	u8 *prog = *pprog;
 
 	for (i = 0; i < tl->nr_links; i++) {
+		if (tl->links[i]->link.prog->call_session_cookie) {
+			emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off,
+					       func_meta | (cur_cookie << BPF_TRAMP_SHIFT_COOKIE));
+			cur_cookie--;
+		}
 		if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
 				    run_ctx_off, save_ret, image, rw_image))
 			return -EINVAL;
@@ -3218,12 +3224,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 					 void *func_addr)
 {
 	int i, ret, nr_regs = m->nr_args, stack_size = 0;
-	int regs_off, nregs_off, ip_off, run_ctx_off, arg_stack_off, rbx_off;
+	int regs_off, func_meta_off, ip_off, run_ctx_off, arg_stack_off, rbx_off;
 	struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
 	struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
 	struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
 	void *orig_call = func_addr;
+	int cookie_off, cookie_cnt;
 	u8 **branches = NULL;
+	u64 func_meta;
 	u8 *prog;
 	bool save_ret;
 
@@ -3259,7 +3267,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 	 *                 [ ...             ]
 	 * RBP - regs_off  [ reg_arg1        ]  program's ctx pointer
 	 *
-	 * RBP - nregs_off [ regs count	     ]  always
+	 * RBP - func_meta_off [ regs count, etc ]  always
 	 *
 	 * RBP - ip_off    [ traced function ]  BPF_TRAMP_F_IP_ARG flag
 	 *
@@ -3282,15 +3290,20 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 	stack_size += nr_regs * 8;
 	regs_off = stack_size;
 
-	/* regs count  */
+	/* function matedata, such as regs count  */
 	stack_size += 8;
-	nregs_off = stack_size;
+	func_meta_off = stack_size;
 
 	if (flags & BPF_TRAMP_F_IP_ARG)
 		stack_size += 8; /* room for IP address argument */
 
 	ip_off = stack_size;
 
+	cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
+	/* room for session cookies */
+	stack_size += cookie_cnt * 8;
+	cookie_off = stack_size;
+
 	stack_size += 8;
 	rbx_off = stack_size;
 
@@ -3358,8 +3371,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 	/* mov QWORD PTR [rbp - rbx_off], rbx */
 	emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_6, -rbx_off);
 
+	func_meta = nr_regs;
 	/* Store number of argument registers of the traced function */
-	emit_store_stack_imm64(&prog, BPF_REG_0, -nregs_off, nr_regs);
+	emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off, func_meta);
 
 	if (flags & BPF_TRAMP_F_IP_ARG) {
 		/* Store IP address of the traced function */
@@ -3378,9 +3392,18 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 		}
 	}
 
+	if (bpf_fsession_cnt(tlinks)) {
+		/* clear all the session cookies' value */
+		for (int i = 0; i < cookie_cnt; i++)
+			emit_store_stack_imm64(&prog, BPF_REG_0, -cookie_off + 8 * i, 0);
+		/* clear the return value to make sure fentry always get 0 */
+		emit_store_stack_imm64(&prog, BPF_REG_0, -8, 0);
+	}
+
 	if (fentry->nr_links) {
-		if (invoke_bpf(m, &prog, fentry, regs_off, run_ctx_off,
-			       flags & BPF_TRAMP_F_RET_FENTRY_RET, image, rw_image))
+		if (invoke_bpf(m, &prog, fentry, regs_off, run_ctx_off, func_meta_off,
+			       flags & BPF_TRAMP_F_RET_FENTRY_RET, image, rw_image,
+			       func_meta, cookie_off))
 			return -EINVAL;
 	}
 
@@ -3440,9 +3463,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 		}
 	}
 
+	/* set the "is_return" flag for fsession */
+	func_meta |= (1ULL << BPF_TRAMP_SHIFT_IS_RETURN);
+	if (bpf_fsession_cnt(tlinks))
+		emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off, func_meta);
+
 	if (fexit->nr_links) {
-		if (invoke_bpf(m, &prog, fexit, regs_off, run_ctx_off,
-			       false, image, rw_image)) {
+		if (invoke_bpf(m, &prog, fexit, regs_off, run_ctx_off, func_meta_off,
+			       false, image, rw_image, func_meta, cookie_off)) {
 			ret = -EINVAL;
 			goto cleanup;
 		}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 08/12] libbpf: add fsession support
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (6 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64 Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 09/12] bpftool: " Menglong Dong
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Add BPF_TRACE_FSESSION to libbpf.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v10:
- split the modification to bpftool to a separate patch

v5:
- remove the handling of BPF_TRACE_SESSION in legacy fallback path for
  BPF_RAW_TRACEPOINT_OPEN
- use fsession terminology consistently
---
 tools/lib/bpf/bpf.c    | 1 +
 tools/lib/bpf/libbpf.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 21b57a629916..5846de364209 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -794,6 +794,7 @@ int bpf_link_create(int prog_fd, int target_fd,
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
 	case BPF_MODIFY_RETURN:
+	case BPF_TRACE_FSESSION:
 	case BPF_LSM_MAC:
 		attr.link_create.tracing.cookie = OPTS_GET(opts, tracing.cookie, 0);
 		if (!OPTS_ZEROED(opts, tracing))
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index bbcfd72b07d5..0c8bf0b5cce4 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -115,6 +115,7 @@ static const char * const attach_type_name[] = {
 	[BPF_TRACE_FENTRY]		= "trace_fentry",
 	[BPF_TRACE_FEXIT]		= "trace_fexit",
 	[BPF_MODIFY_RETURN]		= "modify_return",
+	[BPF_TRACE_FSESSION]		= "trace_fsession",
 	[BPF_LSM_MAC]			= "lsm_mac",
 	[BPF_LSM_CGROUP]		= "lsm_cgroup",
 	[BPF_SK_LOOKUP]			= "sk_lookup",
@@ -9859,6 +9860,8 @@ static const struct bpf_sec_def section_defs[] = {
 	SEC_DEF("fentry.s+",		TRACING, BPF_TRACE_FENTRY, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
 	SEC_DEF("fmod_ret.s+",		TRACING, BPF_MODIFY_RETURN, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
 	SEC_DEF("fexit.s+",		TRACING, BPF_TRACE_FEXIT, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
+	SEC_DEF("fsession+",		TRACING, BPF_TRACE_FSESSION, SEC_ATTACH_BTF, attach_trace),
+	SEC_DEF("fsession.s+",		TRACING, BPF_TRACE_FSESSION, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_trace),
 	SEC_DEF("freplace+",		EXT, 0, SEC_ATTACH_BTF, attach_trace),
 	SEC_DEF("lsm+",			LSM, BPF_LSM_MAC, SEC_ATTACH_BTF, attach_lsm),
 	SEC_DEF("lsm.s+",		LSM, BPF_LSM_MAC, SEC_ATTACH_BTF | SEC_SLEEPABLE, attach_lsm),
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 09/12] bpftool: add fsession support
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (7 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 08/12] libbpf: add fsession support Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 10/12] selftests/bpf: add testcases for fsession Menglong Dong
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Add BPF_TRACE_FSESSION to bpftool.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 tools/bpf/bpftool/common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index e8daf963ecef..8bfcff9e2f63 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -1191,6 +1191,7 @@ const char *bpf_attach_type_input_str(enum bpf_attach_type t)
 	case BPF_TRACE_FENTRY:			return "fentry";
 	case BPF_TRACE_FEXIT:			return "fexit";
 	case BPF_MODIFY_RETURN:			return "mod_ret";
+	case BPF_TRACE_FSESSION:		return "fsession";
 	case BPF_SK_REUSEPORT_SELECT:		return "sk_skb_reuseport_select";
 	case BPF_SK_REUSEPORT_SELECT_OR_MIGRATE:	return "sk_skb_reuseport_select_or_migrate";
 	default:	return libbpf_bpf_attach_type_str(t);
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 10/12] selftests/bpf: add testcases for fsession
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (8 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 09/12] bpftool: " Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-15 11:22 ` [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie Menglong Dong
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Add testcases for BPF_TRACE_FSESSION. The function arguments and return
value are tested both in the entry and exit. And the kfunc
bpf_session_is_ret() is also tested.

As the layout of the stack changed for fsession, so we also test
bpf_get_func_ip() for it.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v3:
- restructure the testcase by combine the testcases for session cookie and
  get_func_ip into one patch
---
 .../selftests/bpf/prog_tests/fsession_test.c  |  90 ++++++++++++++
 .../selftests/bpf/progs/fsession_test.c       | 110 ++++++++++++++++++
 2 files changed, 200 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/fsession_test.c
 create mode 100644 tools/testing/selftests/bpf/progs/fsession_test.c

diff --git a/tools/testing/selftests/bpf/prog_tests/fsession_test.c b/tools/testing/selftests/bpf/prog_tests/fsession_test.c
new file mode 100644
index 000000000000..75bb42942b67
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/fsession_test.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 ChinaTelecom */
+#include <test_progs.h>
+#include "fsession_test.skel.h"
+
+static int check_result(struct fsession_test *skel)
+{
+	LIBBPF_OPTS(bpf_test_run_opts, topts);
+	int err, prog_fd;
+
+	/* Trigger test function calls */
+	prog_fd = bpf_program__fd(skel->progs.test1);
+	err = bpf_prog_test_run_opts(prog_fd, &topts);
+	if (!ASSERT_OK(err, "test_run_opts err"))
+		return err;
+	if (!ASSERT_OK(topts.retval, "test_run_opts retval"))
+		return topts.retval;
+
+	for (int i = 0; i < sizeof(*skel->bss) / sizeof(__u64); i++) {
+		if (!ASSERT_EQ(((__u64 *)skel->bss)[i], 1, "test_result"))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void test_fsession_basic(void)
+{
+	struct fsession_test *skel = NULL;
+	int err;
+
+	skel = fsession_test__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open_and_load"))
+		goto cleanup;
+
+	err = fsession_test__attach(skel);
+	if (!ASSERT_OK(err, "fsession_attach"))
+		goto cleanup;
+
+	check_result(skel);
+cleanup:
+	fsession_test__destroy(skel);
+}
+
+static void test_fsession_reattach(void)
+{
+	struct fsession_test *skel = NULL;
+	int err;
+
+	skel = fsession_test__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open_and_load"))
+		goto cleanup;
+
+	/* first attach */
+	err = fsession_test__attach(skel);
+	if (!ASSERT_OK(err, "fsession_first_attach"))
+		goto cleanup;
+
+	if (check_result(skel))
+		goto cleanup;
+
+	/* detach */
+	fsession_test__detach(skel);
+
+	/* reset counters */
+	memset(skel->bss, 0, sizeof(*skel->bss));
+
+	/* second attach */
+	err = fsession_test__attach(skel);
+	if (!ASSERT_OK(err, "fsession_second_attach"))
+		goto cleanup;
+
+	if (check_result(skel))
+		goto cleanup;
+
+cleanup:
+	fsession_test__destroy(skel);
+}
+
+void test_fsession_test(void)
+{
+#if !defined(__x86_64__)
+	test__skip();
+	return;
+#endif
+	if (test__start_subtest("fsession_test"))
+		test_fsession_basic();
+	if (test__start_subtest("fsession_reattach"))
+		test_fsession_reattach();
+}
diff --git a/tools/testing/selftests/bpf/progs/fsession_test.c b/tools/testing/selftests/bpf/progs/fsession_test.c
new file mode 100644
index 000000000000..f504984d42f2
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/fsession_test.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 ChinaTelecom */
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+__u64 test1_entry_result = 0;
+__u64 test1_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test1")
+int BPF_PROG(test1, int a, int ret)
+{
+	bool is_exit = bpf_session_is_return(ctx);
+
+	if (!is_exit) {
+		test1_entry_result = a == 1 && ret == 0;
+		return 0;
+	}
+
+	test1_exit_result = a == 1 && ret == 2;
+	return 0;
+}
+
+__u64 test2_entry_result = 0;
+__u64 test2_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test3")
+int BPF_PROG(test2, char a, int b, __u64 c, int ret)
+{
+	bool is_exit = bpf_session_is_return(ctx);
+
+	if (!is_exit) {
+		test2_entry_result = a == 4 && b == 5 && c == 6 && ret == 0;
+		return 0;
+	}
+
+	test2_exit_result = a == 4 && b == 5 && c == 6 && ret == 15;
+	return 0;
+}
+
+__u64 test3_entry_result = 0;
+__u64 test3_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test4")
+int BPF_PROG(test3, void *a, char b, int c, __u64 d, int ret)
+{
+	bool is_exit = bpf_session_is_return(ctx);
+
+	if (!is_exit) {
+		test3_entry_result = a == (void *)7 && b == 8 && c == 9 && d == 10 && ret == 0;
+		return 0;
+	}
+
+	test3_exit_result = a == (void *)7 && b == 8 && c == 9 && d == 10 && ret == 34;
+	return 0;
+}
+
+__u64 test4_entry_result = 0;
+__u64 test4_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test5")
+int BPF_PROG(test4, __u64 a, void *b, short c, int d, __u64 e, int ret)
+{
+	bool is_exit = bpf_session_is_return(ctx);
+
+	if (!is_exit) {
+		test4_entry_result = a == 11 && b == (void *)12 && c == 13 && d == 14 &&
+			e == 15 && ret == 0;
+		return 0;
+	}
+
+	test4_exit_result = a == 11 && b == (void *)12 && c == 13 && d == 14 &&
+		e == 15 && ret == 65;
+	return 0;
+}
+
+__u64 test5_entry_result = 0;
+__u64 test5_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test7")
+int BPF_PROG(test5, struct bpf_fentry_test_t *arg, int ret)
+{
+	bool is_exit = bpf_session_is_return(ctx);
+
+	if (!is_exit) {
+		if (!arg)
+			test5_entry_result = ret == 0;
+		return 0;
+	}
+
+	if (!arg)
+		test5_exit_result = 1;
+	return 0;
+}
+
+__u64 test6_entry_result = 0;
+__u64 test6_exit_result = 0;
+SEC("fsession/bpf_fentry_test1")
+int BPF_PROG(test6, int a)
+{
+	__u64 addr = bpf_get_func_ip(ctx);
+
+	if (bpf_session_is_return(ctx))
+		test6_exit_result = (const void *) addr == &bpf_fentry_test1;
+	else
+		test6_entry_result = (const void *) addr == &bpf_fentry_test1;
+	return 0;
+}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (9 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 10/12] selftests/bpf: add testcases for fsession Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-22  0:07   ` Andrii Nakryiko
  2026-01-15 11:22 ` [PATCH bpf-next v10 12/12] selftests/bpf: test fsession mixed with fentry and fexit Menglong Dong
  2026-01-22  0:09 ` [PATCH bpf-next v10 00/12] bpf: fsession support Andrii Nakryiko
  12 siblings, 1 reply; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Test session cookie for fsession. Multiple fsession BPF progs is attached
to bpf_fentry_test1() and session cookie is read and write in the
testcase.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v3:
- restructure the testcase by combine the testcases for session cookie and
  get_func_ip into one patch
---
 .../selftests/bpf/progs/fsession_test.c       | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/fsession_test.c b/tools/testing/selftests/bpf/progs/fsession_test.c
index f504984d42f2..4e55ca67db46 100644
--- a/tools/testing/selftests/bpf/progs/fsession_test.c
+++ b/tools/testing/selftests/bpf/progs/fsession_test.c
@@ -108,3 +108,56 @@ int BPF_PROG(test6, int a)
 		test6_entry_result = (const void *) addr == &bpf_fentry_test1;
 	return 0;
 }
+
+__u64 test7_entry_ok = 0;
+__u64 test7_exit_ok = 0;
+SEC("fsession/bpf_fentry_test1")
+int BPF_PROG(test7, int a)
+{
+	__u64 *cookie = bpf_session_cookie(ctx);
+
+	if (!bpf_session_is_return(ctx)) {
+		*cookie = 0xAAAABBBBCCCCDDDDull;
+		test7_entry_ok = *cookie == 0xAAAABBBBCCCCDDDDull;
+		return 0;
+	}
+
+	test7_exit_ok = *cookie == 0xAAAABBBBCCCCDDDDull;
+	return 0;
+}
+
+__u64 test8_entry_ok = 0;
+__u64 test8_exit_ok = 0;
+
+SEC("fsession/bpf_fentry_test1")
+int BPF_PROG(test8, int a)
+{
+	__u64 *cookie = bpf_session_cookie(ctx);
+
+	if (!bpf_session_is_return(ctx)) {
+		*cookie = 0x1111222233334444ull;
+		test8_entry_ok = *cookie == 0x1111222233334444ull;
+		return 0;
+	}
+
+	test8_exit_ok = *cookie == 0x1111222233334444ull;
+	return 0;
+}
+
+__u64 test9_entry_result = 0;
+__u64 test9_exit_result = 0;
+
+SEC("fsession/bpf_fentry_test1")
+int BPF_PROG(test9, int a, int ret)
+{
+	__u64 *cookie = bpf_session_cookie(ctx);
+
+	if (!bpf_session_is_return(ctx)) {
+		test9_entry_result = a == 1 && ret == 0;
+		*cookie = 0x123456ULL;
+		return 0;
+	}
+
+	test9_exit_result = a == 1 && ret == 2 && *cookie == 0x123456ULL;
+	return 0;
+}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH bpf-next v10 12/12] selftests/bpf: test fsession mixed with fentry and fexit
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (10 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie Menglong Dong
@ 2026-01-15 11:22 ` Menglong Dong
  2026-01-22  0:09 ` [PATCH bpf-next v10 00/12] bpf: fsession support Andrii Nakryiko
  12 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-15 11:22 UTC (permalink / raw)
  To: ast, andrii
  Cc: daniel, martin.lau, eddyz87, song, yonghong.song, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx, mingo,
	jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev, linux-kernel

Test the fsession when it is used together with fentry, fexit.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 .../testing/selftests/bpf/progs/fsession_test.c  | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/fsession_test.c b/tools/testing/selftests/bpf/progs/fsession_test.c
index 4e55ca67db46..7f640ddc8905 100644
--- a/tools/testing/selftests/bpf/progs/fsession_test.c
+++ b/tools/testing/selftests/bpf/progs/fsession_test.c
@@ -161,3 +161,19 @@ int BPF_PROG(test9, int a, int ret)
 	test9_exit_result = a == 1 && ret == 2 && *cookie == 0x123456ULL;
 	return 0;
 }
+
+__u64 test10_result = 0;
+SEC("fexit/bpf_fentry_test1")
+int BPF_PROG(test10, int a, int ret)
+{
+	test10_result = a == 1 && ret == 2;
+	return 0;
+}
+
+__u64 test11_result = 0;
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(test11, int a)
+{
+	test11_result = a == 1;
+	return 0;
+}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64
  2026-01-15 11:22 ` [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64 Menglong Dong
@ 2026-01-22  0:06   ` Andrii Nakryiko
  2026-01-22  0:22     ` Andrii Nakryiko
  0 siblings, 1 reply; 21+ messages in thread
From: Andrii Nakryiko @ 2026-01-22  0:06 UTC (permalink / raw)
  To: Menglong Dong
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> Add BPF_TRACE_FSESSION supporting to x86_64, including:
>
> 1. clear the return value in the stack before fentry to make the fentry
>    of the fsession can only get 0 with bpf_get_func_ret().
>
> 2. clear all the session cookies' value in the stack.
>
> 2. store the index of the cookie to ctx[-1] before the calling to fsession
>
> 3. store the "is_return" flag to ctx[-1] before the calling to fexit of
>    the fsession.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
> Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
> ---
> v10:
> - use "|" for func_meta instead of "+"
> - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
>   computing it with "stack_size + 8"
> - pass the "cookie_off" to invoke_bpf() instead of computing the current
>   cookie index with "func_meta"
>
> v5:
> - add the variable "func_meta"
> - define cookie_off in a new line
>
> v4:
> - some adjustment to the 1st patch, such as we get the fsession prog from
>   fentry and fexit hlist
> - remove the supporting of skipping fexit with fentry return non-zero
>
> v2:
> - add session cookie support
> - add the session stuff after return value, instead of before nr_args
> ---
>  arch/x86/net/bpf_jit_comp.c | 52 ++++++++++++++++++++++++++++---------
>  1 file changed, 40 insertions(+), 12 deletions(-)
>
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 2f31331955b5..16720f2be16c 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -3094,13 +3094,19 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
>
>  static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
>                       struct bpf_tramp_links *tl, int stack_size,
> -                     int run_ctx_off, bool save_ret,
> -                     void *image, void *rw_image)
> +                     int run_ctx_off, int func_meta_off, bool save_ret,
> +                     void *image, void *rw_image, u64 func_meta,
> +                     int cookie_off)
>  {
> -       int i;
> +       int i, cur_cookie = (cookie_off - stack_size) / 8;

not sure why you went with passing cookie_off and then calculating,
effectively, cookie count out of that?... why not pass cookie count
directly then? it's minor, but just seems like a weird choice here,
tbh



>         u8 *prog = *pprog;
>
>         for (i = 0; i < tl->nr_links; i++) {
> +               if (tl->links[i]->link.prog->call_session_cookie) {
> +                       emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off,
> +                                              func_meta | (cur_cookie << BPF_TRAMP_SHIFT_COOKIE));
> +                       cur_cookie--;
> +               }
>                 if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
>                                     run_ctx_off, save_ret, image, rw_image))
>                         return -EINVAL;

[...]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie
  2026-01-15 11:22 ` [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie Menglong Dong
@ 2026-01-22  0:07   ` Andrii Nakryiko
  2026-01-22  2:18     ` Menglong Dong
  0 siblings, 1 reply; 21+ messages in thread
From: Andrii Nakryiko @ 2026-01-22  0:07 UTC (permalink / raw)
  To: Menglong Dong
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> Test session cookie for fsession. Multiple fsession BPF progs is attached
> to bpf_fentry_test1() and session cookie is read and write in the
> testcase.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> v3:
> - restructure the testcase by combine the testcases for session cookie and
>   get_func_ip into one patch
> ---
>  .../selftests/bpf/progs/fsession_test.c       | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/fsession_test.c b/tools/testing/selftests/bpf/progs/fsession_test.c
> index f504984d42f2..4e55ca67db46 100644
> --- a/tools/testing/selftests/bpf/progs/fsession_test.c
> +++ b/tools/testing/selftests/bpf/progs/fsession_test.c
> @@ -108,3 +108,56 @@ int BPF_PROG(test6, int a)
>                 test6_entry_result = (const void *) addr == &bpf_fentry_test1;
>         return 0;
>  }
> +
> +__u64 test7_entry_ok = 0;
> +__u64 test7_exit_ok = 0;
> +SEC("fsession/bpf_fentry_test1")
> +int BPF_PROG(test7, int a)
> +{
> +       __u64 *cookie = bpf_session_cookie(ctx);
> +
> +       if (!bpf_session_is_return(ctx)) {
> +               *cookie = 0xAAAABBBBCCCCDDDDull;
> +               test7_entry_ok = *cookie == 0xAAAABBBBCCCCDDDDull;

you are trying to double-check that writing into *cookie preserves the
written value, is that right? Do we need volatile read here to ensure
that compiler doesn't optimize this?

> +               return 0;
> +       }
> +
> +       test7_exit_ok = *cookie == 0xAAAABBBBCCCCDDDDull;
> +       return 0;
> +}
> +
> +__u64 test8_entry_ok = 0;
> +__u64 test8_exit_ok = 0;
> +
> +SEC("fsession/bpf_fentry_test1")
> +int BPF_PROG(test8, int a)
> +{
> +       __u64 *cookie = bpf_session_cookie(ctx);
> +
> +       if (!bpf_session_is_return(ctx)) {
> +               *cookie = 0x1111222233334444ull;
> +               test8_entry_ok = *cookie == 0x1111222233334444ull;
> +               return 0;
> +       }
> +
> +       test8_exit_ok = *cookie == 0x1111222233334444ull;
> +       return 0;
> +}
> +
> +__u64 test9_entry_result = 0;
> +__u64 test9_exit_result = 0;
> +
> +SEC("fsession/bpf_fentry_test1")
> +int BPF_PROG(test9, int a, int ret)
> +{
> +       __u64 *cookie = bpf_session_cookie(ctx);
> +
> +       if (!bpf_session_is_return(ctx)) {
> +               test9_entry_result = a == 1 && ret == 0;
> +               *cookie = 0x123456ULL;
> +               return 0;
> +       }
> +
> +       test9_exit_result = a == 1 && ret == 2 && *cookie == 0x123456ULL;
> +       return 0;
> +}
> --
> 2.52.0
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 00/12] bpf: fsession support
  2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
                   ` (11 preceding siblings ...)
  2026-01-15 11:22 ` [PATCH bpf-next v10 12/12] selftests/bpf: test fsession mixed with fentry and fexit Menglong Dong
@ 2026-01-22  0:09 ` Andrii Nakryiko
  2026-01-22  2:49   ` Menglong Dong
  12 siblings, 1 reply; 21+ messages in thread
From: Andrii Nakryiko @ 2026-01-22  0:09 UTC (permalink / raw)
  To: Menglong Dong
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On Thu, Jan 15, 2026 at 3:23 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> Hi, all.
>
> In this version, I followed Andrii's suggestions in v9, and did many
> adjustment.
>
> overall
> -------
> Sometimes, we need to hook both the entry and exit of a function with
> TRACING. Therefore, we need define a FENTRY and a FEXIT for the target
> function, which is not convenient.
>
> Therefore, we add a tracing session support for TRACING. Generally
> speaking, it's similar to kprobe session, which can hook both the entry
> and exit of a function with a single BPF program.
>
> We allow the usage of bpf_get_func_ret() to get the return value in the
> fentry of the tracing session, as it will always get "0", which is safe
> enough and is OK.
>
> Session cookie is also supported with the kfunc bpf_session_cookie().
> In order to limit the stack usage, we limit the maximum number of cookies
> to 4.
>
> kfunc design
> ------------
> In order to keep consistency with existing kfunc, we don't introduce new
> kfunc for fsession. Instead, we reuse the existing kfunc
> bpf_session_cookie() and bpf_session_is_return().
>
> The prototype of bpf_session_cookie() and bpf_session_is_return() don't
> satisfy our needs, so we change their prototype by adding the argument
> "void *ctx" to them.
>
> We inline bpf_session_cookie() and bpf_session_is_return() for fsession
> in the verifier directly. Therefore, we don't need to introduce new
> functions for them.
>
> architecture
> ------------
> The fsession stuff is arch related, so the -EOPNOTSUPP will be returned if
> it is not supported yet by the arch. In this series, we only support
> x86_64. And later, other arch will be implemented.
>
> Changes v9 -> v10:
> * 1st patch: some small adjustment, such as use switch in
>   bpf_prog_has_trampoline()
> * 2nd patch: some adjustment to the commit log and comment
> * 3rd patch:
>   - drop the declaration of bpf_session_is_return() and
>     bpf_session_cookie()
>   - use vmlinux.h instead of bpf_kfuncs.h in uprobe_multi_session.c,
>     kprobe_multi_session_cookie.c and uprobe_multi_session_cookie.c
> * 4th patch:
>   - some adjustment to the comment and commit log
>   - rename the prefix from BPF_TRAMP_M_ tp BPF_TRAMP_SHIFT_

This is minor nit, but I think BPF_TRAMP_IS_RETURN_SHIFT and
BPF_TRAMP_COOKIE_INDEX_SHIFT (note added INDEX, because that's what we
store, not the cookie itself) makes more sense naming-wise and is more
natural to read. Consider updating this.

>   - remove the definition of BPF_TRAMP_M_NR_ARGS
>   - check the program type in bpf_session_filter()
> * 5th patch: some adjustment to the commit log
> * 6th patch:
>   - add the "reg" to the function arguments of emit_store_stack_imm64()
>   - use the positive offset in emit_store_stack_imm64()
> * 7th patch:
>   - use "|" for func_meta instead of "+"
>   - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
>     computing it with "stack_size + 8"
>   - pass the "cookie_off" to invoke_bpf() instead of computing the current
>     cookie index with "func_meta"
> * 8th patch:
>   - split the modification to bpftool to a separate patch
> * v9: https://lore.kernel.org/bpf/20260110141115.537055-1-dongml2@chinatelecom.cn/
>

Overall this looks great, I was actually trying to apply and push it
despite those minor nits I left. But unfortunately there is some
conflict, so you'll have to rebase and resend. Hopefully just one last
time :)

> Changes v8 -> v9:
> * remove the definition of bpf_fsession_cookie and bpf_fsession_is_return
>   in the 4th and 5th patch
> * rename emit_st_r0_imm64() to emit_store_stack_imm64() in the 6th patch
> * v8: https://lore.kernel.org/bpf/20260108022450.88086-1-dongml2@chinatelecom.cn/
>
> Changes v7 -> v8:
> * use the last byte of nr_args for bpf_get_func_arg_cnt() in the 2nd patch
> * v7: https://lore.kernel.org/bpf/20260107064352.291069-1-dongml2@chinatelecom.cn/
>
> Changes v6 -> v7:
> * change the prototype of bpf_session_cookie() and bpf_session_is_return(),
>   and reuse them instead of introduce new kfunc for fsession.
> * v6: https://lore.kernel.org/bpf/20260104122814.183732-1-dongml2@chinatelecom.cn/
>
> Changes v5 -> v6:
> * No changes in this version, just a rebase to deal with conflicts.
> * v5: https://lore.kernel.org/bpf/20251224130735.201422-1-dongml2@chinatelecom.cn/
>
> Changes v4 -> v5:
> * use fsession terminology consistently in all patches
> * 1st patch:
>   - use more explicit way in __bpf_trampoline_link_prog()
> * 4th patch:
>   - remove "cookie_cnt" in struct bpf_trampoline
> * 6th patch:
>   - rename nr_regs to func_md
>   - define cookie_off in a new line
> * 7th patch:
>   - remove the handling of BPF_TRACE_SESSION in legacy fallback path for
>     BPF_RAW_TRACEPOINT_OPEN
> * v4: https://lore.kernel.org/bpf/20251217095445.218428-1-dongml2@chinatelecom.cn/
>
> Changes v3 -> v4:
> * instead of adding a new hlist to progs_hlist in trampoline, add the bpf
>   program to both the fentry hlist and the fexit hlist.
> * introduce the 2nd patch to reuse the nr_args field in the stack to
>   store all the information we need(except the session cookies).
> * limit the maximum number of cookies to 4.
> * remove the logic to skip fexit if the fentry return non-zero.
> * v3: https://lore.kernel.org/bpf/20251026030143.23807-1-dongml2@chinatelecom.cn/
>
> Changes v2 -> v3:
> * squeeze some patches:
>   - the 2 patches for the kfunc bpf_tracing_is_exit() and
>     bpf_fsession_cookie() are merged into the second patch.
>   - the testcases for fsession are also squeezed.
> * fix the CI error by move the testcase for bpf_get_func_ip to
>   fsession_test.c
> * v2: https://lore.kernel.org/bpf/20251022080159.553805-1-dongml2@chinatelecom.cn/
>
> Changes v1 -> v2:
> * session cookie support.
>   In this version, session cookie is implemented, and the kfunc
>   bpf_fsession_cookie() is added.
> * restructure the layout of the stack.
>   In this version, the session stuff that stored in the stack is changed,
>   and we locate them after the return value to not break
>   bpf_get_func_ip().
> * testcase enhancement.
>   Some nits in the testcase that suggested by Jiri is fixed. Meanwhile,
>   the testcase for get_func_ip and session cookie is added too.
> * v1: https://lore.kernel.org/bpf/20251018142124.783206-1-dongml2@chinatelecom.cn/
>
> Menglong Dong (12):
>   bpf: add fsession support
>   bpf: use the least significant byte for the nr_args in trampoline
>   bpf: change prototype of bpf_session_{cookie,is_return}
>   bpf: support fsession for bpf_session_is_return
>   bpf: support fsession for bpf_session_cookie
>   bpf,x86: introduce emit_store_stack_imm64() for trampoline
>   bpf,x86: add fsession support for x86_64
>   libbpf: add fsession support
>   bpftool: add fsession support
>   selftests/bpf: add testcases for fsession
>   selftests/bpf: add testcases for fsession cookie
>   selftests/bpf: test fsession mixed with fentry and fexit
>
>  arch/x86/net/bpf_jit_comp.c                   |  71 +++++--
>  include/linux/bpf.h                           |  36 ++++
>  include/uapi/linux/bpf.h                      |   1 +
>  kernel/bpf/btf.c                              |   2 +
>  kernel/bpf/syscall.c                          |  18 +-
>  kernel/bpf/trampoline.c                       |  53 +++++-
>  kernel/bpf/verifier.c                         |  86 +++++++--
>  kernel/trace/bpf_trace.c                      |  49 +++--
>  net/bpf/test_run.c                            |   1 +
>  net/core/bpf_sk_storage.c                     |   1 +
>  tools/bpf/bpftool/common.c                    |   1 +
>  tools/include/uapi/linux/bpf.h                |   1 +
>  tools/lib/bpf/bpf.c                           |   1 +
>  tools/lib/bpf/libbpf.c                        |   3 +
>  tools/testing/selftests/bpf/bpf_kfuncs.h      |   3 -
>  .../selftests/bpf/prog_tests/fsession_test.c  |  90 +++++++++
>  .../bpf/prog_tests/tracing_failure.c          |   2 +-
>  .../selftests/bpf/progs/fsession_test.c       | 179 ++++++++++++++++++
>  .../bpf/progs/kprobe_multi_session_cookie.c   |  15 +-
>  .../bpf/progs/uprobe_multi_session.c          |   7 +-
>  .../bpf/progs/uprobe_multi_session_cookie.c   |  15 +-
>  .../progs/uprobe_multi_session_recursive.c    |  11 +-
>  22 files changed, 550 insertions(+), 96 deletions(-)
>  create mode 100644 tools/testing/selftests/bpf/prog_tests/fsession_test.c
>  create mode 100644 tools/testing/selftests/bpf/progs/fsession_test.c
>
> --
> 2.52.0
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64
  2026-01-22  0:06   ` Andrii Nakryiko
@ 2026-01-22  0:22     ` Andrii Nakryiko
  2026-01-22  2:41       ` Menglong Dong
  0 siblings, 1 reply; 21+ messages in thread
From: Andrii Nakryiko @ 2026-01-22  0:22 UTC (permalink / raw)
  To: Menglong Dong
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On Wed, Jan 21, 2026 at 4:06 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > Add BPF_TRACE_FSESSION supporting to x86_64, including:
> >
> > 1. clear the return value in the stack before fentry to make the fentry
> >    of the fsession can only get 0 with bpf_get_func_ret().
> >
> > 2. clear all the session cookies' value in the stack.
> >
> > 2. store the index of the cookie to ctx[-1] before the calling to fsession
> >
> > 3. store the "is_return" flag to ctx[-1] before the calling to fexit of
> >    the fsession.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
> > Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
> > ---
> > v10:
> > - use "|" for func_meta instead of "+"
> > - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
> >   computing it with "stack_size + 8"
> > - pass the "cookie_off" to invoke_bpf() instead of computing the current
> >   cookie index with "func_meta"
> >
> > v5:
> > - add the variable "func_meta"
> > - define cookie_off in a new line
> >
> > v4:
> > - some adjustment to the 1st patch, such as we get the fsession prog from
> >   fentry and fexit hlist
> > - remove the supporting of skipping fexit with fentry return non-zero
> >
> > v2:
> > - add session cookie support
> > - add the session stuff after return value, instead of before nr_args
> > ---
> >  arch/x86/net/bpf_jit_comp.c | 52 ++++++++++++++++++++++++++++---------
> >  1 file changed, 40 insertions(+), 12 deletions(-)
> >
> > diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> > index 2f31331955b5..16720f2be16c 100644
> > --- a/arch/x86/net/bpf_jit_comp.c
> > +++ b/arch/x86/net/bpf_jit_comp.c
> > @@ -3094,13 +3094,19 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
> >
> >  static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
> >                       struct bpf_tramp_links *tl, int stack_size,
> > -                     int run_ctx_off, bool save_ret,
> > -                     void *image, void *rw_image)
> > +                     int run_ctx_off, int func_meta_off, bool save_ret,
> > +                     void *image, void *rw_image, u64 func_meta,
> > +                     int cookie_off)
> >  {
> > -       int i;
> > +       int i, cur_cookie = (cookie_off - stack_size) / 8;
>
> not sure why you went with passing cookie_off and then calculating,
> effectively, cookie count out of that?... why not pass cookie count
> directly then? it's minor, but just seems like a weird choice here,
> tbh
>

consider also just calculating cookie count out from bpf_tramp_links?
would that work? Then "func_meta" would really be just nr_args (and
I'd call it that) and bool for whether this is entry or exit
invokation (for IS_RETURN bit, and maybe we'll need this distinction
somewhere else in the future), and then invoke_bpf() will construct
func_meta from scratch.

It's relatively minor thing, but as I mentioned before, it's this
hybrid approach of partially opaque (from invoke_bpf's POV) func_meta
which we also adjust or fill out (for cookie index) is a bit of a sign
that this is not a proper interface.

>
>
> >         u8 *prog = *pprog;
> >
> >         for (i = 0; i < tl->nr_links; i++) {
> > +               if (tl->links[i]->link.prog->call_session_cookie) {
> > +                       emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off,
> > +                                              func_meta | (cur_cookie << BPF_TRAMP_SHIFT_COOKIE));
> > +                       cur_cookie--;
> > +               }
> >                 if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
> >                                     run_ctx_off, save_ret, image, rw_image))
> >                         return -EINVAL;
>
> [...]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie
  2026-01-22  0:07   ` Andrii Nakryiko
@ 2026-01-22  2:18     ` Menglong Dong
  0 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-22  2:18 UTC (permalink / raw)
  To: Menglong Dong, Andrii Nakryiko
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On 2026/1/22 08:07 Andrii Nakryiko <andrii.nakryiko@gmail.com> write:
> On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > Test session cookie for fsession. Multiple fsession BPF progs is attached
> > to bpf_fentry_test1() and session cookie is read and write in the
> > testcase.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > v3:
> > - restructure the testcase by combine the testcases for session cookie and
> >   get_func_ip into one patch
> > ---
> >  .../selftests/bpf/progs/fsession_test.c       | 53 +++++++++++++++++++
> >  1 file changed, 53 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/progs/fsession_test.c b/tools/testing/selftests/bpf/progs/fsession_test.c
> > index f504984d42f2..4e55ca67db46 100644
> > --- a/tools/testing/selftests/bpf/progs/fsession_test.c
> > +++ b/tools/testing/selftests/bpf/progs/fsession_test.c
> > @@ -108,3 +108,56 @@ int BPF_PROG(test6, int a)
> >                 test6_entry_result = (const void *) addr == &bpf_fentry_test1;
> >         return 0;
> >  }
> > +
> > +__u64 test7_entry_ok = 0;
> > +__u64 test7_exit_ok = 0;
> > +SEC("fsession/bpf_fentry_test1")
> > +int BPF_PROG(test7, int a)
> > +{
> > +       __u64 *cookie = bpf_session_cookie(ctx);
> > +
> > +       if (!bpf_session_is_return(ctx)) {
> > +               *cookie = 0xAAAABBBBCCCCDDDDull;
> > +               test7_entry_ok = *cookie == 0xAAAABBBBCCCCDDDDull;
> 
> you are trying to double-check that writing into *cookie preserves the
> written value, is that right? Do we need volatile read here to ensure
> that compiler doesn't optimize this?

Yeah, you are right. READ_ONCE and WRITE_ONCE should be used
here. I'll use them next version.

Thanks!
Menglong Dong

> 
> > +               return 0;
> > +       }
> > +
> > +       test7_exit_ok = *cookie == 0xAAAABBBBCCCCDDDDull;
> > +       return 0;
> > +}
> > +
> > +__u64 test8_entry_ok = 0;
> > +__u64 test8_exit_ok = 0;
> > +
> > +SEC("fsession/bpf_fentry_test1")
> > +int BPF_PROG(test8, int a)
> > +{
> > +       __u64 *cookie = bpf_session_cookie(ctx);
> > +
> > +       if (!bpf_session_is_return(ctx)) {
> > +               *cookie = 0x1111222233334444ull;
> > +               test8_entry_ok = *cookie == 0x1111222233334444ull;
> > +               return 0;
> > +       }
> > +
> > +       test8_exit_ok = *cookie == 0x1111222233334444ull;
> > +       return 0;
> > +}
> > +
> > +__u64 test9_entry_result = 0;
> > +__u64 test9_exit_result = 0;
> > +
> > +SEC("fsession/bpf_fentry_test1")
> > +int BPF_PROG(test9, int a, int ret)
> > +{
> > +       __u64 *cookie = bpf_session_cookie(ctx);
> > +
> > +       if (!bpf_session_is_return(ctx)) {
> > +               test9_entry_result = a == 1 && ret == 0;
> > +               *cookie = 0x123456ULL;
> > +               return 0;
> > +       }
> > +
> > +       test9_exit_result = a == 1 && ret == 2 && *cookie == 0x123456ULL;
> > +       return 0;
> > +}
> > --
> > 2.52.0
> >
> 





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64
  2026-01-22  0:22     ` Andrii Nakryiko
@ 2026-01-22  2:41       ` Menglong Dong
  2026-01-22 16:57         ` Andrii Nakryiko
  0 siblings, 1 reply; 21+ messages in thread
From: Menglong Dong @ 2026-01-22  2:41 UTC (permalink / raw)
  To: Menglong Dong, Andrii Nakryiko
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On 2026/1/22 08:22 Andrii Nakryiko <andrii.nakryiko@gmail.com> write:
> On Wed, Jan 21, 2026 at 4:06 PM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> > >
> > > Add BPF_TRACE_FSESSION supporting to x86_64, including:
> > >
> > > 1. clear the return value in the stack before fentry to make the fentry
> > >    of the fsession can only get 0 with bpf_get_func_ret().
> > >
> > > 2. clear all the session cookies' value in the stack.
> > >
> > > 2. store the index of the cookie to ctx[-1] before the calling to fsession
> > >
> > > 3. store the "is_return" flag to ctx[-1] before the calling to fexit of
> > >    the fsession.
> > >
> > > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > > Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
> > > Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
> > > ---
> > > v10:
> > > - use "|" for func_meta instead of "+"
> > > - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
> > >   computing it with "stack_size + 8"
> > > - pass the "cookie_off" to invoke_bpf() instead of computing the current
> > >   cookie index with "func_meta"
> > >
> > > v5:
> > > - add the variable "func_meta"
> > > - define cookie_off in a new line
> > >
> > > v4:
> > > - some adjustment to the 1st patch, such as we get the fsession prog from
> > >   fentry and fexit hlist
> > > - remove the supporting of skipping fexit with fentry return non-zero
> > >
> > > v2:
> > > - add session cookie support
> > > - add the session stuff after return value, instead of before nr_args
> > > ---
> > >  arch/x86/net/bpf_jit_comp.c | 52 ++++++++++++++++++++++++++++---------
> > >  1 file changed, 40 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> > > index 2f31331955b5..16720f2be16c 100644
> > > --- a/arch/x86/net/bpf_jit_comp.c
> > > +++ b/arch/x86/net/bpf_jit_comp.c
> > > @@ -3094,13 +3094,19 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
> > >
> > >  static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
> > >                       struct bpf_tramp_links *tl, int stack_size,
> > > -                     int run_ctx_off, bool save_ret,
> > > -                     void *image, void *rw_image)
> > > +                     int run_ctx_off, int func_meta_off, bool save_ret,
> > > +                     void *image, void *rw_image, u64 func_meta,
> > > +                     int cookie_off)
> > >  {
> > > -       int i;
> > > +       int i, cur_cookie = (cookie_off - stack_size) / 8;
> >
> > not sure why you went with passing cookie_off and then calculating,
> > effectively, cookie count out of that?... why not pass cookie count
> > directly then? it's minor, but just seems like a weird choice here,
> > tbh

Hi, Andrii. I think you misunderstand it here. The cur_cookie is not the
same as cookie count. The layout of the stack looks like this:

  return value  -> 8 bytes
  argN          -> 8 bytes
  ...
  arg1          -> 8 bytes
  nr_args       -> 8 bytes
  ip (optional) -> 8 bytes
  cookie2       -> 8 bytes
  cookie1       -> 8 bytes

So if the bpf_get_func_ip() not used, the cur_cookie is exactly the same
as cookie count. But if it exist, they are not the same.

The location of the cookies is independent from the context, and the
cur_cookie, which is the index of the current cookie, don't rely on cookie
count too and can be bigger than cookie count.

PS: the location of "ip" should always laid before the nr_args, as we get
it with ctx[-2]. Maybe we can optimize it later. We store the index of
the ip the func_meta too, therefore it is independent from the ctx too.
Ah, it looks not make much sense ;)

> >
> 
> consider also just calculating cookie count out from bpf_tramp_links?
> would that work? Then "func_meta" would really be just nr_args (and
> I'd call it that) and bool for whether this is entry or exit
> invokation (for IS_RETURN bit, and maybe we'll need this distinction
> somewhere else in the future), and then invoke_bpf() will construct
> func_meta from scratch.
> 
> It's relatively minor thing, but as I mentioned before, it's this
> hybrid approach of partially opaque (from invoke_bpf's POV) func_meta
> which we also adjust or fill out (for cookie index) is a bit of a sign
> that this is not a proper interface.

Yeah, the current approach is indeed not perfect. But I think it's
a little not flex if we construct the whole func_meta in invoke_bpf().
For now, we need to pass nr_args, is_return, cookie_off to it. And
we need to add more function arguments to invoke_bpf() if there
are new flags occur in the feature, which is not convenient, right?

So what do you think?

Thanks!
Menglong Dong

> 
> >
> >
> > >         u8 *prog = *pprog;
> > >
> > >         for (i = 0; i < tl->nr_links; i++) {
> > > +               if (tl->links[i]->link.prog->call_session_cookie) {
> > > +                       emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off,
> > > +                                              func_meta | (cur_cookie << BPF_TRAMP_SHIFT_COOKIE));
> > > +                       cur_cookie--;
> > > +               }
> > >                 if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
> > >                                     run_ctx_off, save_ret, image, rw_image))
> > >                         return -EINVAL;
> >
> > [...]
> 





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 00/12] bpf: fsession support
  2026-01-22  0:09 ` [PATCH bpf-next v10 00/12] bpf: fsession support Andrii Nakryiko
@ 2026-01-22  2:49   ` Menglong Dong
  0 siblings, 0 replies; 21+ messages in thread
From: Menglong Dong @ 2026-01-22  2:49 UTC (permalink / raw)
  To: Menglong Dong, Andrii Nakryiko
  Cc: ast, andrii, daniel, martin.lau, eddyz87, song, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, dsahern, tglx,
	mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf, netdev,
	linux-kernel

On 2026/1/22 08:09 Andrii Nakryiko <andrii.nakryiko@gmail.com> write:
> On Thu, Jan 15, 2026 at 3:23 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > Hi, all.
> >
> > In this version, I followed Andrii's suggestions in v9, and did many
> > adjustment.
> >
> > overall
> > -------
> > Sometimes, we need to hook both the entry and exit of a function with
> > TRACING. Therefore, we need define a FENTRY and a FEXIT for the target
> > function, which is not convenient.
> >
> > Therefore, we add a tracing session support for TRACING. Generally
> > speaking, it's similar to kprobe session, which can hook both the entry
> > and exit of a function with a single BPF program.
> >
> > We allow the usage of bpf_get_func_ret() to get the return value in the
> > fentry of the tracing session, as it will always get "0", which is safe
> > enough and is OK.
> >
> > Session cookie is also supported with the kfunc bpf_session_cookie().
> > In order to limit the stack usage, we limit the maximum number of cookies
> > to 4.
> >
> > kfunc design
> > ------------
> > In order to keep consistency with existing kfunc, we don't introduce new
> > kfunc for fsession. Instead, we reuse the existing kfunc
> > bpf_session_cookie() and bpf_session_is_return().
> >
> > The prototype of bpf_session_cookie() and bpf_session_is_return() don't
> > satisfy our needs, so we change their prototype by adding the argument
> > "void *ctx" to them.
> >
> > We inline bpf_session_cookie() and bpf_session_is_return() for fsession
> > in the verifier directly. Therefore, we don't need to introduce new
> > functions for them.
> >
> > architecture
> > ------------
> > The fsession stuff is arch related, so the -EOPNOTSUPP will be returned if
> > it is not supported yet by the arch. In this series, we only support
> > x86_64. And later, other arch will be implemented.
> >
> > Changes v9 -> v10:
> > * 1st patch: some small adjustment, such as use switch in
> >   bpf_prog_has_trampoline()
> > * 2nd patch: some adjustment to the commit log and comment
> > * 3rd patch:
> >   - drop the declaration of bpf_session_is_return() and
> >     bpf_session_cookie()
> >   - use vmlinux.h instead of bpf_kfuncs.h in uprobe_multi_session.c,
> >     kprobe_multi_session_cookie.c and uprobe_multi_session_cookie.c
> > * 4th patch:
> >   - some adjustment to the comment and commit log
> >   - rename the prefix from BPF_TRAMP_M_ tp BPF_TRAMP_SHIFT_
> 
> This is minor nit, but I think BPF_TRAMP_IS_RETURN_SHIFT and
> BPF_TRAMP_COOKIE_INDEX_SHIFT (note added INDEX, because that's what we
> store, not the cookie itself) makes more sense naming-wise and is more
> natural to read. Consider updating this.

Yeah, looks nice.

> 
> >   - remove the definition of BPF_TRAMP_M_NR_ARGS
> >   - check the program type in bpf_session_filter()
> > * 5th patch: some adjustment to the commit log
> > * 6th patch:
> >   - add the "reg" to the function arguments of emit_store_stack_imm64()
> >   - use the positive offset in emit_store_stack_imm64()
> > * 7th patch:
> >   - use "|" for func_meta instead of "+"
> >   - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
> >     computing it with "stack_size + 8"
> >   - pass the "cookie_off" to invoke_bpf() instead of computing the current
> >     cookie index with "func_meta"
> > * 8th patch:
> >   - split the modification to bpftool to a separate patch
> > * v9: https://lore.kernel.org/bpf/20260110141115.537055-1-dongml2@chinatelecom.cn/
> >
> 
> Overall this looks great, I was actually trying to apply and push it
> despite those minor nits I left. But unfortunately there is some
> conflict, so you'll have to rebase and resend. Hopefully just one last
> time :)

Haha, sounds great! I'll follow your comment and rebase, and
send the next version later.

Thanks you the review ;)

> 
> > Changes v8 -> v9:
> > * remove the definition of bpf_fsession_cookie and bpf_fsession_is_return
> >   in the 4th and 5th patch
> > * rename emit_st_r0_imm64() to emit_store_stack_imm64() in the 6th patch
> > * v8: https://lore.kernel.org/bpf/20260108022450.88086-1-dongml2@chinatelecom.cn/
> >
[...]
> >
> 





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64
  2026-01-22  2:41       ` Menglong Dong
@ 2026-01-22 16:57         ` Andrii Nakryiko
  0 siblings, 0 replies; 21+ messages in thread
From: Andrii Nakryiko @ 2026-01-22 16:57 UTC (permalink / raw)
  To: Menglong Dong
  Cc: Menglong Dong, ast, andrii, daniel, martin.lau, eddyz87, song,
	yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa, davem,
	dsahern, tglx, mingo, jiang.biao, bp, dave.hansen, x86, hpa, bpf,
	netdev, linux-kernel

On Wed, Jan 21, 2026 at 6:41 PM Menglong Dong <menglong.dong@linux.dev> wrote:
>
> On 2026/1/22 08:22 Andrii Nakryiko <andrii.nakryiko@gmail.com> write:
> > On Wed, Jan 21, 2026 at 4:06 PM Andrii Nakryiko
> > <andrii.nakryiko@gmail.com> wrote:
> > >
> > > On Thu, Jan 15, 2026 at 3:24 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> > > >
> > > > Add BPF_TRACE_FSESSION supporting to x86_64, including:
> > > >
> > > > 1. clear the return value in the stack before fentry to make the fentry
> > > >    of the fsession can only get 0 with bpf_get_func_ret().
> > > >
> > > > 2. clear all the session cookies' value in the stack.
> > > >
> > > > 2. store the index of the cookie to ctx[-1] before the calling to fsession
> > > >
> > > > 3. store the "is_return" flag to ctx[-1] before the calling to fexit of
> > > >    the fsession.
> > > >
> > > > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > > > Co-developed-by: Leon Hwang <leon.hwang@linux.dev>
> > > > Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
> > > > ---
> > > > v10:
> > > > - use "|" for func_meta instead of "+"
> > > > - pass the "func_meta_off" to invoke_bpf() explicitly, instead of
> > > >   computing it with "stack_size + 8"
> > > > - pass the "cookie_off" to invoke_bpf() instead of computing the current
> > > >   cookie index with "func_meta"
> > > >
> > > > v5:
> > > > - add the variable "func_meta"
> > > > - define cookie_off in a new line
> > > >
> > > > v4:
> > > > - some adjustment to the 1st patch, such as we get the fsession prog from
> > > >   fentry and fexit hlist
> > > > - remove the supporting of skipping fexit with fentry return non-zero
> > > >
> > > > v2:
> > > > - add session cookie support
> > > > - add the session stuff after return value, instead of before nr_args
> > > > ---
> > > >  arch/x86/net/bpf_jit_comp.c | 52 ++++++++++++++++++++++++++++---------
> > > >  1 file changed, 40 insertions(+), 12 deletions(-)
> > > >
> > > > diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> > > > index 2f31331955b5..16720f2be16c 100644
> > > > --- a/arch/x86/net/bpf_jit_comp.c
> > > > +++ b/arch/x86/net/bpf_jit_comp.c
> > > > @@ -3094,13 +3094,19 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
> > > >
> > > >  static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
> > > >                       struct bpf_tramp_links *tl, int stack_size,
> > > > -                     int run_ctx_off, bool save_ret,
> > > > -                     void *image, void *rw_image)
> > > > +                     int run_ctx_off, int func_meta_off, bool save_ret,
> > > > +                     void *image, void *rw_image, u64 func_meta,
> > > > +                     int cookie_off)
> > > >  {
> > > > -       int i;
> > > > +       int i, cur_cookie = (cookie_off - stack_size) / 8;
> > >
> > > not sure why you went with passing cookie_off and then calculating,
> > > effectively, cookie count out of that?... why not pass cookie count
> > > directly then? it's minor, but just seems like a weird choice here,
> > > tbh
>
> Hi, Andrii. I think you misunderstand it here. The cur_cookie is not the
> same as cookie count. The layout of the stack looks like this:
>
>   return value  -> 8 bytes
>   argN          -> 8 bytes
>   ...
>   arg1          -> 8 bytes
>   nr_args       -> 8 bytes
>   ip (optional) -> 8 bytes
>   cookie2       -> 8 bytes
>   cookie1       -> 8 bytes
>
> So if the bpf_get_func_ip() not used, the cur_cookie is exactly the same
> as cookie count. But if it exist, they are not the same.
>
> The location of the cookies is independent from the context, and the
> cur_cookie, which is the index of the current cookie, don't rely on cookie
> count too and can be bigger than cookie count.
>
> PS: the location of "ip" should always laid before the nr_args, as we get
> it with ctx[-2]. Maybe we can optimize it later. We store the index of
> the ip the func_meta too, therefore it is independent from the ctx too.
> Ah, it looks not make much sense ;)

no, it makes sense, I missed that we have this optional ip stored,
which changes cookies offset. So let's leave everything as is.

A thing to consider for the future would be whether it would make
sense to have dedicated ip slot on the stack regardless of whether we
use bpf_get_func_ip() or not, just not fill it out if not necessary.
That would fix offsets and make things a bit simpler. But as I said,
just something to think about, no need to change the logic right now,
I think.

>
> > >
> >
> > consider also just calculating cookie count out from bpf_tramp_links?
> > would that work? Then "func_meta" would really be just nr_args (and
> > I'd call it that) and bool for whether this is entry or exit
> > invokation (for IS_RETURN bit, and maybe we'll need this distinction
> > somewhere else in the future), and then invoke_bpf() will construct
> > func_meta from scratch.
> >
> > It's relatively minor thing, but as I mentioned before, it's this
> > hybrid approach of partially opaque (from invoke_bpf's POV) func_meta
> > which we also adjust or fill out (for cookie index) is a bit of a sign
> > that this is not a proper interface.
>
> Yeah, the current approach is indeed not perfect. But I think it's
> a little not flex if we construct the whole func_meta in invoke_bpf().
> For now, we need to pass nr_args, is_return, cookie_off to it. And
> we need to add more function arguments to invoke_bpf() if there
> are new flags occur in the feature, which is not convenient, right?
>

I think at some point we should just collect all those different
arguments into a small on-the-stack struct and pass it as an
"invocation parameters" argument. That way we'll have properly named
arguments (struct fields) and we can easily have some defaults
skipped, if necessary. But again, just something for the future to
ponder. Just resubmit your patches as they are right now.

> So what do you think?
>
> Thanks!
> Menglong Dong
>
> >
> > >
> > >
> > > >         u8 *prog = *pprog;
> > > >
> > > >         for (i = 0; i < tl->nr_links; i++) {
> > > > +               if (tl->links[i]->link.prog->call_session_cookie) {
> > > > +                       emit_store_stack_imm64(&prog, BPF_REG_0, -func_meta_off,
> > > > +                                              func_meta | (cur_cookie << BPF_TRAMP_SHIFT_COOKIE));
> > > > +                       cur_cookie--;
> > > > +               }
> > > >                 if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
> > > >                                     run_ctx_off, save_ret, image, rw_image))
> > > >                         return -EINVAL;
> > >
> > > [...]
> >
>
>
>
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-01-22 16:58 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-15 11:22 [PATCH bpf-next v10 00/12] bpf: fsession support Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 01/12] bpf: add " Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 02/12] bpf: use the least significant byte for the nr_args in trampoline Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 03/12] bpf: change prototype of bpf_session_{cookie,is_return} Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 04/12] bpf: support fsession for bpf_session_is_return Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 05/12] bpf: support fsession for bpf_session_cookie Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 06/12] bpf,x86: introduce emit_store_stack_imm64() for trampoline Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 07/12] bpf,x86: add fsession support for x86_64 Menglong Dong
2026-01-22  0:06   ` Andrii Nakryiko
2026-01-22  0:22     ` Andrii Nakryiko
2026-01-22  2:41       ` Menglong Dong
2026-01-22 16:57         ` Andrii Nakryiko
2026-01-15 11:22 ` [PATCH bpf-next v10 08/12] libbpf: add fsession support Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 09/12] bpftool: " Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 10/12] selftests/bpf: add testcases for fsession Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 11/12] selftests/bpf: add testcases for fsession cookie Menglong Dong
2026-01-22  0:07   ` Andrii Nakryiko
2026-01-22  2:18     ` Menglong Dong
2026-01-15 11:22 ` [PATCH bpf-next v10 12/12] selftests/bpf: test fsession mixed with fentry and fexit Menglong Dong
2026-01-22  0:09 ` [PATCH bpf-next v10 00/12] bpf: fsession support Andrii Nakryiko
2026-01-22  2:49   ` Menglong Dong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox