* [PATCH 0/3] fix BTI exception when execute gotox insturcion
@ 2026-03-06 22:13 Yeoreum Yun
2026-03-06 22:13 ` [PATCH 1/3] bpf: introduce gotox_point in bpf_insn_aux_data Yeoreum Yun
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-06 22:13 UTC (permalink / raw)
To: bpf, linux-kernel, linux-arm-kernel
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, puranjay, xukuohai,
catalin.marinas, will, richardcochran, a.s.protopopov,
Yeoreum Yun
On systems where FEAT_BTI is enabled, running the verifier_gotox testcase
triggers a BTI exception:
[ 257.920598] Internal error: Oops - BTI: 0000000036000003 [#1] SMP
[ 257.920740] Modules linked in:
[ 257.920860] CPU: 4 UID: 0 PID: 239 Comm: test_progs Not tainted 7.0.0-rc2+ #602 PREEMPT(full)
[ 257.921061] Hardware name: , BIOS
[ 257.921160] pstate: 161402c09 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=j-)
[ 257.921337] pc : bpf_prog_0a2b4e44c75a3cb4_jump_table_ok+0x40/0x60
[ 257.921491] lr : bpf_test_run+0x1e8/0x460
[ 257.921639] sp : ffff80008435b7f0
[ 257.921736] x29: ffff80008435b800 x28: ffff80008435b858 x27: ffff80008435b870
[ 257.921991] x26: ffff80008435b7f0 x25: f8ff000803478000 x24: 0000000000000001
[ 257.922243] x23: f0ff8000839bd000 x22: f4ff000801f7f200 x21: ffff80008435b9a4
[ 257.922498] x20: ffff80008435b9a0 x19: 0000000000000000 x18: 0000000000000000
[ 257.922743] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[ 257.922992] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[ 257.923232] x11: 000000000000dd86 x10: 0000000000000000 x9 : ffff8000814f06f0
[ 257.923480] x8 : ffff800083d9d888 x7 : ffff800083d9d8c8 x6 : 0000000000000000
[ 257.923731] x5 : 0000000000000000 x4 : ffff80008435b9a0 x3 : 0000000000000000
[ 257.923976] x2 : 0000000000000000 x1 : f0ff8000839bd060 x0 : f4ff000801f7f200
[ 257.924226] Call trace:
[ 257.924307] bpf_prog_0a2b4e44c75a3cb4_jump_table_ok+0x40/0x60 (P)
[ 257.924481] bpf_test_run+0x1e8/0x460
[ 257.924644] bpf_prog_test_run_skb+0x424/0x708
[ 257.924820] bpf_prog_test_run+0xf4/0x218
[ 257.924978] __sys_bpf+0x3c4/0x498
[ 257.925124] __arm64_sys_bpf+0x30/0x58
[ 257.925312] invoke_syscall+0x68/0xe8
[ 257.925490] el0_svc_common+0x94/0xf8
[ 257.925668] do_el0_svc+0x28/0x48
[ 257.925840] el0_svc+0x40/0x100
[ 257.925998] el0t_64_sync_handler+0x84/0x140
[ 257.926172] el0t_64_sync+0x1bc/0x1c0
[ 257.926359] Code: f28bea07 910020e7 f94000e7 d61f00e0 (d2800027)
[ 257.926489] ---[ end trace 0000000000000000 ]---
[ 257.926612] Kernel panic - not syncing: Oops - BTI: Fatal exception in interrupt
[ 257.926755] SMP: stopping secondary CPUs
[ 257.927208] Kernel Offset: disabled
[ 257.927300] CPU features: 0x0000000,00040f05,dffb65e1,976ff727
[ 257.927437] Memory Limit: none
[ 257.927540] ---[ end Kernel panic - not syncing: Oops - BTI: Fatal exception in interrupt ]---
This occurs because the target of the gotox instruction
(BPF_JMP | BPF_JA | BPF_X) does not begin with a BTI instruction.
To fix this:
PATCH #1-#2 makes verifier deliver "gotox point" to JIT.
PATCH #3 emit a BTI J instrction at the beginning of the gotox
destination.
after this patch verifier_gotox passes without exception:
# ./test_progs -a verifier_gotox
...
#540/1 verifier_gotox/jump_table_ok:OK
#540/2 verifier_gotox/jump_table_reserved_field_src_reg:OK
#540/3 verifier_gotox/jump_table_reserved_field_non_zero_off:OK
#540/4 verifier_gotox/jump_table_reserved_field_non_zero_imm:OK
#540/5 verifier_gotox/jump_table_no_jump_table:OK
#540/6 verifier_gotox/jump_table_incorrect_dst_reg_type:OK
#540/7 verifier_gotox/jump_table_invalid_read_size_u32:OK
#540/8 verifier_gotox/jump_table_invalid_read_size_u16:OK
#540/9 verifier_gotox/jump_table_invalid_read_size_u8:OK
#540/10 verifier_gotox/jump_table_misaligned_access:OK
#540/11 verifier_gotox/jump_table_invalid_mem_acceess_pos:OK
#540/12 verifier_gotox/jump_table_invalid_mem_acceess_neg:OK
#540/13 verifier_gotox/jump_table_add_sub_ok:OK
#540/14 verifier_gotox/jump_table_no_writes:OK
#540/15 verifier_gotox/jump_table_use_reg_r0:OK
#540/16 verifier_gotox/jump_table_use_reg_r1:OK
#540/17 verifier_gotox/jump_table_use_reg_r2:OK
#540/18 verifier_gotox/jump_table_use_reg_r3:OK
#540/19 verifier_gotox/jump_table_use_reg_r4:OK
#540/20 verifier_gotox/jump_table_use_reg_r5:OK
#540/21 verifier_gotox/jump_table_use_reg_r6:OK
#540/22 verifier_gotox/jump_table_use_reg_r7:OK
#540/23 verifier_gotox/jump_table_use_reg_r8:OK
#540/24 verifier_gotox/jump_table_use_reg_r9:OK
#540/25 verifier_gotox/jump_table_outside_subprog:OK
#540/26 verifier_gotox/jump_table_contains_non_unique_values:OK
#540 verifier_gotox:OK
This patch based on v7.0-rc2
Yeoreum Yun (3):
bpf: introduce gotox_point in bpf_insn_aux_data.
bpf: introduce bpf_jit_insn_aux_data
bpf: arm64: fix BTI exception when execute gotox instruction
arch/arm64/net/bpf_jit_comp.c | 15 +++++++++
include/linux/bpf.h | 6 ++++
include/linux/bpf_verifier.h | 3 ++
include/linux/filter.h | 4 +++
kernel/bpf/core.c | 59 ++++++++++++++++++++++++++++++++++-
kernel/bpf/verifier.c | 36 ++++++++++++++++++++-
6 files changed, 121 insertions(+), 2 deletions(-)
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/3] bpf: introduce gotox_point in bpf_insn_aux_data.
2026-03-06 22:13 [PATCH 0/3] fix BTI exception when execute gotox insturcion Yeoreum Yun
@ 2026-03-06 22:13 ` Yeoreum Yun
2026-03-06 22:13 ` [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data Yeoreum Yun
2026-03-06 22:13 ` [PATCH 3/3] bpf: arm64: fix BTI exception when execute gotox instruction Yeoreum Yun
2 siblings, 0 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-06 22:13 UTC (permalink / raw)
To: bpf, linux-kernel, linux-arm-kernel
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, puranjay, xukuohai,
catalin.marinas, will, richardcochran, a.s.protopopov,
Yeoreum Yun
This is preparation patch to fix BTI exception with gotox.
To make JIT know whether instruction is gotox points,
Add gotox_point field in bpf_insn_aux_data.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
include/linux/bpf_verifier.h | 3 +++
kernel/bpf/verifier.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index ef8e45a362d9..92f4c252193e 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -588,6 +588,9 @@ struct bpf_insn_aux_data {
* accepts callback function as a parameter.
*/
bool calls_callback;
+ /* true if instruction is destination of gotox.
+ */
+ bool gotox_point;
/*
* CFG strongly connected component this instruction belongs to,
* zero if it is a singleton SCC.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 401d6c4960ec..bf0281fb5db9 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3973,6 +3973,11 @@ static bool is_jmp_point(struct bpf_verifier_env *env, int insn_idx)
return env->insn_aux_data[insn_idx].jmp_point;
}
+static void mark_gotox_point(struct bpf_verifier_env *env, int idx)
+{
+ env->insn_aux_data[idx].gotox_point = true;
+}
+
#define LR_FRAMENO_BITS 3
#define LR_SPI_BITS 6
#define LR_ENTRY_BITS (LR_SPI_BITS + LR_FRAMENO_BITS + 1)
@@ -18720,6 +18725,7 @@ static int visit_gotox_insn(int t, struct bpf_verifier_env *env)
}
mark_jmp_point(env, w);
+ mark_gotox_point(env, w);
/* EXPLORED || DISCOVERED */
if (insn_state[w])
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data
2026-03-06 22:13 [PATCH 0/3] fix BTI exception when execute gotox insturcion Yeoreum Yun
2026-03-06 22:13 ` [PATCH 1/3] bpf: introduce gotox_point in bpf_insn_aux_data Yeoreum Yun
@ 2026-03-06 22:13 ` Yeoreum Yun
2026-03-06 22:33 ` Alexei Starovoitov
2026-03-06 23:02 ` bot+bpf-ci
2026-03-06 22:13 ` [PATCH 3/3] bpf: arm64: fix BTI exception when execute gotox instruction Yeoreum Yun
2 siblings, 2 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-06 22:13 UTC (permalink / raw)
To: bpf, linux-kernel, linux-arm-kernel
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, puranjay, xukuohai,
catalin.marinas, will, richardcochran, a.s.protopopov,
Yeoreum Yun
This patch prepares for fixing the BTI exception related to gotox.
bpf_jit_insn_aux_data contains per-instruction auxiliary data for the JIT,
extracted from env->insn_aux_data.
For example, it is used to determine whether an instruction is
a destination of a gotox, allowing the JIT to emit
the appropriate BTI instruction at that location in arm64.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
include/linux/bpf.h | 6 +++++
include/linux/filter.h | 4 +++
kernel/bpf/core.c | 59 +++++++++++++++++++++++++++++++++++++++++-
kernel/bpf/verifier.c | 30 ++++++++++++++++++++-
4 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 05b34a6355b0..12fed098ec85 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1606,6 +1606,11 @@ struct bpf_jit_poke_descriptor {
u32 insn_idx;
};
+/* Per-instruction auxiliary data for JIT. */
+struct bpf_jit_insn_aux_data {
+ bool gotox_point;
+};
+
/* reg_type info for ctx arguments */
struct bpf_ctx_arg_aux {
u32 offset;
@@ -1768,6 +1773,7 @@ struct bpf_prog_aux {
struct bpf_stream stream[2];
struct mutex st_ops_assoc_mutex;
struct bpf_map __rcu *st_ops_assoc;
+ struct bpf_jit_insn_aux_data *insn_aux_data;
};
#define BPF_NR_CONTEXTS 4 /* normal, softirq, hardirq, NMI */
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 44d7ae95ddbc..79b18a061cc0 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -38,6 +38,7 @@ struct xdp_buff;
struct sock_reuseport;
struct ctl_table;
struct ctl_table_header;
+struct bpf_insn_aux_data;
/* ArgX, context and stack frame pointer register positions. Note,
* Arg1, Arg2, Arg3, etc are used as argument mappings of function
@@ -1116,6 +1117,9 @@ bool bpf_opcode_in_insntable(u8 code);
void bpf_prog_fill_jited_linfo(struct bpf_prog *prog,
const u32 *insn_to_jit_off);
int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog);
+int bpf_prog_alloc_jit_insn_aux_data(struct bpf_prog *prog);
+void bpf_prog_fill_jit_insn_aux_data(struct bpf_prog *prog,
+ struct bpf_insn_aux_data *insn_aux_data);
void bpf_prog_jit_attempt_done(struct bpf_prog *prog);
struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags);
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 3ece2da55625..32656ef7750e 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -189,8 +189,27 @@ int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog)
return 0;
}
+int bpf_prog_alloc_jit_insn_aux_data(struct bpf_prog *prog)
+{
+ if (!prog->len || !prog->jit_requested)
+ return -EINVAL;
+
+ prog->aux->insn_aux_data = kvzalloc_objs(*prog->aux->insn_aux_data,
+ prog->len,
+ bpf_memcg_flags(GFP_KERNEL | __GFP_NOWARN));
+ if (!prog->aux->insn_aux_data)
+ return -ENOMEM;
+
+ return 0;
+}
+
void bpf_prog_jit_attempt_done(struct bpf_prog *prog)
{
+ if (prog->aux->insn_aux_data) {
+ kvfree(prog->aux->insn_aux_data);
+ prog->aux->insn_aux_data = NULL;
+ }
+
if (prog->aux->jited_linfo &&
(!prog->jited || !prog->aux->jited_linfo[0])) {
kvfree(prog->aux->jited_linfo);
@@ -254,6 +273,20 @@ void bpf_prog_fill_jited_linfo(struct bpf_prog *prog,
insn_to_jit_off[linfo[i].insn_off - insn_start - 1];
}
+void bpf_prog_fill_jit_insn_aux_data(struct bpf_prog *prog,
+ struct bpf_insn_aux_data *insn_aux_data)
+{
+ int i;
+
+ if (!prog->aux->insn_aux_data || !insn_aux_data)
+ return;
+
+ for (i = 0; i < prog->len; i++) {
+ prog->aux->insn_aux_data[i].gotox_point =
+ insn_aux_data[i].gotox_point;
+ }
+}
+
struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
gfp_t gfp_extra_flags)
{
@@ -458,6 +491,7 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
u32 insn_adj_cnt, insn_rest, insn_delta = len - 1;
const u32 cnt_max = S16_MAX;
struct bpf_prog *prog_adj;
+ struct bpf_jit_insn_aux_data *insn_aux_data = NULL;
int err;
/* Since our patchlet doesn't expand the image, we're done. */
@@ -477,14 +511,28 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
(err = bpf_adj_branches(prog, off, off + 1, off + len, true)))
return ERR_PTR(err);
+ if (prog->aux->insn_aux_data) {
+ insn_aux_data = kvzalloc_objs(*prog->aux->insn_aux_data,
+ insn_adj_cnt,
+ bpf_memcg_flags(GFP_KERNEL | __GFP_NOWARN));
+ if (!insn_aux_data)
+ return ERR_PTR(-ENOMEM);
+
+ memcpy(insn_aux_data, prog->aux->insn_aux_data,
+ prog->len * sizeof(*prog->aux->insn_aux_data));
+ }
+
/* Several new instructions need to be inserted. Make room
* for them. Likely, there's no need for a new allocation as
* last page could have large enough tailroom.
*/
prog_adj = bpf_prog_realloc(prog, bpf_prog_size(insn_adj_cnt),
GFP_USER);
- if (!prog_adj)
+ if (!prog_adj) {
+ if (insn_aux_data)
+ kvfree(insn_aux_data);
return ERR_PTR(-ENOMEM);
+ }
prog_adj->len = insn_adj_cnt;
@@ -502,6 +550,15 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
sizeof(*patch) * insn_rest);
memcpy(prog_adj->insnsi + off, patch, sizeof(*patch) * len);
+ if (insn_aux_data) {
+ memmove(insn_aux_data + off + len, insn_aux_data + off + 1,
+ sizeof(*insn_aux_data) * insn_rest);
+ memset(insn_aux_data + off + 1, 0x00,
+ sizeof(*insn_aux_data) * insn_delta);
+ kvfree(prog_adj->aux->insn_aux_data);
+ prog_adj->aux->insn_aux_data = insn_aux_data;
+ }
+
/* We are guaranteed to not fail at this point, otherwise
* the ship has sailed to reverse to the original state. An
* overflow cannot happen at this point.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index bf0281fb5db9..cfc87106aae2 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -22865,6 +22865,12 @@ static int jit_subprogs(struct bpf_verifier_env *env)
func[i]->aux->arena = prog->aux->arena;
func[i]->aux->used_maps = env->used_maps;
func[i]->aux->used_map_cnt = env->used_map_cnt;
+
+ err = bpf_prog_alloc_jit_insn_aux_data(func[i]);
+ if (err)
+ goto out_free;
+ bpf_prog_fill_jit_insn_aux_data(func[i], &env->insn_aux_data[subprog_start]);
+
num_exentries = 0;
insn = func[i]->insnsi;
for (j = 0; j < func[i]->len; j++, insn++) {
@@ -22957,6 +22963,9 @@ static int jit_subprogs(struct bpf_verifier_env *env)
for (i = 0; i < env->subprog_cnt; i++) {
func[i]->aux->used_maps = NULL;
func[i]->aux->used_map_cnt = 0;
+ func[i]->aux->insn_aux_data = NULL;
+ kvfree(func[i]->aux->insn_aux_data);
+ func[i]->aux->insn_aux_data = NULL;
}
/* finally lock prog and jit images for all functions and
@@ -23019,6 +23028,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
if (!func[i])
continue;
func[i]->aux->poke_tab = NULL;
+ if (func[i]->aux->insn_aux_data) {
+ kvfree(func[i]->aux->insn_aux_data);
+ func[i]->aux->insn_aux_data = NULL;;
+ }
bpf_jit_free(func[i]);
}
kfree(func);
@@ -26086,6 +26099,15 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
print_verification_stats(env);
env->prog->aux->verified_insns = env->insn_processed;
+ if (ret == 0 && !env->prog->jited && env->prog->jit_requested &&
+ !bpf_prog_is_offloaded(env->prog->aux)) {
+ /* jit_insn_aux_data will be freed at bpf_prog_select_runtime() */
+ ret = bpf_prog_alloc_jit_insn_aux_data(env->prog);
+ if (ret)
+ goto err_release_maps;
+ bpf_prog_fill_jit_insn_aux_data(env->prog, env->insn_aux_data);
+ }
+
/* preserve original error even if log finalization is successful */
err = bpf_vlog_finalize(&env->log, &log_true_size);
if (err)
@@ -26140,8 +26162,14 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
adjust_btf_func(env);
err_release_maps:
- if (ret)
+ if (ret) {
+ if (env->prog->aux->insn_aux_data) {
+ kvfree(env->prog->aux->insn_aux_data);
+ env->prog->aux->insn_aux_data = NULL;
+ }
+
release_insn_arrays(env);
+ }
if (!env->prog->aux->used_maps)
/* if we didn't copy map pointers into bpf_prog_info, release
* them now. Otherwise free_used_maps() will release them.
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] bpf: arm64: fix BTI exception when execute gotox instruction
2026-03-06 22:13 [PATCH 0/3] fix BTI exception when execute gotox insturcion Yeoreum Yun
2026-03-06 22:13 ` [PATCH 1/3] bpf: introduce gotox_point in bpf_insn_aux_data Yeoreum Yun
2026-03-06 22:13 ` [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data Yeoreum Yun
@ 2026-03-06 22:13 ` Yeoreum Yun
2 siblings, 0 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-06 22:13 UTC (permalink / raw)
To: bpf, linux-kernel, linux-arm-kernel
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, puranjay, xukuohai,
catalin.marinas, will, richardcochran, a.s.protopopov,
Yeoreum Yun
On systems where FEAT_BTI is enabled, running the verifier_gotox testcase
triggers a BTI exception:
[ 257.920598] Internal error: Oops - BTI: 0000000036000003 [#1] SMP
[ 257.920740] Modules linked in:
[ 257.920860] CPU: 4 UID: 0 PID: 239 Comm: test_progs Not tainted 7.0.0-rc2+ #602 PREEMPT(full)
[ 257.921061] Hardware name: , BIOS
[ 257.921160] pstate: 161402c09 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=j-)
[ 257.921337] pc : bpf_prog_0a2b4e44c75a3cb4_jump_table_ok+0x40/0x60
[ 257.921491] lr : bpf_test_run+0x1e8/0x460
[ 257.921639] sp : ffff80008435b7f0
[ 257.921736] x29: ffff80008435b800 x28: ffff80008435b858 x27: ffff80008435b870
[ 257.921991] x26: ffff80008435b7f0 x25: f8ff000803478000 x24: 0000000000000001
[ 257.922243] x23: f0ff8000839bd000 x22: f4ff000801f7f200 x21: ffff80008435b9a4
[ 257.922498] x20: ffff80008435b9a0 x19: 0000000000000000 x18: 0000000000000000
[ 257.922743] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[ 257.922992] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[ 257.923232] x11: 000000000000dd86 x10: 0000000000000000 x9 : ffff8000814f06f0
[ 257.923480] x8 : ffff800083d9d888 x7 : ffff800083d9d8c8 x6 : 0000000000000000
[ 257.923731] x5 : 0000000000000000 x4 : ffff80008435b9a0 x3 : 0000000000000000
[ 257.923976] x2 : 0000000000000000 x1 : f0ff8000839bd060 x0 : f4ff000801f7f200
[ 257.924226] Call trace:
[ 257.924307] bpf_prog_0a2b4e44c75a3cb4_jump_table_ok+0x40/0x60 (P)
[ 257.924481] bpf_test_run+0x1e8/0x460
[ 257.924644] bpf_prog_test_run_skb+0x424/0x708
[ 257.924820] bpf_prog_test_run+0xf4/0x218
[ 257.924978] __sys_bpf+0x3c4/0x498
[ 257.925124] __arm64_sys_bpf+0x30/0x58
[ 257.925312] invoke_syscall+0x68/0xe8
[ 257.925490] el0_svc_common+0x94/0xf8
[ 257.925668] do_el0_svc+0x28/0x48
[ 257.925840] el0_svc+0x40/0x100
[ 257.925998] el0t_64_sync_handler+0x84/0x140
[ 257.926172] el0t_64_sync+0x1bc/0x1c0
[ 257.926359] Code: f28bea07 910020e7 f94000e7 d61f00e0 (d2800027)
[ 257.926489] ---[ end trace 0000000000000000 ]---
[ 257.926612] Kernel panic - not syncing: Oops - BTI: Fatal exception in interrupt
[ 257.926755] SMP: stopping secondary CPUs
[ 257.927208] Kernel Offset: disabled
[ 257.927300] CPU features: 0x0000000,00040f05,dffb65e1,976ff727
[ 257.927437] Memory Limit: none
[ 257.927540] ---[ end Kernel panic - not syncing: Oops - BTI: Fatal exception in interrupt ]---
This occurs because the target of the gotox instruction
(BPF_JMP | BPF_JA | BPF_X) does not begin with a BTI instruction.
To fix this, emit a BTI J instruction at the beginning of
the gotox destination block.
after this patch verifier_gotox passes without exception:
# ./test_progs -a verifier_gotox
...
#540/1 verifier_gotox/jump_table_ok:OK
#540/2 verifier_gotox/jump_table_reserved_field_src_reg:OK
#540/3 verifier_gotox/jump_table_reserved_field_non_zero_off:OK
#540/4 verifier_gotox/jump_table_reserved_field_non_zero_imm:OK
#540/5 verifier_gotox/jump_table_no_jump_table:OK
#540/6 verifier_gotox/jump_table_incorrect_dst_reg_type:OK
#540/7 verifier_gotox/jump_table_invalid_read_size_u32:OK
#540/8 verifier_gotox/jump_table_invalid_read_size_u16:OK
#540/9 verifier_gotox/jump_table_invalid_read_size_u8:OK
#540/10 verifier_gotox/jump_table_misaligned_access:OK
#540/11 verifier_gotox/jump_table_invalid_mem_acceess_pos:OK
#540/12 verifier_gotox/jump_table_invalid_mem_acceess_neg:OK
#540/13 verifier_gotox/jump_table_add_sub_ok:OK
#540/14 verifier_gotox/jump_table_no_writes:OK
#540/15 verifier_gotox/jump_table_use_reg_r0:OK
#540/16 verifier_gotox/jump_table_use_reg_r1:OK
#540/17 verifier_gotox/jump_table_use_reg_r2:OK
#540/18 verifier_gotox/jump_table_use_reg_r3:OK
#540/19 verifier_gotox/jump_table_use_reg_r4:OK
#540/20 verifier_gotox/jump_table_use_reg_r5:OK
#540/21 verifier_gotox/jump_table_use_reg_r6:OK
#540/22 verifier_gotox/jump_table_use_reg_r7:OK
#540/23 verifier_gotox/jump_table_use_reg_r8:OK
#540/24 verifier_gotox/jump_table_use_reg_r9:OK
#540/25 verifier_gotox/jump_table_outside_subprog:OK
#540/26 verifier_gotox/jump_table_contains_non_unique_values:OK
#540 verifier_gotox:OK
Fixes: f4a66cf1cb14 ("bpf: arm64: Add support for indirect jumps")
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
arch/arm64/net/bpf_jit_comp.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index adf84962d579..e54e45b35015 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1223,6 +1223,21 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
int off_adj;
int ret;
bool sign_extend;
+ struct bpf_prog_aux *aux = ctx->prog->aux;
+
+ /*
+ * In some cases, insn_aux_data is not passed,
+ * and it does not need to be. For example, the embedded
+ * program in ptp_classifier_init().
+ * Therefore, we need to check whether insn_aux_data is present.
+ */
+ if (aux->insn_aux_data) {
+ /*
+ * emit BTI J for (BPF_JMP | BPF_X)'s destination.
+ */
+ if (aux->insn_aux_data[i].gotox_point)
+ emit_bti(A64_BTI_J, ctx);
+ }
switch (code) {
/* dst = src */
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data
2026-03-06 22:13 ` [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data Yeoreum Yun
@ 2026-03-06 22:33 ` Alexei Starovoitov
2026-03-06 22:42 ` Yeoreum Yun
2026-03-06 23:02 ` bot+bpf-ci
1 sibling, 1 reply; 8+ messages in thread
From: Alexei Starovoitov @ 2026-03-06 22:33 UTC (permalink / raw)
To: Yeoreum Yun
Cc: bpf, LKML, linux-arm-kernel, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau, Eduard,
Song Liu, Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo,
Jiri Olsa, Puranjay Mohan, Xu Kuohai, Catalin Marinas,
Will Deacon, richardcochran, Anton Protopopov
On Fri, Mar 6, 2026 at 2:13 PM Yeoreum Yun <yeoreum.yun@arm.com> wrote:
>
> This patch prepares for fixing the BTI exception related to gotox.
>
> bpf_jit_insn_aux_data contains per-instruction auxiliary data for the JIT,
> extracted from env->insn_aux_data.
>
> For example, it is used to determine whether an instruction is
> a destination of a gotox, allowing the JIT to emit
> the appropriate BTI instruction at that location in arm64.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
> include/linux/bpf.h | 6 +++++
> include/linux/filter.h | 4 +++
> kernel/bpf/core.c | 59 +++++++++++++++++++++++++++++++++++++++++-
> kernel/bpf/verifier.c | 30 ++++++++++++++++++++-
> 4 files changed, 97 insertions(+), 2 deletions(-)
before posting patches please scan the mailing list to see whether
a particular issue was discussed.
pw-bot: cr
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data
2026-03-06 22:33 ` Alexei Starovoitov
@ 2026-03-06 22:42 ` Yeoreum Yun
0 siblings, 0 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-06 22:42 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, LKML, linux-arm-kernel, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau, Eduard,
Song Liu, Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo,
Jiri Olsa, Puranjay Mohan, Xu Kuohai, Catalin Marinas,
Will Deacon, richardcochran, Anton Protopopov
> On Fri, Mar 6, 2026 at 2:13 PM Yeoreum Yun <yeoreum.yun@arm.com> wrote:
> >
> > This patch prepares for fixing the BTI exception related to gotox.
> >
> > bpf_jit_insn_aux_data contains per-instruction auxiliary data for the JIT,
> > extracted from env->insn_aux_data.
> >
> > For example, it is used to determine whether an instruction is
> > a destination of a gotox, allowing the JIT to emit
> > the appropriate BTI instruction at that location in arm64.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > ---
> > include/linux/bpf.h | 6 +++++
> > include/linux/filter.h | 4 +++
> > kernel/bpf/core.c | 59 +++++++++++++++++++++++++++++++++++++++++-
> > kernel/bpf/verifier.c | 30 ++++++++++++++++++++-
> > 4 files changed, 97 insertions(+), 2 deletions(-)
>
> before posting patches please scan the mailing list to see whether
> a particular issue was discussed.
>
> pw-bot: cr
Oh. I missed Xu Kuohai's patch posted on today.
- https://lore.kernel.org/all/20260306102329.2056216-1-xukuohai@huaweicloud.com/
Thanks.
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data
2026-03-06 22:13 ` [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data Yeoreum Yun
2026-03-06 22:33 ` Alexei Starovoitov
@ 2026-03-06 23:02 ` bot+bpf-ci
2026-03-07 6:22 ` Yeoreum Yun
1 sibling, 1 reply; 8+ messages in thread
From: bot+bpf-ci @ 2026-03-06 23:02 UTC (permalink / raw)
To: yeoreum.yun, bpf, linux-kernel, linux-arm-kernel
Cc: ast, daniel, john.fastabend, andrii, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, jolsa, puranjay, xukuohai,
catalin.marinas, will, richardcochran, a.s.protopopov,
yeoreum.yun, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index d4a73a34c46b..68152dbe9a24 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -23020,6 +23026,9 @@ static int jit_subprogs(struct bpf_verifier_env *env)
> for (i = 0; i < env->subprog_cnt; i++) {
> func[i]->aux->used_maps = NULL;
> func[i]->aux->used_map_cnt = 0;
> + func[i]->aux->insn_aux_data = NULL;
> + kvfree(func[i]->aux->insn_aux_data);
> + func[i]->aux->insn_aux_data = NULL;
> }
Does this leak insn_aux_data for every subprog on the success path?
The pointer is set to NULL before kvfree() is called, so kvfree()
receives NULL and the allocated memory is never freed.
The error path (out_free) has the correct ordering:
> if (func[i]->aux->insn_aux_data) {
> kvfree(func[i]->aux->insn_aux_data);
> func[i]->aux->insn_aux_data = NULL;;
> }
It looks like the success path should match:
kvfree(func[i]->aux->insn_aux_data);
func[i]->aux->insn_aux_data = NULL;
Neither __bpf_prog_free() nor bpf_prog_free_deferred() free
insn_aux_data, so this would be a permanent leak for every
successfully JITed BPF program with multiple subprogs.
Also, there is a double semicolon on the NULL assignment in the
error path above.
---
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/22784798570
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data
2026-03-06 23:02 ` bot+bpf-ci
@ 2026-03-07 6:22 ` Yeoreum Yun
0 siblings, 0 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-03-07 6:22 UTC (permalink / raw)
To: bot+bpf-ci
Cc: bpf, linux-kernel, linux-arm-kernel, ast, daniel, john.fastabend,
andrii, martin.lau, eddyz87, song, yonghong.song, kpsingh, sdf,
haoluo, jolsa, puranjay, xukuohai, catalin.marinas, will,
richardcochran, a.s.protopopov, martin.lau, clm, ihor.solodrai
> > @@ -23020,6 +23026,9 @@ static int jit_subprogs(struct bpf_verifier_env *env)
> > for (i = 0; i < env->subprog_cnt; i++) {
> > func[i]->aux->used_maps = NULL;
> > func[i]->aux->used_map_cnt = 0;
> > + func[i]->aux->insn_aux_data = NULL;
> > + kvfree(func[i]->aux->insn_aux_data);
> > + func[i]->aux->insn_aux_data = NULL;
> > }
Oops. This's my mistake. If i need to send next-version, I'll fix it.
Thanks.
[...]
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-07 6:23 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-06 22:13 [PATCH 0/3] fix BTI exception when execute gotox insturcion Yeoreum Yun
2026-03-06 22:13 ` [PATCH 1/3] bpf: introduce gotox_point in bpf_insn_aux_data Yeoreum Yun
2026-03-06 22:13 ` [PATCH 2/3] bpf: introduce bpf_jit_insn_aux_data Yeoreum Yun
2026-03-06 22:33 ` Alexei Starovoitov
2026-03-06 22:42 ` Yeoreum Yun
2026-03-06 23:02 ` bot+bpf-ci
2026-03-07 6:22 ` Yeoreum Yun
2026-03-06 22:13 ` [PATCH 3/3] bpf: arm64: fix BTI exception when execute gotox instruction Yeoreum Yun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox