Skip to contentSkip to conversation

bpf, arm64: Add fsession support

PATCH Superseded Leon Hwang 8 participants 18 messages Jan 28 – Jan 30

Subsystems (8)
x86 Kselftest BPF arm64 +4 more subsystems

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Leon Hwang

author
#0 lore raw

v2 cover bpf, arm64: Add fsession support

Similar to commit 98770bd4e6df ("bpf,x86: add fsession support for x86_64"), add fsession support on arm64.

Patch #1 adds bpf_arch_supports_fsession() to prevent fsession loading on architectures that do not implement fsession support.

Patch #2 implements fsession support in the arm64 BPF JIT trampoline.

Patch #3 enables the relevant selftests on arm64, including get_func_ip, and get_func_args.

All enabled tests pass on arm64:

cd tools/testing/selftests/bpf
./test_progs -t fsession

 #135/1   fsession_test/fsession_test:OK
 #135/2   fsession_test/fsession_reattach:OK
 #135/3   fsession_test/fsession_cookie:OK
 #135     fsession_test:OK

Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED

./test_progs -t get_func
#138 get_func_args_test:OK
#139 get_func_ip_test:OK
Summary: 2/0 PASSED, 0 SKIPPED, 0 FAILED

Changes:
v1 -> v2:
* Add bpf_arch_supports_fsession().

Leon Hwang (3):
bpf: Add bpf_arch_supports_fsession()
bpf, arm64: Add fsession support
bpf/selftests: Enable get_func_args and get_func_ip tests on arm64

 arch/arm64/net/bpf_jit_comp.c                 | 71 ++++++++++++++++---
 arch/x86/net/bpf_jit_comp.c                   |  5 ++
 include/linux/bpf.h                           |  7 +-
 include/linux/filter.h                        |  1 +
 kernel/bpf/core.c                             |  5 ++
 kernel/bpf/verifier.c                         |  3 +
 .../selftests/bpf/prog_tests/fsession_test.c  | 32 ++++++---
 .../selftests/bpf/progs/get_func_args_test.c  |  2 +-
 .../selftests/bpf/progs/get_func_ip_test.c    |  2 +-
 9 files changed, 108 insertions(+), 20 deletions(-)

--
2.52.0

author
#1 lore raw

PATCH v2 1/3 bpf: Add bpf_arch_supports_fsession()

fsession programs can currently be loaded on architectures that do not implement fsession support, which leads to runtime errors instead of a clean verifier rejection.

For example, running fsession selftests on arm64 before fsession support is added results in:

test_fsession_basic:PASS:fsession_test__open_and_load 0 nsec test_fsession_basic:PASS:fsession_attach 0 nsec check_result:FAIL:test_run_opts err unexpected error: -14 (errno 14)

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support. Architectures without fsession support will now fail program load with -EOPNOTSUPP, allowing selftests to skip cleanly instead of errors at runtime.

x86 declares fsession support, while the default implementation returns false.

Fixes 2d419c44658f ("bpf: add fsession support")
---
 arch/x86/net/bpf_jit_comp.c                   |  5 +++
 include/linux/filter.h                        |  1 +
 kernel/bpf/core.c                             |  5 +++
 kernel/bpf/verifier.c                         |  3 ++
 .../selftests/bpf/prog_tests/fsession_test.c  | 32 ++++++++++++++-----
 5 files changed, 38 insertions(+), 8 deletions(-)
arch/x86/net/bpf_jit_comp.c +5 -0
index 5a075e06cf45..070ba80e39d7 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
include/linux/filter.h +1 -0
index fd54fed8f95f..4e1cb4f91f49 100644
@@ -1167,6 +1167,7 @@ bool bpf_jit_supports_arena(void);
 bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena);
 bool bpf_jit_supports_private_stack(void);
 bool bpf_jit_supports_timed_may_goto(void);
+bool bpf_jit_supports_fsession(void);
 u64 bpf_arch_uaddress_limit(void);
 void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
 u64 arch_bpf_timed_may_goto(void);
kernel/bpf/core.c +5 -0
index e0b8a8a5aaa9..3b1eb632bf7c 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
 
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}
+
 u64 __weak bpf_arch_uaddress_limit(void)
 {
 #if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
kernel/bpf/verifier.c +3 -0
index c2f2650db9fd..6f867ebf78d1 100644
@@ -24872,6 +24872,9 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
 	case BPF_TRACE_FSESSION:
+		if (prog->expected_attach_type == BPF_TRACE_FSESSION &&
+		    !bpf_jit_supports_fsession())
+			return -EOPNOTSUPP;
 		if (!btf_type_is_func(t)) {
 			bpf_log(log, "attach_btf_id %u is not a function\n",
 				btf_id);
tools/testing/selftests/bpf/prog_tests/fsession_test.c +24 -8
index 0c4b428e1cee..a299aeb8cc2e 100644
@@ -29,8 +29,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	err = fsession_test__attach(skel);
@@ -47,8 +55,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	/* first attach */
@@ -94,6 +110,10 @@ static void test_fsession_cookie(void)
 	bpf_program__set_autoload(skel->progs.test6, false);
 
 	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
 	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
@@ -111,10 +131,6 @@ static void test_fsession_cookie(void)
 
 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"))
Signature · 1 line
2.52.0
#2 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Sorry about the subject.

It should be "bpf: Add bpf_jit_supports_fsession()".

Quoted 148 lines · Leon Hwang

fsession programs can currently be loaded on architectures that do not implement fsession support, which leads to runtime errors instead of a clean verifier rejection.

For example, running fsession selftests on arm64 before fsession support is added results in:

test_fsession_basic:PASS:fsession_test__open_and_load 0 nsec test_fsession_basic:PASS:fsession_attach 0 nsec check_result:FAIL:test_run_opts err unexpected error: -14 (errno 14)

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support. Architectures without fsession support will now fail program load with -EOPNOTSUPP, allowing selftests to skip cleanly instead of errors at runtime.

x86 declares fsession support, while the default implementation returns false.

Fixes 2d419c44658f ("bpf: add fsession support")
---
 arch/x86/net/bpf_jit_comp.c                   |  5 +++
 include/linux/filter.h                        |  1 +
 kernel/bpf/core.c                             |  5 +++
 kernel/bpf/verifier.c                         |  3 ++
 .../selftests/bpf/prog_tests/fsession_test.c  | 32 ++++++++++++++-----
 5 files changed, 38 insertions(+), 8 deletions(-)
arch/x86/net/bpf_jit_comp.c +5 -0
index 5a075e06cf45..070ba80e39d7 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
include/linux/filter.h +1 -0
index fd54fed8f95f..4e1cb4f91f49 100644
@@ -1167,6 +1167,7 @@ bool bpf_jit_supports_arena(void);
 bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena);
 bool bpf_jit_supports_private_stack(void);
 bool bpf_jit_supports_timed_may_goto(void);
+bool bpf_jit_supports_fsession(void);
 u64 bpf_arch_uaddress_limit(void);
 void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
 u64 arch_bpf_timed_may_goto(void);
kernel/bpf/core.c +5 -0
index e0b8a8a5aaa9..3b1eb632bf7c 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
 
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}
+
 u64 __weak bpf_arch_uaddress_limit(void)
 {
 #if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
kernel/bpf/verifier.c +3 -0
index c2f2650db9fd..6f867ebf78d1 100644
@@ -24872,6 +24872,9 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
 	case BPF_TRACE_FSESSION:
+		if (prog->expected_attach_type == BPF_TRACE_FSESSION &&
+		    !bpf_jit_supports_fsession())
+			return -EOPNOTSUPP;
 		if (!btf_type_is_func(t)) {
 			bpf_log(log, "attach_btf_id %u is not a function\n",
 				btf_id);
tools/testing/selftests/bpf/prog_tests/fsession_test.c +24 -8
index 0c4b428e1cee..a299aeb8cc2e 100644
@@ -29,8 +29,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	err = fsession_test__attach(skel);
@@ -47,8 +55,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	/* first attach */
@@ -94,6 +110,10 @@ static void test_fsession_cookie(void)
 	bpf_program__set_autoload(skel->progs.test6, false);
 
 	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
 	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
@@ -111,10 +131,6 @@ static void test_fsession_cookie(void)
 
 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"))
#3 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

In reply to Leon Hwang
This is the actual function name in the code.

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^

This is the actual function name in the code.

Quoted 3 lines
arch/x86/net/bpf_jit_comp.c +3 -0
+{
+	return true;
+}

[ ... ]

kernel/bpf/core.c bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena) · line 3148

Quoted 12 lines
kernel/bpf/core.c +5 -0
index e0b8a8a5aa..3b1eb632bf 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
+
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}

---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21443677441

AI-authorship-score: low
AI-authorship-explanation: The naming inconsistency between commit message and code suggests a human renaming the function during development without updating the commit message, not AI-generated content.
issues-found: 1
issue-severity-score: low
issue-severity-explanation: Documentation-only issue - commit message function name does not match actual code, which may confuse future code archaeology but has no runtime impact.

author
#4 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 11 lines · On 2026/1/28 23:26, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines

This is the actual function name in the code.

There is no issue here.

bpf_jit_supports_fsession() follows the same pattern as other bpf_jit_supports_*() helpers: it is declared in filter.h, provided as a __weak default implementation in core.c, and overridden by individual JIT backends as needed.

Thanks,
Leon

Quoted 31 lines
Quoted 3 lines
arch/x86/net/bpf_jit_comp.c +3 -0
+{
+	return true;
+}

[ ... ]

kernel/bpf/core.c bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena) · line 3148

Quoted 12 lines
kernel/bpf/core.c +5 -0
index e0b8a8a5aa..3b1eb632bf 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
+
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}

---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21443677441

AI-authorship-score: low
AI-authorship-explanation: The naming inconsistency between commit message and code suggests a human renaming the function during development without updating the commit message, not AI-generated content.
issues-found: 1
issue-severity-score: low
issue-severity-explanation: Documentation-only issue - commit message function name does not match actual code, which may confuse future code archaeology but has no runtime impact.

#5 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

In reply to [email protected]
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

commit f636685cc0b05bb758bb58729cc65dde79ac7108
Author: Leon Hwang <[email protected]>

bpf: Add bpf_arch_supports_fsession()

This commit adds architecture-specific gating for fsession programs, returning -EOPNOTSUPP when the architecture does not implement fsession support, instead of failing at runtime with -EFAULT.

Quoted 1 line

bpf: Add bpf_arch_supports_fsession()

The commit subject references bpf_arch_supports_fsession(), but the actual function implemented is named bpf_jit_supports_fsession().

Quoted 2 lines

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support.

Similarly, the commit body describes bpf_arch_supports_fsession(), while the code uses bpf_jit_supports_fsession().

Should the commit message be updated to match the actual function name? The function follows the existing bpf_jit_supports_*() naming convention used by similar functions in the codebase.

-chris

author
#6 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 36 lines · Chris Mason
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

commit f636685cc0b05bb758bb58729cc65dde79ac7108
Author: Leon Hwang <[email protected]>

bpf: Add bpf_arch_supports_fsession()

This commit adds architecture-specific gating for fsession programs, returning -EOPNOTSUPP when the architecture does not implement fsession support, instead of failing at runtime with -EFAULT.

Quoted 1 line

bpf: Add bpf_arch_supports_fsession()

The commit subject references bpf_arch_supports_fsession(), but the actual function implemented is named bpf_jit_supports_fsession().

Quoted 2 lines

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support.

Quoted 7 lines

Similarly, the commit body describes bpf_arch_supports_fsession(), while the code uses bpf_jit_supports_fsession().

Should the commit message be updated to match the actual function name? The function follows the existing bpf_jit_supports_*() naming convention used by similar functions in the codebase.

Correct, in commit message, the function should be bpf_jit_supports_fsession(), too.

Thanks,
Leon

reviewer
#7 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

In reply to Chris Mason
Quoted 16 lines · Chris Mason
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Quoted 2 lines

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

This is the email body pre-processing in KPD, yes.

At some point we decided to remove the commit message before sending an email, but now that AI reviews the messages too, I think we should just send the generated review-inline.txt as is.

Alexei, wdyt?

Quoted 3 lines

[...]

#8 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 21 lines · Ihor Solodrai
Quoted 16 lines · Chris Mason
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
    return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Quoted 2 lines

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

Quoted 7 lines

This is the email body pre-processing in KPD, yes.

At some point we decided to remove the commit message before sending an email, but now that AI reviews the messages too, I think we should just send the generated review-inline.txt as is.

Alexei, wdyt?

I think KPD is only supposed to trim the header until 'diff ..' line. In this case there is no 'diff', so I'm not sure why it trimmed so much.

commit sha...
Author: ...

are useless in email reply, so we should still trim them.

reviewer
#9 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 24 lines · Alexei Starovoitov
Quoted 23 lines · Ihor Solodrai
Quoted 16 lines · Chris Mason
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
    return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Quoted 2 lines

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

This is the email body pre-processing in KPD, yes.

Quoted 8 lines
Quoted 5 lines

At some point we decided to remove the commit message before sending an email, but now that AI reviews the messages too, I think we should just send the generated review-inline.txt as is.

Alexei, wdyt?

I think KPD is only supposed to trim the header until 'diff ..' line. In this case there is no 'diff', so I'm not sure why it trimmed so much.

There is. Here is the PR comment with the review:
https://github.com/kernel-patches/bpf/pull/10868#issuecomment-3811930805

KPD trimmed everything before the first "> diff" occurrence, as expected.

I'll try to fix this up in KPD. We should probably search for the first line starting with "> " (a quote start) to trim the header correctly.

Alternatively, AI can be prompted to avoid generating the header in review-inline.txt, but that's probably less reliable. And maybe it is useful for local runs, idk.

Quoted 5 lines

commit sha...
Author: ...

are useless in email reply, so we should still trim them.

#10 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 38 lines · Ihor Solodrai
Quoted 24 lines · Alexei Starovoitov
Quoted 23 lines · Ihor Solodrai
Quoted 16 lines · Chris Mason
Quoted 11 lines · On 1/28/26 10:26 AM, [email protected] wrote:

arch/x86/net/bpf_jit_comp.c bool bpf_jit_supports_timed_may_goto(void) · line 4116

Quoted 10 lines
arch/x86/net/bpf_jit_comp.c +2 -0
index 5a075e06cf..070ba80e39 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
    return true;
 }
+
+bool bpf_jit_supports_fsession(void)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 1 line

This is the actual function name in the code.

Quoted 2 lines

Ihor, I think the script parsing review-inline.txt chopped off the part of the review where AI was complaining about the commit message?

This is the email body pre-processing in KPD, yes.

Quoted 8 lines
Quoted 5 lines

At some point we decided to remove the commit message before sending an email, but now that AI reviews the messages too, I think we should just send the generated review-inline.txt as is.

Alexei, wdyt?

I think KPD is only supposed to trim the header until 'diff ..' line. In this case there is no 'diff', so I'm not sure why it trimmed so much.

There is. Here is the PR comment with the review:
https://github.com/kernel-patches/bpf/pull/10868#issuecomment-3811930805

Quoted 8 lines

KPD trimmed everything before the first "> diff" occurrence, as expected.

I'll try to fix this up in KPD. We should probably search for the first line starting with "> " (a quote start) to trim the header correctly.

Alternatively, AI can be prompted to avoid generating the header in review-inline.txt, but that's probably less reliable. And maybe it is useful for local runs, idk.

I see. let's then strip the first 4 lines ?
(commit, author, subj) ?

tbh this one was unusual. If it repeats then yeah '> diff' is a wrong marker.

#11 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

In reply to Leon Hwang

On 2026/1/28 23:01 Leon Hwang <[email protected]> write:

Quoted 16 lines

fsession programs can currently be loaded on architectures that do not implement fsession support, which leads to runtime errors instead of a clean verifier rejection.

For example, running fsession selftests on arm64 before fsession support is added results in:

test_fsession_basic:PASS:fsession_test__open_and_load 0 nsec test_fsession_basic:PASS:fsession_attach 0 nsec check_result:FAIL:test_run_opts err unexpected error: -14 (errno 14)

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support. Architectures without fsession support will now fail program load with -EOPNOTSUPP, allowing selftests to skip cleanly instead of errors at runtime.

Quoted 4 lines

x86 declares fsession support, while the default implementation returns false.

Fixes 2d419c44658f ("bpf: add fsession support")

I were wondering how this problem happen, as I remember that I added such checking. When I look back, I found that the checking is lost during v3->v4. I recalled that the AI warned me about this part, but I thought that checking exists in my mind :/

It seems that we can't ignore the AI's warning easily. It mostly make sense.

Quoted 118 lines
---
 arch/x86/net/bpf_jit_comp.c                   |  5 +++
 include/linux/filter.h                        |  1 +
 kernel/bpf/core.c                             |  5 +++
 kernel/bpf/verifier.c                         |  3 ++
 .../selftests/bpf/prog_tests/fsession_test.c  | 32 ++++++++++++++-----
 5 files changed, 38 insertions(+), 8 deletions(-)
arch/x86/net/bpf_jit_comp.c +5 -0
index 5a075e06cf45..070ba80e39d7 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
include/linux/filter.h +1 -0
index fd54fed8f95f..4e1cb4f91f49 100644
@@ -1167,6 +1167,7 @@ bool bpf_jit_supports_arena(void);
 bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena);
 bool bpf_jit_supports_private_stack(void);
 bool bpf_jit_supports_timed_may_goto(void);
+bool bpf_jit_supports_fsession(void);
 u64 bpf_arch_uaddress_limit(void);
 void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
 u64 arch_bpf_timed_may_goto(void);
kernel/bpf/core.c +5 -0
index e0b8a8a5aaa9..3b1eb632bf7c 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
 
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}
+
 u64 __weak bpf_arch_uaddress_limit(void)
 {
 #if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
kernel/bpf/verifier.c +3 -0
index c2f2650db9fd..6f867ebf78d1 100644
@@ -24872,6 +24872,9 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
 	case BPF_TRACE_FSESSION:
+		if (prog->expected_attach_type == BPF_TRACE_FSESSION &&
+		    !bpf_jit_supports_fsession())
+			return -EOPNOTSUPP;
 		if (!btf_type_is_func(t)) {
 			bpf_log(log, "attach_btf_id %u is not a function\n",
 				btf_id);
tools/testing/selftests/bpf/prog_tests/fsession_test.c +24 -4
index 0c4b428e1cee..a299aeb8cc2e 100644
@@ -29,8 +29,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	err = fsession_test__attach(skel);
@@ -47,8 +55,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	/* first attach */
@@ -94,6 +110,10 @@ static void test_fsession_cookie(void)
 	bpf_program__set_autoload(skel->progs.test6, false);
 
 	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
 	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 

tools/testing/selftests/bpf/prog_tests/fsession_test.c static void test_fsession_cookie(void) · line 117

Quoted 7 lines
tools/testing/selftests/bpf/prog_tests/fsession_test.c +0 -4
@@ -111,10 +131,6 @@ static void test_fsession_cookie(void)
 
 void test_fsession_test(void)
 {
-#if !defined(__x86_64__)
-	test__skip();
-	return;
-#endif

Ah, I see you enabled the testing for arm64 in this patch. Maybe we can move this part to the 3rd patch, or split it out to another patch?

TBH, I prefer the previous implement. In this way, the CI can still pass if x86_64 or arm64 return -EOPNOTSUPP, right?

Maybe you can test the not-supported case stand alone, such as:

#if !defined(__x86_64__)
	test__fsession_not_support();
	return;

#endif

wdyt?

Thanks!
Menglong Dong

Quoted 8 lines
tools/testing/selftests/bpf/prog_tests/fsession_test.c +0 -0
 	if (test__start_subtest("fsession_test"))
 		test_fsession_basic();
 	if (test__start_subtest("fsession_reattach"))
Signature · 1 line
2.52.0
author
#12 lore raw

Re: [PATCH bpf-next v2 1/3] bpf: Add bpf_arch_supports_fsession()

Quoted 149 lines · Menglong Dong

On 2026/1/28 23:01 Leon Hwang <[email protected]> write:

Quoted 16 lines

fsession programs can currently be loaded on architectures that do not implement fsession support, which leads to runtime errors instead of a clean verifier rejection.

For example, running fsession selftests on arm64 before fsession support is added results in:

test_fsession_basic:PASS:fsession_test__open_and_load 0 nsec test_fsession_basic:PASS:fsession_attach 0 nsec check_result:FAIL:test_run_opts err unexpected error: -14 (errno 14)

Introduce bpf_arch_supports_fsession() to explicitly gate fsession usage based on architecture support. Architectures without fsession support will now fail program load with -EOPNOTSUPP, allowing selftests to skip cleanly instead of errors at runtime.

Quoted 4 lines

x86 declares fsession support, while the default implementation returns false.

Fixes 2d419c44658f ("bpf: add fsession support")

I were wondering how this problem happen, as I remember that I added such checking. When I look back, I found that the checking is lost during v3->v4. I recalled that the AI warned me about this part, but I thought that checking exists in my mind :/

It seems that we can't ignore the AI's warning easily. It mostly make sense.

Quoted 119 lines
---
 arch/x86/net/bpf_jit_comp.c                   |  5 +++
 include/linux/filter.h                        |  1 +
 kernel/bpf/core.c                             |  5 +++
 kernel/bpf/verifier.c                         |  3 ++
 .../selftests/bpf/prog_tests/fsession_test.c  | 32 ++++++++++++++-----
 5 files changed, 38 insertions(+), 8 deletions(-)
arch/x86/net/bpf_jit_comp.c +5 -0
index 5a075e06cf45..070ba80e39d7 100644
@@ -4112,3 +4112,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
include/linux/filter.h +1 -0
index fd54fed8f95f..4e1cb4f91f49 100644
@@ -1167,6 +1167,7 @@ bool bpf_jit_supports_arena(void);
 bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena);
 bool bpf_jit_supports_private_stack(void);
 bool bpf_jit_supports_timed_may_goto(void);
+bool bpf_jit_supports_fsession(void);
 u64 bpf_arch_uaddress_limit(void);
 void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
 u64 arch_bpf_timed_may_goto(void);
kernel/bpf/core.c +5 -0
index e0b8a8a5aaa9..3b1eb632bf7c 100644
@@ -3142,6 +3142,11 @@ bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
 	return false;
 }
 
+bool __weak bpf_jit_supports_fsession(void)
+{
+	return false;
+}
+
 u64 __weak bpf_arch_uaddress_limit(void)
 {
 #if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
kernel/bpf/verifier.c +3 -0
index c2f2650db9fd..6f867ebf78d1 100644
@@ -24872,6 +24872,9 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
 	case BPF_TRACE_FENTRY:
 	case BPF_TRACE_FEXIT:
 	case BPF_TRACE_FSESSION:
+		if (prog->expected_attach_type == BPF_TRACE_FSESSION &&
+		    !bpf_jit_supports_fsession())
+			return -EOPNOTSUPP;
 		if (!btf_type_is_func(t)) {
 			bpf_log(log, "attach_btf_id %u is not a function\n",
 				btf_id);
tools/testing/selftests/bpf/prog_tests/fsession_test.c +24 -4
index 0c4b428e1cee..a299aeb8cc2e 100644
@@ -29,8 +29,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	err = fsession_test__attach(skel);
@@ -47,8 +55,16 @@ 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"))
+	skel = fsession_test__open();
+	if (!ASSERT_OK_PTR(skel, "fsession_test__open"))
+		return;
+
+	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
+	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
 	/* first attach */
@@ -94,6 +110,10 @@ static void test_fsession_cookie(void)
 	bpf_program__set_autoload(skel->progs.test6, false);
 
 	err = fsession_test__load(skel);
+	if (err == -EOPNOTSUPP) {
+		test__skip();
+		goto cleanup;
+	}
 	if (!ASSERT_OK(err, "fsession_test__load"))
 		goto cleanup;
 
@@ -111,10 +131,6 @@ static void test_fsession_cookie(void)
 
Quoted 8 lines

tools/testing/selftests/bpf/prog_tests/fsession_test.c static void test_fsession_cookie(void) · line 117

Quoted 6 lines
tools/testing/selftests/bpf/prog_tests/fsession_test.c +0 -4
 void test_fsession_test(void)
 {
-#if !defined(__x86_64__)
-	test__skip();
-	return;
-#endif

Ah, I see you enabled the testing for arm64 in this patch. Maybe

The test was not enabled for arm64 in this patch, since bpf_jit_supports_fsession() still returns false there.

The test only becomes enabled when bpf_jit_supports_fsession() returns true, which happens in patch #2.

Quoted 8 lines

we can move this part to the 3rd patch, or split it out to another patch?

Quoted 1 line

TBH, I prefer the previous implement. In this way, the CI can

still pass if x86_64 or arm64 return -EOPNOTSUPP, right?

Maybe you can test the not-supported case stand alone, such as:

Quoted 7 lines
#if !defined(__x86_64__)
	test__fsession_not_support();
	return;

#endif

wdyt?

With this patch, the test now depends on the runtime return value of bpf_jit_supports_fsession() rather than a compile-time #if macro.

This makes the test more extensible: when another architecture (e.g. LoongArch) adds fsession support in the future, it only needs to implement bpf_jit_supports_fsession() in its JIT backend, which will enable the test without touching the test code at the same time.

For architectures that do not support fsession, the existing subtests will be skipped in the same way as before, so a separate '-EOPNOTSUPP'-specific subtest is not necessary.

Thanks,
Leon

author
#13 lore raw

PATCH v2 2/3 bpf, arm64: Add fsession support

In reply to Leon Hwang

Implement fsession support in the arm64 BPF JIT trampoline.

Extend the trampoline stack layout to store function metadata and session cookies, and pass the appropriate metadata to fentry and fexit programs. This mirrors the existing x86 behavior and enables call session cookies on arm64.

---
 arch/arm64/net/bpf_jit_comp.c | 71 ++++++++++++++++++++++++++++++-----
 include/linux/bpf.h           |  7 +++-
 2 files changed, 68 insertions(+), 10 deletions(-)
arch/arm64/net/bpf_jit_comp.c +62 -9
index 0c4d44bcfbf4..952e00e078b2 100644
@@ -2510,6 +2510,12 @@ static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
 		fentry_links->links[0]->link.type == BPF_LINK_TYPE_STRUCT_OPS;
 }
 
+static void store_func_meta(struct jit_ctx *ctx, u64 func_meta, int func_meta_off)
+{
+	emit_a64_mov_i64(A64_R(10), func_meta, ctx);
+	emit(A64_STR64I(A64_R(10), A64_SP, func_meta_off), ctx);
+}
+
 /* Based on the x86's implementation of arch_prepare_bpf_trampoline().
  *
  * bpf prog and function entry before bpf trampoline hooked:
@@ -2533,7 +2539,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 	int regs_off;
 	int retval_off;
 	int bargs_off;
-	int nfuncargs_off;
+	int func_meta_off;
 	int ip_off;
 	int run_ctx_off;
 	int oargs_off;
@@ -2544,6 +2550,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 	bool save_ret;
 	__le32 **branches = NULL;
 	bool is_struct_ops = is_struct_ops_tramp(fentry);
+	int cookie_off, cookie_cnt, cookie_bargs_off;
+	int fsession_cnt = bpf_fsession_cnt(tlinks);
+	u64 func_meta;
 
 	/* trampoline stack layout:
 	 *                    [ parent ip         ]
@@ -2562,10 +2571,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 	 *                    [ ...               ]
 	 * SP + bargs_off     [ arg reg 1         ] for bpf
 	 *
-	 * SP + nfuncargs_off [ arg regs count    ]
+	 * SP + func_meta_off [ regs count, etc   ]
 	 *
 	 * SP + ip_off        [ traced function   ] BPF_TRAMP_F_IP_ARG flag
 	 *
+	 *                    [ stack cookie N    ]
+	 *                    [ ...               ]
+	 * SP + cookie_off    [ stack cookie 1    ]
+	 *
 	 * SP + run_ctx_off   [ bpf_tramp_run_ctx ]
 	 *
 	 *                    [ stack arg N       ]
@@ -2582,13 +2595,18 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 	/* room for bpf_tramp_run_ctx */
 	stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
 
+	cookie_off = stack_size;
+	/* room for session cookies */
+	cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
+	stack_size += cookie_cnt * 8;
+
 	ip_off = stack_size;
 	/* room for IP address argument */
 	if (flags & BPF_TRAMP_F_IP_ARG)
 		stack_size += 8;
 
-	nfuncargs_off = stack_size;
-	/* room for args count */
+	func_meta_off = stack_size;
+	/* room for function metadata, such as regs count */
 	stack_size += 8;
 
 	bargs_off = stack_size;
@@ -2646,9 +2664,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 		emit(A64_STR64I(A64_R(10), A64_SP, ip_off), ctx);
 	}
 
-	/* save arg regs count*/
-	emit(A64_MOVZ(1, A64_R(10), nfuncargs, 0), ctx);
-	emit(A64_STR64I(A64_R(10), A64_SP, nfuncargs_off), ctx);
+	/* save function metadata */
+	func_meta = nfuncargs;
+	store_func_meta(ctx, func_meta, func_meta_off);
 
 	/* save args for bpf */
 	save_args(ctx, bargs_off, oargs_off, m, a, false);
@@ -2666,10 +2684,27 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 		emit_call((const u64)__bpf_tramp_enter, ctx);
 	}
 
-	for (i = 0; i < fentry->nr_links; i++)
+	if (fsession_cnt) {
+		/* clear all the session cookies' value */
+		emit(A64_MOVZ(1, A64_R(10), 0, 0), ctx);
+		for (int i = 0; i < cookie_cnt; i++)
+			emit(A64_STR64I(A64_R(10), A64_SP, cookie_off + 8 * i), ctx);
+		/* clear the return value to make sure fentry always gets 0 */
+		emit(A64_STR64I(A64_R(10), A64_SP, retval_off), ctx);
+	}
+
+	cookie_bargs_off = (bargs_off - cookie_off) / 8;
+	for (i = 0; i < fentry->nr_links; i++) {
+		if (bpf_link_prog_session_cookie(fentry->links[i])) {
+			u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
+
+			store_func_meta(ctx, meta, func_meta_off);
+			cookie_bargs_off--;
+		}
 		invoke_bpf_prog(ctx, fentry->links[i], bargs_off,
 				retval_off, run_ctx_off,
 				flags & BPF_TRAMP_F_RET_FENTRY_RET);
+	}
 
 	if (fmod_ret->nr_links) {
 		branches = kcalloc(fmod_ret->nr_links, sizeof(__le32 *),
@@ -2701,9 +2736,22 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 		*branches[i] = cpu_to_le32(A64_CBNZ(1, A64_R(10), offset));
 	}
 
-	for (i = 0; i < fexit->nr_links; i++)
+	/* set the "is_return" flag for fsession */
+	func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
+	if (fsession_cnt)
+		store_func_meta(ctx, func_meta, func_meta_off);
+
+	cookie_bargs_off = (bargs_off - cookie_off) / 8;
+	for (i = 0; i < fexit->nr_links; i++) {
+		if (bpf_link_prog_session_cookie(fexit->links[i])) {
+			u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
+
+			store_func_meta(ctx, meta, func_meta_off);
+			cookie_bargs_off--;
+		}
 		invoke_bpf_prog(ctx, fexit->links[i], bargs_off, retval_off,
 				run_ctx_off, false);
+	}
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
 		im->ip_epilogue = ctx->ro_image + ctx->idx;
@@ -2753,6 +2801,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
 	return ctx->idx;
 }
 
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
+
 int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
 			     struct bpf_tramp_links *tlinks, void *func_addr)
 {
include/linux/bpf.h +6 -1
index 4427c6e98331..b299d1206bfc 100644
@@ -2192,13 +2192,18 @@ static inline int bpf_fsession_cnt(struct bpf_tramp_links *links)
 	return cnt;
 }
 
+static inline bool bpf_link_prog_session_cookie(struct bpf_tramp_link *link)
+{
+	return link->link.prog->call_session_cookie;
+}
+
 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)
+		if (bpf_link_prog_session_cookie(fentries.links[i]))
 			cnt++;
 	}
 
Signature · 1 line
2.52.0
#14 lore raw

arch/arm64/net/bpf_jit_comp.c static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, · line 2703

Quoted 9 lines · Leon Hwang
arch/arm64/net/bpf_jit_comp.c +8 -0
+       cookie_bargs_off = (bargs_off - cookie_off) / 8;
+       for (i = 0; i < fentry->nr_links; i++) {
+               if (bpf_link_prog_session_cookie(fentry->links[i])) {
+                       u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
+
+                       store_func_meta(ctx, meta, func_meta_off);
+                       cookie_bargs_off--;
+               }

I think the name could use an improvement.

include/linux/bpf.h static inline int bpf_fsession_cnt(struct bpf_tramp_links *links) · line 2198

Quoted 4 lines
include/linux/bpf.h +4 -0
+static inline bool bpf_link_prog_session_cookie(struct bpf_tramp_link *link)
+{
+       return link->link.prog->call_session_cookie;
+}

reading the first hunk without looking at the body isn't trivial.

How about
bpf_prog_calls_session_cookie() ?
Then it's obvious that return is boolean.

pw-bot: cr

author
#15 lore raw

PATCH v2 3/3 bpf/selftests: Enable get_func_args and get_func_ip tests on arm64

In reply to Leon Hwang

Allow get_func_args, and get_func_ip selftests to run on arm64.

---
 tools/testing/selftests/bpf/progs/get_func_args_test.c | 2 +-
 tools/testing/selftests/bpf/progs/get_func_ip_test.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/progs/get_func_args_test.c +1 -1
index 0a3236a7a109..180ba5098ca1 100644
@@ -167,7 +167,7 @@ int BPF_PROG(tp_test2)
 }
 
 __u64 test7_result = 0;
-#ifdef __TARGET_ARCH_x86
+#if defined(bpf_target_x86) || defined(bpf_target_arm64)
 SEC("fsession/bpf_fentry_test1")
 int BPF_PROG(test7)
 {
tools/testing/selftests/bpf/progs/get_func_ip_test.c +1 -1
index 65f7e1f182bf..43ff836a8ed8 100644
@@ -106,7 +106,7 @@ int BPF_URETPROBE(test8, int ret)
 
 __u64 test9_entry_result = 0;
 __u64 test9_exit_result = 0;
-#ifdef __TARGET_ARCH_x86
+#if defined(bpf_target_x86) || defined(bpf_target_arm64)
 SEC("fsession/bpf_fentry_test1")
 int BPF_PROG(test9, int a)
 {
Signature · 1 line
2.52.0
#16 lore raw

Re: [PATCH bpf-next v2 3/3] bpf/selftests: Enable get_func_args and get_func_ip tests on arm64

On 2026/1/28 23:01 Leon Hwang <[email protected]> write:

Quoted 1 line

Allow get_func_args, and get_func_ip selftests to run on arm64.

Hi, Leon.

I think you missed the fsession_test.c, right? You need to enable the test_fsession_test() for arm64 too. Therefore, the title of this patch maybe:
bpf/selftests: Enable fsession tests on arm64

Thanks!
Menglong Dong

Quoted 38 lines
---
 tools/testing/selftests/bpf/progs/get_func_args_test.c | 2 +-
 tools/testing/selftests/bpf/progs/get_func_ip_test.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/progs/get_func_args_test.c +1 -1
index 0a3236a7a109..180ba5098ca1 100644
@@ -167,7 +167,7 @@ int BPF_PROG(tp_test2)
 }
 
 __u64 test7_result = 0;
-#ifdef __TARGET_ARCH_x86
+#if defined(bpf_target_x86) || defined(bpf_target_arm64)
 SEC("fsession/bpf_fentry_test1")
 int BPF_PROG(test7)
 {
tools/testing/selftests/bpf/progs/get_func_ip_test.c +1 -1
index 65f7e1f182bf..43ff836a8ed8 100644
@@ -106,7 +106,7 @@ int BPF_URETPROBE(test8, int ret)
 
 __u64 test9_entry_result = 0;
 __u64 test9_exit_result = 0;
-#ifdef __TARGET_ARCH_x86
+#if defined(bpf_target_x86) || defined(bpf_target_arm64)
 SEC("fsession/bpf_fentry_test1")
 int BPF_PROG(test9, int a)
 {
Signature · 1 line
2.52.0
maintainer Acked-by Tested-by on the v2 series
#17 lore raw
In reply to Leon Hwang
Quoted 22 lines · Leon Hwang

Similar to commit 98770bd4e6df ("bpf,x86: add fsession support for x86_64"), add fsession support on arm64.

Patch #1 adds bpf_arch_supports_fsession() to prevent fsession loading on architectures that do not implement fsession support.

Patch #2 implements fsession support in the arm64 BPF JIT trampoline.

Patch #3 enables the relevant selftests on arm64, including get_func_ip, and get_func_args.

All enabled tests pass on arm64:

cd tools/testing/selftests/bpf
./test_progs -t fsession

 #135/1   fsession_test/fsession_test:OK
 #135/2   fsession_test/fsession_reattach:OK
 #135/3   fsession_test/fsession_cookie:OK
 #135     fsession_test:OK

Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED

Quoted 9 lines

./test_progs -t get_func
#138 get_func_args_test:OK
#139 get_func_ip_test:OK
Summary: 2/0 PASSED, 0 SKIPPED, 0 FAILED

Changes:
v1 -> v2:
* Add bpf_arch_supports_fsession().

Please fix the commit message issue detected by AI and then

For the series: