* [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
@ 2026-08-05 6:06 ` Saket Kumar Bhaskar
2026-08-05 6:21 ` sashiko-bot
2026-08-06 17:15 ` Hari Bathini
2026-08-05 6:06 ` [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub Saket Kumar Bhaskar
` (6 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:06 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
Ensure the dummy trampoline address field present between the OOL stub
and the long branch stub is 8-byte aligned, for memory compatibility
when content loaded to a register.
Reported-by: Hari Bathini <hbathini@linux.ibm.com>
Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 4 ++--
arch/powerpc/net/bpf_jit_comp.c | 39 +++++++++++++++++++++++++++----
arch/powerpc/net/bpf_jit_comp32.c | 4 ++--
arch/powerpc/net/bpf_jit_comp64.c | 4 ++--
4 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index f32de8704d4d..71e6e7d01057 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -214,8 +214,8 @@ int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context *
int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct codegen_context *ctx,
u32 *addrs, int pass, bool extra_pass);
void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
-void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
-void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx);
+void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx);
+void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx);
void bpf_jit_realloc_regs(struct codegen_context *ctx);
int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr);
void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 7b07b43575f1..42046f73c279 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -49,11 +49,39 @@ asm (
" .popsection ;"
);
-void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
+void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx)
{
int ool_stub_idx, long_branch_stub_idx;
+ int ool_stub_sz;
/*
+ * In the final pass, align the mis-aligned dummy_tramp_addr field
+ * in the fimage. The alignment NOP must appear before OOL stub,
+ * to make ool_stub_idx & long_branch_stub_idx constant from end.
+ *
+ * dummy_tramp_addr must be 8-byte aligned for load-register
+ * compatibility. The fimage can be non 8-byte aligned, so final
+ * alignment depends on start of fimage and the stub's instruction
+ * count offset. The OOL stub size is 4 instructions (with
+ * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 3 instructions (without)
+ * before dummy_tramp_addr.
+ *
+ * Emit a NOP here if (ctx->idx + ool_stub_sz) is odd, so that
+ * dummy_tramp_addr lands at an even instruction offset (== 8-byte
+ * aligned from an 8-byte aligned base).
+ *
+ * In pass=0 when image==NULL, conservatively account for space
+ * required to accommodate alignment NOP. In case final pass skips
+ * emitting alignment NOP, the image buffer have 4 spare bytes and
+ * jited_len signifies correct program size.
+ */
+
+ ool_stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 16 : 12;
+ if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + ool_stub_sz, SZL))
+ EMIT(PPC_RAW_NOP());
+
+ /*
+ * nop // optional, for alignment of dummy_tramp_addr
* Out-of-line stub:
* mflr r0
* [b|bl] tramp
@@ -70,7 +98,7 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
/*
* Long branch stub:
- * .long <dummy_tramp_addr>
+ * .long <dummy_tramp_addr> // 8-byte aligned
* mflr r11
* bcl 20,31,$+4
* mflr r12
@@ -81,6 +109,7 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
*/
if (image)
*((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
+
ctx->idx += SZL / 4;
long_branch_stub_idx = ctx->idx;
EMIT(PPC_RAW_MFLR(_R11));
@@ -107,7 +136,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
PPC_JMP(ctx->alt_exit_addr);
} else {
ctx->alt_exit_addr = ctx->idx * 4;
- bpf_jit_build_epilogue(image, ctx);
+ bpf_jit_build_epilogue(image, NULL, ctx);
}
return 0;
@@ -286,7 +315,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
*/
bpf_jit_build_prologue(NULL, &cgctx);
addrs[fp->len] = cgctx.idx * 4;
- bpf_jit_build_epilogue(NULL, &cgctx);
+ bpf_jit_build_epilogue(NULL, NULL, &cgctx);
fixup_len = fp->aux->num_exentries * BPF_FIXUP_LEN * 4;
extable_len = fp->aux->num_exentries * sizeof(struct exception_table_entry);
@@ -318,7 +347,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
bpf_jit_binary_pack_free(fhdr, hdr);
goto out_err;
}
- bpf_jit_build_epilogue(code_base, &cgctx);
+ bpf_jit_build_epilogue(code_base, fcode_base, &cgctx);
if (bpf_jit_enable > 1)
pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index bfdc50740da8..95bda0dee925 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -229,7 +229,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
}
-void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
+void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx)
{
EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
@@ -237,7 +237,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
EMIT(PPC_RAW_BLR());
- bpf_jit_build_fentry_stubs(image, ctx);
+ bpf_jit_build_fentry_stubs(image, fimage, ctx);
}
/* Relative offset needs to be calculated based on final image location */
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index dab106cae22b..ed78992f4dac 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -398,7 +398,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
}
}
-void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
+void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx)
{
bpf_jit_emit_common_epilogue(image, ctx);
@@ -407,7 +407,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
EMIT(PPC_RAW_BLR());
- bpf_jit_build_fentry_stubs(image, ctx);
+ bpf_jit_build_fentry_stubs(image, fimage, ctx);
}
/*
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
2026-08-05 6:06 ` [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address Saket Kumar Bhaskar
@ 2026-08-05 6:06 ` Saket Kumar Bhaskar
2026-08-06 17:18 ` Hari Bathini
2026-08-05 6:06 ` [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure Saket Kumar Bhaskar
` (5 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:06 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
Move the long branch address field to the bottom of the long
branch stub. This allows uninterrupted disassembly until the
last 8 bytes. The last bytes exclusion is logically necessary to
prevent disassembly failure, otherwise the actual program layout
is never altered. Hence no effect on overall program size.
Also, align dummy_tramp_addr field with 8-byte boundary.
Following is disassembler output for test program with moved down
dummy_tramp_addr field:
.....
.....
pc:68 left:44 a6 03 08 7c : mtlr 0
pc:72 left:40 bc ff ff 4b : b .-68
pc:76 left:36 a6 02 68 7d : mflr 11
pc:80 left:32 05 00 9f 42 : bcl 20, 31, .+4
pc:84 left:28 a6 02 88 7d : mflr 12
pc:88 left:24 14 00 8c e9 : ld 12, 20(12)
pc:92 left:20 a6 03 89 7d : mtctr 12
pc:96 left:16 a6 03 68 7d : mtlr 11
pc:100 left:12 20 04 80 4e : bctr
pc:104 left:8 c0 34 1d 00 :
Failure log:
Can't disasm instruction at offset 104: c0 34 1d 00 00 00 00 c0
Disassembly logic can truncate at 104, ignoring last 8 bytes.
Update the dummy_tramp_addr field offset calculation from the end
of the program to reflect its new location, for bpf_arch_text_poke()
to update the actual trampoline's address in this field.
All BPF trampoline selftests continue to pass with this patch applied.
Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 3 +-
arch/powerpc/net/bpf_jit_comp.c | 51 ++++++++++++++++---------------
arch/powerpc/net/bpf_jit_comp32.c | 3 +-
arch/powerpc/net/bpf_jit_comp64.c | 3 +-
4 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 71e6e7d01057..6632de9871dd 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -217,7 +217,8 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx);
void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx);
void bpf_jit_realloc_regs(struct codegen_context *ctx);
-int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr);
+int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx, int tmp_reg,
+ long exit_addr);
void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
int cookie_off, int retval_off);
void store_func_meta(u32 *image, struct codegen_context *ctx, u64 func_meta, int func_meta_off);
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 42046f73c279..5d559d613f3a 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -52,9 +52,10 @@ asm (
void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx)
{
int ool_stub_idx, long_branch_stub_idx;
- int ool_stub_sz;
+ int stub_sz;
/*
+ * The dummy_tramp_addr field is placed at bottom of Long branch stub.
* In the final pass, align the mis-aligned dummy_tramp_addr field
* in the fimage. The alignment NOP must appear before OOL stub,
* to make ool_stub_idx & long_branch_stub_idx constant from end.
@@ -62,13 +63,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
* dummy_tramp_addr must be 8-byte aligned for load-register
* compatibility. The fimage can be non 8-byte aligned, so final
* alignment depends on start of fimage and the stub's instruction
- * count offset. The OOL stub size is 4 instructions (with
- * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 3 instructions (without)
- * before dummy_tramp_addr.
- *
- * Emit a NOP here if (ctx->idx + ool_stub_sz) is odd, so that
- * dummy_tramp_addr lands at an even instruction offset (== 8-byte
- * aligned from an 8-byte aligned base).
+ * count. The stubs block has 11 instructions (with
+ * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 10 instructions (without)
+ * before dummy_tramp_addr field. Emit a NOP if the address of
+ * dummy_tramp_addr is non aligned.
*
* In pass=0 when image==NULL, conservatively account for space
* required to accommodate alignment NOP. In case final pass skips
@@ -76,8 +74,8 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
* jited_len signifies correct program size.
*/
- ool_stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 16 : 12;
- if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + ool_stub_sz, SZL))
+ stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 44 : 40;
+ if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + stub_sz, SZL))
EMIT(PPC_RAW_NOP());
/*
@@ -98,35 +96,37 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
/*
* Long branch stub:
- * .long <dummy_tramp_addr> // 8-byte aligned
* mflr r11
* bcl 20,31,$+4
- * mflr r12
- * ld r12, -8-SZL(r12)
+ * mflr r12 // lr/r12 stores pc of current(this) inst.
+ * ld r12, 20(r12) // offset(dummy_tramp_addr) from prev inst. is 20
* mtctr r12
- * mtlr r11 // needed to retain ftrace ABI
+ * mtlr r11 // needed to retain ftrace ABI
* bctr
+ * .long <dummy_tramp_addr> // 8-byte aligned
*/
- if (image)
- *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
-
- ctx->idx += SZL / 4;
long_branch_stub_idx = ctx->idx;
EMIT(PPC_RAW_MFLR(_R11));
EMIT(PPC_RAW_BCL4());
EMIT(PPC_RAW_MFLR(_R12));
- EMIT(PPC_RAW_LL(_R12, _R12, -8-SZL));
+ EMIT(PPC_RAW_LL(_R12, _R12, 20));
EMIT(PPC_RAW_MTCTR(_R12));
EMIT(PPC_RAW_MTLR(_R11));
EMIT(PPC_RAW_BCTR());
+ if (image)
+ *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
+
+ ctx->idx += SZL / 4;
+
if (!bpf_jit_ool_stub) {
bpf_jit_ool_stub = (ctx->idx - ool_stub_idx) * 4;
bpf_jit_long_branch_stub = (ctx->idx - long_branch_stub_idx) * 4;
}
}
-int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr)
+int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx,
+ int tmp_reg, long exit_addr)
{
if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
PPC_JMP(exit_addr);
@@ -136,7 +136,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
PPC_JMP(ctx->alt_exit_addr);
} else {
ctx->alt_exit_addr = ctx->idx * 4;
- bpf_jit_build_epilogue(image, NULL, ctx);
+ bpf_jit_build_epilogue(image, fimage, ctx);
}
return 0;
@@ -1294,6 +1294,7 @@ static void do_isync(void *info __maybe_unused)
* bpf_func:
* [nop|b] ool_stub
* 2. Out-of-line stub:
+ * nop // optional nop for alignment
* ool_stub:
* mflr r0
* [b|bl] <bpf_prog>/<long_branch_stub>
@@ -1301,14 +1302,14 @@ static void do_isync(void *info __maybe_unused)
* b bpf_func + 4
* 3. Long branch stub:
* long_branch_stub:
- * .long <branch_addr>/<dummy_tramp>
* mflr r11
* bcl 20,31,$+4
* mflr r12
- * ld r12, -16(r12)
+ * ld r12, 20(r12)
* mtctr r12
* mtlr r11 // needed to retain ftrace ABI
* bctr
+ * .long <branch_addr>/<dummy_tramp>
*
* dummy_tramp is used to reduce synchronization requirements.
*
@@ -1410,10 +1411,12 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
* 1. Update the address in the long branch stub:
* If new_addr is out of range, we will have to use the long branch stub, so patch new_addr
* here. Otherwise, revert to dummy_tramp, but only if we had patched old_addr here.
+ *
+ * dummy_tramp_addr moved to bottom of long branch stub.
*/
if ((new_addr && !is_offset_in_branch_range(new_addr - ip)) ||
(old_addr && !is_offset_in_branch_range(old_addr - ip)))
- ret = patch_ulong((void *)(bpf_func_end - bpf_jit_long_branch_stub - SZL),
+ ret = patch_ulong((void *)(bpf_func_end - SZL), /* SZL: dummy_tramp_addr offset */
(new_addr && !is_offset_in_branch_range(new_addr - ip)) ?
(unsigned long)new_addr : (unsigned long)dummy_tramp);
if (ret)
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
index 95bda0dee925..f5b9441cf46a 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -1149,7 +1149,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* we'll just fall through to the epilogue.
*/
if (i != flen - 1) {
- ret = bpf_jit_emit_exit_insn(image, ctx, _R0, exit_addr);
+ ret = bpf_jit_emit_exit_insn(image, fimage,
+ ctx, _R0, exit_addr);
if (ret)
return ret;
}
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index ed78992f4dac..951eb10ca1f6 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -1737,7 +1737,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
* we'll just fall through to the epilogue.
*/
if (i != flen - 1) {
- ret = bpf_jit_emit_exit_insn(image, ctx, tmp1_reg, exit_addr);
+ ret = bpf_jit_emit_exit_insn(image, fimage, ctx,
+ tmp1_reg, exit_addr);
if (ret)
return ret;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
2026-08-05 6:06 ` [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address Saket Kumar Bhaskar
2026-08-05 6:06 ` [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub Saket Kumar Bhaskar
@ 2026-08-05 6:06 ` Saket Kumar Bhaskar
2026-08-05 7:37 ` bot+bpf-ci
2026-08-06 17:19 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64 Saket Kumar Bhaskar
` (4 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:06 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
Ensure that the trampoline stubs JITed at the tail of the
epilogue do not expose the dummy trampoline address stored
in the last 8 bytes(64-bit) and last 4 bytes(32-bit)
to the disassembly flow. Prevent the disassembler from
ingesting this memory address, as it may occasionally decode
into a seemingly valid but incorrect instruction. Fix this
issue by truncating the last 8/4 bytes from JITed buffers
before supplying them for disassembly.
Fixes: b991fc520700 ("selftests/bpf: utility function to get program disassembly after jit")
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
.../selftests/bpf/jit_disasm_helpers.c | 25 ++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c
index 3558fe10e28c..c4aa1d69d3bb 100644
--- a/tools/testing/selftests/bpf/jit_disasm_helpers.c
+++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c
@@ -179,9 +179,11 @@ int get_jited_program_text(int fd, char *text, size_t text_sz)
struct bpf_prog_info info = {};
__u32 info_len = sizeof(info);
__u32 jited_funcs, len, pc;
+ __u32 trunc_len = 0, disasm_len;
__u32 *func_lens = NULL;
FILE *text_out = NULL;
uint8_t *image = NULL;
+ char *triple = NULL;
int i, err = 0;
if (!llvm_initialized) {
@@ -225,9 +227,30 @@ int get_jited_program_text(int fd, char *text, size_t text_sz)
if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #2"))
goto out;
+ /*
+ * last 8 bytes contains dummy_trampoline address in JIT
+ * output on 64-bit and last 4 bytes on 32-bit powerpc,
+ * which can't disassemble to a valid instruction.
+ */
+ triple = LLVMGetDefaultTargetTriple();
+ if (triple) {
+ if (strstr(triple, "powerpc64") || strstr(triple, "ppc64"))
+ trunc_len = 8;
+ else if (strstr(triple, "powerpc") || strstr(triple, "ppc"))
+ trunc_len = 4;
+ LLVMDisposeMessage(triple);
+ }
+
for (pc = 0, i = 0; i < jited_funcs; ++i) {
+
fprintf(text_out, "func #%d:\n", i);
- disasm_one_func(text_out, image + pc, func_lens[i]);
+ /*
+ * Disabled JIT have zero func_lens, hence underflow
+ */
+ disasm_len = func_lens[i] > trunc_len ?
+ func_lens[i] - trunc_len : 0;
+ disasm_one_func(text_out, image + pc, disasm_len);
+
fprintf(text_out, "\n");
pc += func_lens[i];
}
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
` (2 preceding siblings ...)
2026-08-05 6:06 ` [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure Saket Kumar Bhaskar
@ 2026-08-05 6:07 ` Saket Kumar Bhaskar
2026-08-05 7:07 ` bot+bpf-ci
2026-08-06 17:22 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall Saket Kumar Bhaskar
` (3 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:07 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
This patch enables arch specifier "__powerpc64" in verifier
selftest for ppc64. Power 32-bit would require separate
handling. Changes tested for 64-bit only.
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
tools/testing/selftests/bpf/progs/bpf_misc.h | 1 +
tools/testing/selftests/bpf/test_loader.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
index b0c441384f20..365008d1ed40 100644
--- a/tools/testing/selftests/bpf/progs/bpf_misc.h
+++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
@@ -159,6 +159,7 @@
#define __arch_riscv64 __arch("RISCV64")
#define __arch_s390x __arch("s390x")
#define __arch_loongarch __arch("LOONGARCH")
+#define __arch_powerpc64 __arch("POWERPC64")
#define __caps_unpriv(caps) __test_tag("test_caps_unpriv=" EXPAND_QUOTE(caps))
#define __load_if_JITed() __test_tag("load_mode=jited")
#define __load_if_no_JITed() __test_tag("load_mode=no_jited")
diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c
index 3ce32d134e2c..01b1420097d2 100644
--- a/tools/testing/selftests/bpf/test_loader.c
+++ b/tools/testing/selftests/bpf/test_loader.c
@@ -378,6 +378,7 @@ enum arch {
ARCH_RISCV64 = 0x8,
ARCH_S390X = 0x10,
ARCH_LOONGARCH = 0x20,
+ ARCH_POWERPC64 = 0x40,
};
static int get_current_arch(void)
@@ -392,6 +393,8 @@ static int get_current_arch(void)
return ARCH_S390X;
#elif defined(__loongarch__)
return ARCH_LOONGARCH;
+#elif defined(__powerpc64__)
+ return ARCH_POWERPC64;
#endif
return ARCH_UNKNOWN;
}
@@ -585,6 +588,8 @@ static int parse_test_spec(struct test_loader *tester,
arch = ARCH_S390X;
} else if (strcmp(val, "LOONGARCH") == 0) {
arch = ARCH_LOONGARCH;
+ } else if (strcmp(val, "POWERPC64") == 0) {
+ arch = ARCH_POWERPC64;
} else {
PRINT_FAIL("bad arch spec: '%s'\n", val);
err = -EINVAL;
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
` (3 preceding siblings ...)
2026-08-05 6:07 ` [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64 Saket Kumar Bhaskar
@ 2026-08-05 6:07 ` Saket Kumar Bhaskar
2026-08-06 17:24 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64 Saket Kumar Bhaskar
` (2 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:07 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
The tail_call_info field can contain either a scalar counter
value or a 64-bit pointer to the counter, using a 32-bit
compare (cmplwi) only checks the lower 32 bits, which can lead
to incorrect comparisions when location of counter is near 4GB
boundary. Use instruction cmpldi/cmplwi for accurate comparision
in corresponding cases.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/bpf/20260517191450.85AE6C2BCB8@smtp.kernel.org/
Fixes: 2ed2d8f6fb38 ("powerpc64/bpf: Support tailcalls with subprogs")
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 6 ++++++
arch/powerpc/net/bpf_jit_comp.c | 2 +-
arch/powerpc/net/bpf_jit_comp64.c | 8 ++++----
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 6632de9871dd..af510da12d8e 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -188,6 +188,12 @@ struct codegen_context {
#define bpf_to_ppc(r) (ctx->b2p[r])
+#ifdef CONFIG_PPC64
+#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLDI(a, i)
+#else
+#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLWI(a, i)
+#endif
+
#ifdef CONFIG_PPC32
#define BPF_FIXUP_LEN 3 /* Three instructions => 12 bytes */
#else
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 5d559d613f3a..8be5ded13a4a 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -768,7 +768,7 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_conte
* Setting the tail_call_info in trampoline's frame
* depending on if previous frame had value or reference.
*/
- EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT));
+ EMIT(PPC_RAW_CMPLLI(_R3, MAX_TAIL_CALL_CNT));
PPC_BCC_CONST_SHORT(COND_GT, 8);
EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL));
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
index 951eb10ca1f6..e80312171aa7 100644
--- a/arch/powerpc/net/bpf_jit_comp64.c
+++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -276,7 +276,7 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
*/
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, 0));
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), -(BPF_PPC_TAILCALL)));
- EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+ EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
PPC_BCC_CONST_SHORT(COND_GT, 8);
EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2),
-(BPF_PPC_TAILCALL)));
@@ -662,7 +662,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
PPC_BCC_SHORT(COND_GE, out);
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R1, bpf_jit_stack_tailcallinfo_offset(ctx)));
- EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+ EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
PPC_BCC_CONST_SHORT(COND_LE, 8);
/* dereference TMP_REG_1 */
@@ -672,7 +672,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
* if (tail_call_info == MAX_TAIL_CALL_CNT)
* goto out;
*/
- EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
+ EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
PPC_BCC_SHORT(COND_EQ, out);
/*
@@ -707,7 +707,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
* tail_call_info.
*/
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, bpf_jit_stack_tailcallinfo_offset(ctx)));
- EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
+ EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
PPC_BCC_CONST_SHORT(COND_GT, 8);
/* First get address of tail_call_info */
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
` (4 preceding siblings ...)
2026-08-05 6:07 ` [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall Saket Kumar Bhaskar
@ 2026-08-05 6:07 ` Saket Kumar Bhaskar
2026-08-05 6:14 ` sashiko-bot
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
2026-08-05 6:07 ` [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure Saket Kumar Bhaskar
7 siblings, 1 reply; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:07 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
Verifier testcase result for tailcalls:
Summary: 2/3 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
.../bpf/progs/verifier_tailcall_jit.c | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c b/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
index 48fa34d2959f..7655742f627b 100644
--- a/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
+++ b/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
@@ -91,6 +91,80 @@ __jited(" popq %rax")
__jited(" jmp {{.*}}") /* jump to tail call tgt */
__jited("L0: leave")
__jited(" {{(retq|jmp 0x)}}") /* return or jump to rethunk */
+__arch_powerpc64
+/* program entry for main(), regular function prologue */
+__jited(" nop")
+__jited("...") /* ld 2, 16(13) absent with CONFIG_PPC_KERNEL_PCREL */
+__jited(" li 9, 0")
+__jited(" std 9, -8(1)")
+__jited(" mflr 0")
+__jited(" std 0, 16(1)")
+__jited(" stdu 1, {{.*}}(1)")
+/* load address and call sub() via count register */
+/* Address materialization differs between PCREL and non-PCREL kernels.
+ * Skip the address generation sequence and verify only that the call
+ * target is loaded into CTR before branching.
+ */
+__jited("...")
+__jited("...")
+__jited("...")
+__jited("...")
+__jited("...")
+__jited(" mtctr 12")
+__jited(" bctrl")
+__jited(" mr 8, 3")
+__jited(" li 8, 0")
+__jited(" addi 1, 1, {{.*}}")
+__jited(" ld 0, 16(1)")
+__jited(" mtlr 0")
+__jited(" mr 3, 8")
+__jited(" blr")
+__jited("...")
+__jited("func #1")
+/* subprogram entry for sub() */
+__jited(" nop")
+__jited("...") /* ld 2, 16(13) absent with CONFIG_PPC_KERNEL_PCREL */
+/* tail call prologue for subprogram */
+__jited(" ld 10, 0(1)")
+__jited(" ld 9, -8(10)")
+__jited(" cmpldi 9, 33")
+__jited(" bt {{.*}}, {{.*}}")
+__jited(" addi 9, 10, -8")
+__jited(" std 9, -8(1)")
+__jited(" lis {{.*}}, {{.*}}")
+__jited(" sldi {{.*}}, {{.*}}, 32")
+__jited(" oris {{.*}}, {{.*}}, {{.*}}")
+__jited(" ori {{.*}}, {{.*}}, {{.*}}")
+__jited(" li {{.*}}, 0")
+__jited(" lwz 9, {{.*}}({{.*}})")
+__jited(" slwi {{.*}}, {{.*}}, 0")
+__jited(" cmplw {{.*}}, 9")
+__jited(" bf 0, {{.*}}")
+/* bpf_tail_call implementation */
+__jited(" ld 9, -8(1)")
+__jited(" cmpldi 9, 33")
+__jited(" bf {{.*}}, {{.*}}")
+__jited(" ld 9, 0(9)")
+__jited(" cmpldi 9, 33")
+__jited(" bt {{.*}}, {{.*}}")
+__jited(" addi 9, 9, 1")
+__jited(" mulli 10, {{.*}}, 8")
+__jited(" add 10, 10, {{.*}}")
+__jited(" ld 10, {{.*}}(10)")
+__jited(" cmpldi 10, 0")
+__jited(" bt {{.*}}, {{.*}}")
+__jited(" ld 10, {{.*}}(10)")
+__jited(" addi 10, 10, {{.*}}") /* offset depends on CONFIG_PPC_KERNEL_PCREL */
+__jited(" mtctr 10")
+__jited(" ld 10, -8(1)")
+__jited(" cmpldi 10, 33")
+__jited(" bt {{.*}}, {{.*}}")
+__jited(" addi 10, 1, -8")
+__jited(" std 9, 0(10)")
+__jited(" bctr")
+__jited(" mr 3, 8")
+__jited(" blr")
+
SEC("tc")
__naked int main(void)
{
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
` (5 preceding siblings ...)
2026-08-05 6:07 ` [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64 Saket Kumar Bhaskar
@ 2026-08-05 6:07 ` Saket Kumar Bhaskar
2026-08-05 6:16 ` sashiko-bot
` (2 more replies)
2026-08-05 6:07 ` [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure Saket Kumar Bhaskar
7 siblings, 3 replies; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:07 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
During size calculation in pass-0, exit_addr is 0 since addrs[fp->len]
is not yet populated. bpf_jit_emit_exit_insn() treats a zero exit_addr
as in-range and skips bpf_jit_build_epilogue(), so the alternate inline
epilogue instructions are not counted in alloclen.
In later passes, if the real exit_addr falls outside the 32MB branch
range, the full inline epilogue is emitted into the already-allocated
buffer, writing past its end and corrupting adjacent memory.
Fix by ensuring exit_addr is non-zero before treating it as in-range,
so pass-0 always falls through to bpf_jit_build_epilogue() and
conservatively accounts for all epilogue instructions in alloclen.
Also range check alt_exit_addr directly in the else-if condition.
Since exit_addr handling now falls through to the epilogue, two
related issues in bpf_int_jit_compile() must also be addressed:
1. Reset cgctx.alt_exit_addr before the second size-calculation pass.
Without this, a stale alt_exit_addr from the first pass causes the
second pass to emit a single jump instead of the full epilogue,
undercounting alloclen and reintroducing the overflow.
2. Recompute addrs[fp->len] at the end of each code-generation pass.
The larger pass-0 body can shrink in later passes as out-of-range
exits settle into in-range jumps; a stale addrs[fp->len] would
leave exit branches targeting past the real (shrunken) epilogue.
Because shrinkage in a later pass can move the epilogue offset, the
fixed two-pass loop is no longer sufficient: an exit that was out of
range in an earlier pass may fall in range once the epilogue offset
shrinks, shrinking the body further and overwriting the start of the
epilogue. Convert the code-generation loop to iterate until the
program size converges, bounded by CODEGEN_MAX_PASSES, and fail the
JIT if it does not converge.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
Cc: stable@vger.kernel.org
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Link: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
arch/powerpc/net/bpf_jit.h | 7 +++++++
arch/powerpc/net/bpf_jit_comp.c | 34 +++++++++++++++++++++++++--------
2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index af510da12d8e..4da8bde92e1e 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -14,6 +14,13 @@
#include <asm/ppc-opcode.h>
#include <linux/build_bug.h>
+/*
+ * We need at least 2 passes for proper code generation, and may need
+ * additional passes if code size changes between passes.
+ */
+#define CODEGEN_MIN_PASSES 2
+#define CODEGEN_MAX_PASSES 3
+
#ifdef CONFIG_PPC64_ELF_ABI_V1
#define FUNCTION_DESCR_SIZE 24
#else
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 8be5ded13a4a..3c20bb13cfd7 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -128,11 +128,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx,
int tmp_reg, long exit_addr)
{
- if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
+ if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) {
PPC_JMP(exit_addr);
- } else if (ctx->alt_exit_addr) {
- if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4))))
- return -1;
+ } else if (ctx->alt_exit_addr && is_offset_in_branch_range(
+ (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) {
PPC_JMP(ctx->alt_exit_addr);
} else {
ctx->alt_exit_addr = ctx->idx * 4;
@@ -303,6 +302,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
*/
if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) {
cgctx.idx = 0;
+ cgctx.alt_exit_addr = 0;
if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false))
goto out_err;
}
@@ -335,10 +335,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
code_base = (u32 *)(image + FUNCTION_DESCR_SIZE);
fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE);
- /* Code generation passes 1-2 */
- for (pass = 1; pass < 3; pass++) {
+ /* Code generation passes 1-2+, loop until program size converges. */
+ for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) {
+ u32 prev_proglen = proglen;
+
/* Now build the prologue, body code & epilogue for real. */
cgctx.idx = 0;
+ cgctx.exentry_idx = 0;
cgctx.alt_exit_addr = 0;
bpf_jit_build_prologue(code_base, &cgctx);
if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass,
@@ -347,11 +350,26 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
bpf_jit_binary_pack_free(fhdr, hdr);
goto out_err;
}
+ addrs[fp->len] = cgctx.idx * 4;
bpf_jit_build_epilogue(code_base, fcode_base, &cgctx);
+ proglen = cgctx.idx * 4;
+
if (bpf_jit_enable > 1)
pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
- proglen - (cgctx.idx * 4), cgctx.seen);
+ prev_proglen - proglen, cgctx.seen);
+
+ /* Check if program size has converged, but ensure minimum passes */
+ if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen)
+ break;
+
+ if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) {
+ pr_err("BPF JIT: Program did not converge after %d passes\n",
+ CODEGEN_MAX_PASSES);
+ bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size));
+ bpf_jit_binary_pack_free(fhdr, hdr);
+ goto out_err;
+ }
}
if (bpf_jit_enable > 1)
@@ -428,7 +446,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
u32 *fixup;
/* Populate extable entries only in the last pass */
- if (pass != 2)
+ if (pass >= CODEGEN_MIN_PASSES)
return 0;
if (!fp->aux->extable ||
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
` (6 preceding siblings ...)
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
@ 2026-08-05 6:07 ` Saket Kumar Bhaskar
2026-08-05 6:18 ` sashiko-bot
2026-08-06 17:27 ` Hari Bathini
7 siblings, 2 replies; 23+ messages in thread
From: Saket Kumar Bhaskar @ 2026-08-05 6:07 UTC (permalink / raw)
To: bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99
From: Abhishek Dubey <adubey@linux.ibm.com>
The existing conditional statement in bpf_int_jit_compile() frees the
percpu private stack at out_addrs only when the image buffer was never
allocated.
If bpf_jit_build_body() fails during a code-generation pass, the
image buffer has already been allocated, so !image is false and the
percpu stack is not freed.
Because JIT compilation failed, fp->jited remains at 0. The subsequent
bpf_jit_free() path only frees priv_stack_ptr when fp->jited is set, so
freeing is skipped here too, leaking the percpu allocation.
Fix implements freeing the private stack whenever fp->jited was not set,
i.e. compilation did not succeed, instead of keying off !image. !fp->jited
already covers the !image case, since image is only NULL on early-failure
paths where fp->jited is likewise 0.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/bpf/20260616135426.A06B71F000E9@smtp.kernel.org
Fixes: 156d985123b6 ("powerpc64/bpf: Implement JIT support for private stack")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
---
arch/powerpc/net/bpf_jit_comp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 3c20bb13cfd7..825999f8717b 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -404,7 +404,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
(void *)fimage + FUNCTION_DESCR_SIZE);
out_addrs:
- if (!image && priv_stack_ptr) {
+ if (!fp->jited && priv_stack_ptr) {
fp->aux->priv_stack_ptr = NULL;
free_percpu(priv_stack_ptr);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64
2026-08-05 6:07 ` [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64 Saket Kumar Bhaskar
@ 2026-08-05 6:14 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-08-05 6:14 UTC (permalink / raw)
To: Saket Kumar Bhaskar; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] The patch introduces a multi-line comment that violates the BPF subsystem comment style.
- [Low] Redundant and misleading repetition of `__jited("...")` annotations.
--
--- Patch [6]: [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64 ---
commit 93fe35d1a465f1c1dd05d30ed36bf46603bc5f71
Author: Abhishek Dubey <adubey@linux.ibm.com>
selftest/bpf: Add tailcall verifier selftest for powerpc64
This commit adds a new BPF tailcall verifier JIT selftest for the
powerpc64 architecture. It verifies the emitted JIT instructions for
tail calls, handling differences between PCREL and non-PCREL kernels.
> diff --git a/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c b/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
> index 48fa34d2959f4..7655742f627bc 100644
> --- a/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
> +++ b/tools/testing/selftests/bpf/progs/verifier_tailcall_jit.c
[ ... ]
> @@ -91,6 +91,80 @@ __jited(" popq %rax")
> __jited(" jmp {{.*}}") /* jump to tail call tgt */
> __jited("L0: leave")
> __jited(" {{(retq|jmp 0x)}}") /* return or jump to rethunk */
> +__arch_powerpc64
> +/* program entry for main(), regular function prologue */
> +__jited(" nop")
> +__jited("...") /* ld 2, 16(13) absent with CONFIG_PPC_KERNEL_PCREL */
> +__jited(" li 9, 0")
> +__jited(" std 9, -8(1)")
> +__jited(" mflr 0")
> +__jited(" std 0, 16(1)")
> +__jited(" stdu 1, {{.*}}(1)")
> +/* load address and call sub() via count register */
> +/* Address materialization differs between PCREL and non-PCREL kernels.
> + * Skip the address generation sequence and verify only that the call
> + * target is loaded into CTR before branching.
> + */
[Severity: Low]
This isn't a bug, but does this comment block follow the standard BPF
subsystem comment style?
The subsystem guidelines require multi-line comments to have the opening
characters on a dedicated line, like this:
/*
* Address materialization differs between PCREL and non-PCREL kernels.
* Skip the address generation sequence...
*/
> +__jited("...")
> +__jited("...")
> +__jited("...")
> +__jited("...")
> +__jited("...")
[Severity: Low]
Are these consecutive string annotations redundant?
When test_loader.c parses the "..." string via push_disasm_msg(), it merely
sets the on_next_line flag to false. Repeating it multiple times does not
force the verifier to skip exactly five instructions; it just sets the same
boolean flag repeatedly.
Would a single annotation be sufficient to achieve the desired skip?
> +__jited(" mtctr 12")
> +__jited(" bctrl")
> +__jited(" mr 8, 3")
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1785906979.git.skb99@linux.ibm.com?part=6
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
@ 2026-08-05 6:16 ` sashiko-bot
2026-08-05 7:22 ` bot+bpf-ci
2026-08-06 17:26 ` Hari Bathini
2 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-08-05 6:16 UTC (permalink / raw)
To: Saket Kumar Bhaskar; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Inverted pass condition in `bpf_add_extable_entry()` causes JIT compilation failure and stale exception tables.
--
--- Patch [7]: [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs ---
commit 7c6fc2cfb9f061eb19bae10ea234d06c7a76903c
Author: Abhishek Dubey <adubey@linux.ibm.com>
powerpc/bpf: fix buffer overflow in JIT for large BPF programs
This commit modifies the code-generation loop to iterate until the program size
converges, bounded by CODEGEN_MAX_PASSES, to prevent buffer overflows during JIT
compilation of large BPF programs. It also ensures exit_addr is non-zero before
treating it as in-range and resets alt_exit_addr before subsequent passes.
Link: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 8be5ded13a4a6..3c20bb13cfd70 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
[ ... ]
> @@ -428,7 +446,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
> u32 *fixup;
>
> /* Populate extable entries only in the last pass */
> - if (pass != 2)
> + if (pass >= CODEGEN_MIN_PASSES)
> return 0;
>
> if (!fp->aux->extable ||
[Severity: High]
Does this accidentally invert the logic for populating the exception table?
The comment says to populate extable entries only in the last pass, but returning 0
when pass >= CODEGEN_MIN_PASSES means it will skip the final code generation passes
and instead execute during the early passes.
During the scouting pass 0 in bpf_int_jit_compile(), pass >= CODEGEN_MIN_PASSES
evaluates to false, causing it to fall through. Since the exception table
is not yet allocated at this stage, bpf_add_extable_entry() returns -EINVAL
and unconditionally fails JIT compilation for any BPF program with exceptions.
Additionally, for programs taking the extra_pass path, this would cause the extable
population to be skipped during the final passes. Because instructions can shrink
between passes, this might leave stale extable offsets that point to incorrect
locations, which could trigger a kernel panic during unhandled page faults.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1785906979.git.skb99@linux.ibm.com?part=7
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure
2026-08-05 6:07 ` [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure Saket Kumar Bhaskar
@ 2026-08-05 6:18 ` sashiko-bot
2026-08-06 17:27 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-08-05 6:18 UTC (permalink / raw)
To: Saket Kumar Bhaskar; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Percpu private stack memory is permanently leaked in ARM64 JIT on compilation error paths.
--
--- Patch [8]: [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure ---
commit 04e1b164f2198ac765746ea52f6d89ebc5ed346a
Author: Abhishek Dubey <adubey@linux.ibm.com>
powerpc64/bpf: fix percpu private stack leak on JIT failure
This commit fixes a percpu memory leak in the powerpc64 BPF JIT compiler.
It ensures the private stack is properly freed on error paths by checking
if compilation succeeded, rather than relying on whether the image buffer
was allocated.
Closes: https://lore.kernel.org/bpf/20260616135426.A06B71F000E9@smtp.kernel.org
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 3c20bb13cfd70..825999f8717bd 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -404,7 +404,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> (void *)fimage + FUNCTION_DESCR_SIZE);
>
> out_addrs:
> - if (!image && priv_stack_ptr) {
> + if (!fp->jited && priv_stack_ptr) {
> fp->aux->priv_stack_ptr = NULL;
> free_percpu(priv_stack_ptr);
> }
[Severity: High]
This is a pre-existing issue, but does a similar memory leak exist in the
ARM64 BPF JIT error path?
Looking at bpf_int_jit_compile() in arch/arm64/net/bpf_jit_comp.c:
out_free_hdr:
...
if (header) {
bpf_arch_text_copy(&ro_header->size, &header->size,
sizeof(header->size));
bpf_jit_binary_pack_free(ro_header, header);
}
goto out_off;
out_off:
if (!ro_header && priv_stack_ptr) {
free_percpu(priv_stack_ptr);
prog->aux->priv_stack_ptr = NULL;
}
If the code jumps to out_free_hdr, ro_header is freed but not set to NULL.
When execution proceeds to out_off, the !ro_header check will evaluate to false.
Since prog->jited is also set to 0 on these error paths, bpf_jit_free() will
skip freeing the private stack as well.
Could this allow a user to deliberately trigger JIT failures (for example,
by hitting limits during passes) to repeatedly leak percpu memory and
exhaust the allocator?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1785906979.git.skb99@linux.ibm.com?part=8
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address
2026-08-05 6:06 ` [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address Saket Kumar Bhaskar
@ 2026-08-05 6:21 ` sashiko-bot
2026-08-06 17:15 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-08-05 6:21 UTC (permalink / raw)
To: Saket Kumar Bhaskar; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Passing `NULL` for `fimage` in `bpf_jit_emit_exit_insn()` causes incorrect alignment calculations for alternate epilogues, leading to an unaligned 8-byte memory store during JIT compilation and misaligned runtime addresses.
--
--- Patch [1]: [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address ---
commit 4bc0d2265cceaf063f46ec43f44292e01148338a
Author: Abhishek Dubey <adubey@linux.ibm.com>
powerpc/bpf: fix alignment of long branch trampoline address
This commit attempts to fix the alignment of the dummy trampoline address
field between the out-of-line stub and the long branch stub. It introduces a
NOP padding instruction to ensure the address is 8-byte aligned for
load-register compatibility. It also passes fimage through the epilogue and
fentry stub building functions to calculate the correct alignment.
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 7b07b43575f11..42046f73c2792 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -49,11 +49,39 @@ asm (
> " .popsection ;"
> );
>
> -void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
> +void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx)
> {
[ ... ]
> + ool_stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 16 : 12;
> + if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + ool_stub_sz, SZL))
> + EMIT(PPC_RAW_NOP());
> +
[ ... ]
> @@ -81,6 +109,7 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
> */
> if (image)
> *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
> +
> ctx->idx += SZL / 4;
> long_branch_stub_idx = ctx->idx;
> EMIT(PPC_RAW_MFLR(_R11));
[ ... ]
> @@ -107,7 +136,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
> PPC_JMP(ctx->alt_exit_addr);
> } else {
> ctx->alt_exit_addr = ctx->idx * 4;
> - bpf_jit_build_epilogue(image, ctx);
> + bpf_jit_build_epilogue(image, NULL, ctx);
> }
>
> return 0;
[Severity: High]
Does passing NULL for fimage here cause incorrect alignment calculations for
alternate epilogues?
Since bpf_jit_emit_exit_insn() passes NULL to bpf_jit_build_epilogue(), the
fimage argument eventually passed to bpf_jit_build_fentry_stubs() will be NULL.
This means the IS_ALIGNED() check in bpf_jit_build_fentry_stubs() will evaluate
alignment relative to 0 instead of the actual fcode_base.
Because the executable memory allocated by bpf_jit_binary_pack_alloc() only
guarantees 4-byte alignment, the real fimage base might not be 8-byte aligned.
If the NOP calculation evaluates 0 instead of a 4-byte aligned base, it can
incorrectly omit the padding, leading to an unaligned 64-bit store when writing
dummy_tramp:
if (image)
*((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
Performing a 64-bit store to a misaligned pointer is undefined behavior in C
and can trigger alignment exceptions. Will this also cause the ld instruction
to load from a misaligned address at runtime, defeating the patch's goal of
load-register compatibility?
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1785906979.git.skb99@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64
2026-08-05 6:07 ` [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64 Saket Kumar Bhaskar
@ 2026-08-05 7:07 ` bot+bpf-ci
2026-08-06 17:22 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: bot+bpf-ci @ 2026-08-05 7:07 UTC (permalink / raw)
To: skb99, bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99, ast, andrii, daniel,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2637 bytes --]
> selftest/bpf: Enable verifier selftest for powerpc64
>
> This patch enables arch specifier "__powerpc64" in verifier
> selftest for ppc64. Power 32-bit would require separate
> handling. Changes tested for 64-bit only.
This isn't a bug, but would it read more precisely to name the new tag
as __arch_powerpc64 (matching the macro added in bpf_misc.h) rather
than "__powerpc64"? The actual macro expands to __arch("POWERPC64"),
and "__powerpc64__" is the compiler predefine used in test_loader.c,
but there's no __powerpc64 tag itself.
Also, would phrasing it imperatively match the series style better?
For example, "Add __arch_powerpc64 so verifier tests can gate on ppc64"
instead of "This patch enables..."?
> diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
> index 5eacf1b432521..c35359c97e44b 100644
> --- a/tools/testing/selftests/bpf/progs/bpf_misc.h
> +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
> @@ -159,6 +159,7 @@
> #define __arch_riscv64 __arch("RISCV64")
> #define __arch_s390x __arch("s390x")
> #define __arch_loongarch __arch("LOONGARCH")
> +#define __arch_powerpc64 __arch("POWERPC64")
> #define __caps_unpriv(caps) __test_tag("test_caps_unpriv=" EXPAND_QUOTE(caps))
> #define __load_if_JITed() __test_tag("load_mode=jited")
> #define __load_if_no_JITed() __test_tag("load_mode=no_jited")
> diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c
> index 07807757b518d..221393f2a8ef4 100644
> --- a/tools/testing/selftests/bpf/test_loader.c
> +++ b/tools/testing/selftests/bpf/test_loader.c
> @@ -378,6 +378,7 @@ enum arch {
> ARCH_RISCV64 = 0x8,
> ARCH_S390X = 0x10,
> ARCH_LOONGARCH = 0x20,
> + ARCH_POWERPC64 = 0x40,
> };
>
> static int get_current_arch(void)
> @@ -392,6 +393,8 @@ static int get_current_arch(void)
> return ARCH_S390X;
> #elif defined(__loongarch__)
> return ARCH_LOONGARCH;
> +#elif defined(__powerpc64__)
> + return ARCH_POWERPC64;
> #endif
> return ARCH_UNKNOWN;
> }
> @@ -585,6 +588,8 @@ static int parse_test_spec(struct test_loader *tester,
> arch = ARCH_S390X;
> } else if (strcmp(val, "LOONGARCH") == 0) {
> arch = ARCH_LOONGARCH;
> + } else if (strcmp(val, "POWERPC64") == 0) {
> + arch = ARCH_POWERPC64;
> } else {
> PRINT_FAIL("bad arch spec: '%s'\n", val);
> err = -EINVAL;
---
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/30981212698
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
2026-08-05 6:16 ` sashiko-bot
@ 2026-08-05 7:22 ` bot+bpf-ci
2026-08-06 17:26 ` Hari Bathini
2 siblings, 0 replies; 23+ messages in thread
From: bot+bpf-ci @ 2026-08-05 7:22 UTC (permalink / raw)
To: skb99, bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99, ast, andrii, daniel,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 8592 bytes --]
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index af510da12d8ed..4da8bde92e1ef 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -14,6 +14,13 @@
> #include <asm/ppc-opcode.h>
> #include <linux/build_bug.h>
>
> +/*
> + * We need at least 2 passes for proper code generation, and may need
> + * additional passes if code size changes between passes.
> + */
> +#define CODEGEN_MIN_PASSES 2
> +#define CODEGEN_MAX_PASSES 3
> +
> #ifdef CONFIG_PPC64_ELF_ABI_V1
> #define FUNCTION_DESCR_SIZE 24
> #else
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 8be5ded13a4a6..3c20bb13cfd70 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -128,11 +128,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
> int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx,
> int tmp_reg, long exit_addr)
> {
> - if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
> + if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) {
> PPC_JMP(exit_addr);
> - } else if (ctx->alt_exit_addr) {
> - if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4))))
> - return -1;
> + } else if (ctx->alt_exit_addr && is_offset_in_branch_range(
> + (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) {
> PPC_JMP(ctx->alt_exit_addr);
> } else {
> ctx->alt_exit_addr = ctx->idx * 4;
> @@ -303,6 +302,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> */
> if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) {
> cgctx.idx = 0;
> + cgctx.alt_exit_addr = 0;
> if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false))
> goto out_err;
> }
> @@ -335,10 +335,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> code_base = (u32 *)(image + FUNCTION_DESCR_SIZE);
> fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE);
>
> - /* Code generation passes 1-2 */
> - for (pass = 1; pass < 3; pass++) {
> + /* Code generation passes 1-2+, loop until program size converges. */
> + for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) {
> + u32 prev_proglen = proglen;
> +
> /* Now build the prologue, body code & epilogue for real. */
> cgctx.idx = 0;
> + cgctx.exentry_idx = 0;
> cgctx.alt_exit_addr = 0;
> bpf_jit_build_prologue(code_base, &cgctx);
> if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass,
> @@ -347,11 +350,26 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> bpf_jit_binary_pack_free(fhdr, hdr);
> goto out_err;
> }
> + addrs[fp->len] = cgctx.idx * 4;
> bpf_jit_build_epilogue(code_base, fcode_base, &cgctx);
>
> + proglen = cgctx.idx * 4;
> +
> if (bpf_jit_enable > 1)
> pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
> - proglen - (cgctx.idx * 4), cgctx.seen);
> + prev_proglen - proglen, cgctx.seen);
> +
> + /* Check if program size has converged, but ensure minimum passes */
> + if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen)
> + break;
> +
> + if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) {
> + pr_err("BPF JIT: Program did not converge after %d passes\n",
> + CODEGEN_MAX_PASSES);
> + bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size));
> + bpf_jit_binary_pack_free(fhdr, hdr);
> + goto out_err;
> + }
With CODEGEN_MAX_PASSES set to 3, the convergence loop only allows a
single retry after the mandatory two passes. Is this sufficient margin
for the cascading shrinkage described in the commit message?
The changelog states that when the epilogue offset moves, an exit that
was out of range can fall in range, shrinking the body and potentially
triggering a chain reaction. That pattern can need more than one settling
iteration for a large program. Other architectures allow significantly
more headroom for this exact scenario: riscv and parisc use
NR_JIT_ITERATIONS (default 16), sparc64 uses 40 passes, x86 uses
MAX_PASSES (20), and mips uses JIT_MAX_ITERATIONS (32).
The tight bound has two concrete effects:
1. A program that would eventually converge can now fail the JIT hard.
The old two-pass code did not check convergence at all, so a program
that needs four settling iterations to fully cascade would have been
JITed with pass 2 output. Now it gets -ENOTSUPP. On a
CONFIG_BPF_JIT_ALWAYS_ON or bpf_jit_enable=2 kernel, that is a
verifier rejection at load time, not a silent fallback to interpreter.
2. Each pass walks the entire program without preemption. x86 and sparc64
both call cond_resched() in their codegen loops. A large program will
burn a full pass with preemption unchanged, and with only three passes
allowed there is no headroom to add resched points.
For comparison, x86's codegen loop:
kernel/bpf/core.c:bpf_int_jit_compile() {
for (pass = 0; pass < MAX_PASSES || image; pass++) {
...
cond_resched();
}
}
Would raising CODEGEN_MAX_PASSES to a value with real headroom (perhaps
matching NR_JIT_ITERATIONS at 16, or 20 to match x86) and adding
cond_resched() address these concerns?
> }
>
> if (bpf_jit_enable > 1)
> @@ -428,7 +446,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
> u32 *fixup;
>
> /* Populate extable entries only in the last pass */
> - if (pass != 2)
> + if (pass >= CODEGEN_MIN_PASSES)
> return 0;
Is this comparison inverted? The old predicate was `if (pass != 2)
return 0;` with the fixed two-pass loop `for (pass = 1; pass < 3;
pass++)`, which populated entries only when pass == 2, the final pass.
The new code is `if (pass >= CODEGEN_MIN_PASSES) return 0;` with
CODEGEN_MIN_PASSES == 2, which returns early for pass 2 and pass 3 and
populates entries only when pass == 1. That is the exact inverse, and
contradicts the retained comment "Populate extable entries only in the
last pass."
The correct predicate for "not the last pass" in the new convergence loop
would be `if (pass < CODEGEN_MIN_PASSES) return 0;`, or a last-pass flag,
not `pass >= CODEGEN_MIN_PASSES`.
Two concrete consequences from populating during pass 1 instead of the
final pass:
1. Stale extable contents. Entries are written during pass 1 using pass-1
offsets. The whole point of this patch is that the body can shrink
between passes (an out-of-range exit settling into an in-range jump),
so pass 2/3 instruction addresses differ from pass 1.
bpf_add_extable_entry() records deltas derived from absolute addresses:
kernel/bpf/verifier.c:bpf_add_extable_entry() {
pc = (unsigned long)&image[insn_idx];
offset = pc - (long)&ex_entry->insn;
ex_entry->insn = offset;
fixup[BPF_FIXUP_LEN - 1] = PPC_RAW_BRANCH(
(long)(pc + jmp_off) - (long)&fixup[BPF_FIXUP_LEN - 1]);
}
Because cgctx.exentry_idx is now reset at the top of every pass
(CHANGE-3), and pass 2+ returns early, nothing rewrites these entries
after the layout changes.
search_bpf_extables() in kernel/bpf/core.c then resolves a faulting
PROBE_MEM access to the wrong insn address, and the recorded fixup
branch jumps to a stale offset. For a program whose size changes
between pass 1 and the final pass, that is a wild branch from the fault
fixup path in kernel context.
2. Interaction with extra_pass for subprogs. On the skip_init_ctx path,
the comment at arch/powerpc/net/bpf_jit_comp.c:259 states:
/* During extra pass, ensure index is reset before repopulating
extable entries */
The design intent is that the extra pass repopulates the extable. With
the new predicate, the extra pass enters the loop at pass == 1 and does
populate. But any later iteration of the same loop (pass 2, which is
always executed because CODEGEN_MIN_PASSES == 2 gates the early break)
will not. That leaves the extable describing whichever pass wrote last
(pass 1) while the final emitted code is from pass 2. The comment and
the code now disagree in every configuration.
Would inverting the test to `if (pass < CODEGEN_MIN_PASSES) return 0;`
fix this?
---
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/30981212698
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure
2026-08-05 6:06 ` [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure Saket Kumar Bhaskar
@ 2026-08-05 7:37 ` bot+bpf-ci
2026-08-06 17:19 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: bot+bpf-ci @ 2026-08-05 7:37 UTC (permalink / raw)
To: skb99, bpf, linuxppc-dev
Cc: hbathini, maddy, ast, andrii, daniel, shuah, linux-kselftest,
stable, venkat88, yeswanth, skb99, ast, andrii, daniel,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 6138 bytes --]
> selftest/bpf: Fixing powerpc JIT disassembly failure
>
> Ensure that the trampoline stubs JITed at the tail of the
> epilogue do not expose the dummy trampoline address stored
> in the last 8 bytes(64-bit) and last 4 bytes(32-bit)
> to the disassembly flow. Prevent the disassembler from
> ingesting this memory address, as it may occasionally decode
> into a seemingly valid but incorrect instruction. Fix this
> issue by truncating the last 8/4 bytes from JITed buffers
> before supplying them for disassembly.
>
> Fixes: b991fc520700 ("selftests/bpf: utility function to get program disassembly after jit")
The Fixes: tag names b991fc520700 ("selftests/bpf: utility function to get
program disassembly after jit", 2024-08-21), which is the commit that
introduced get_jited_program_text() itself. That helper was not wrong when
written: at that time no powerpc JIT emitted a raw data word inside a
program, and the helper is documented (jit_disasm_helpers.c:13) as serving
small assembly test programs.
The undisassemblable trailing bytes come from d243b62b7bd3 ("powerpc64/bpf:
Add support for bpf trampolines", 2024-10-31) - the same commit both
sibling patches in this series cite - and only become observable once
powerpc jited selftests are enabled, which happens later in this series in
d3841599dc7ca ("selftest/bpf: Enable verifier selftest for powerpc64").
More importantly, the fix as written is only correct on top of its
immediate parent. Truncating the last trunc_len bytes assumes
dummy_tramp_addr is the final thing in the JITed image. That layout is
established by the immediate parent c6ba4edfe6e46 ("powerpc/bpf: Move out
dummy_tramp_addr after Long branch stub"), which moved the data word from
the top of the long branch stub to its bottom:
arch/powerpc/net/bpf_jit_comp.c:bpf_jit_build_fentry_stubs() {
...
long_branch_stub_idx = ctx->idx;
EMIT(PPC_RAW_MFLR(_R11));
...
EMIT(PPC_RAW_BCTR());
if (image)
*((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
ctx->idx += SZL / 4;
}
On any tree that has b991fc520700 but not c6ba4edfe6e46, dummy_tramp_addr
sits before the seven long-branch instructions, so trimming the tail
removes two real instructions (bctr and mtlr r11 on 64-bit) while leaving
the data word in the middle of the disassembled range - the disassembly
failure this patch targets is not fixed, and expected __jited() output is
silently altered.
A backport driven by the stated Fixes: tag alone would therefore land a
change that does not work. Should the tag point at the commit that
introduced the byte pattern (d243b62b7bd3), or should the dependency on
c6ba4edfe6e46 be stated explicitly in the changelog?
> diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c
> index 3558fe10e28cf..c4aa1d69d3bbf 100644
> --- a/tools/testing/selftests/bpf/jit_disasm_helpers.c
> +++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c
[ ... ]
> @@ -225,9 +227,30 @@ int get_jited_program_text(int fd, char *text, size_t text_sz)
> if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #2"))
> goto out;
>
> + /*
> + * last 8 bytes contains dummy_trampoline address in JIT
> + * output on 64-bit and last 4 bytes on 32-bit powerpc,
> + * which can't disassemble to a valid instruction.
> + */
This isn't a bug, but the comment says the trailing bytes "can't
disassemble to a valid instruction", while the changelog for the same
change says the opposite - "it may occasionally decode into a seemingly
valid but incorrect instruction" - which is the case that actually
motivates unconditional truncation rather than tolerating a disasm
failure.
The comment also names the field "dummy_trampoline", whereas the arch code
calls the symbol "dummy_tramp" and the field "dummy_tramp_addr"
(arch/powerpc/net/bpf_jit_comp.c:118), so grepping from the comment does
not lead to the code.
Separately, the second added comment, "Disabled JIT have zero func_lens,
hence underflow", is a sentence fragment that leaves the reader to infer
that the ternary exists to avoid a __u32 wrap when func_lens[i] is 0.
Could this comment use the "dummy_tramp_addr" name from the arch code and
describe the failure the same way the changelog does, so the two do not
read as contradictory?
> + triple = LLVMGetDefaultTargetTriple();
> + if (triple) {
> + if (strstr(triple, "powerpc64") || strstr(triple, "ppc64"))
> + trunc_len = 8;
> + else if (strstr(triple, "powerpc") || strstr(triple, "ppc"))
> + trunc_len = 4;
> + LLVMDisposeMessage(triple);
> + }
> +
> for (pc = 0, i = 0; i < jited_funcs; ++i) {
> +
> fprintf(text_out, "func #%d:\n", i);
[ ... ]
> +
> fprintf(text_out, "\n");
> pc += func_lens[i];
> }
This isn't a bug, but two blank lines are added inside the loop body that
are unrelated to the fix: one immediately after the "for (...) {" opening
brace, and one between the disasm_one_func() call and the following
fprintf(). Neither separates logical blocks - the loop body is six lines -
and no other loop in this file opens with a blank line (compare the two
"while (pc < len)" loops in disasm_one_func(), which start directly with
their first statement).
Are the two new blank lines inside this loop intentional, or could the
hunk stay limited to the truncation change?
> selftest/bpf: Fixing powerpc JIT disassembly failure
This isn't a bug, but the subject uses the prefix "selftest/bpf:"
(singular) where the tree's overwhelmingly dominant prefix for this
directory is "selftests/bpf:" - 1272 commits versus 10 in recent history.
The subject also uses the gerund "Fixing" rather than the imperative mood
the submitting-patches guidance asks for ("Fix ..." / "Skip ...").
Would "selftests/bpf: Skip trailing trampoline address bytes when
disassembling" fit the usual prefix and imperative style for this
directory better?
---
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/30981212698
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address
2026-08-05 6:06 ` [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address Saket Kumar Bhaskar
2026-08-05 6:21 ` sashiko-bot
@ 2026-08-06 17:15 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:15 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:36 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> Ensure the dummy trampoline address field present between the OOL stub
> and the long branch stub is 8-byte aligned, for memory compatibility
> when content loaded to a register.
This fix is not complete. With 2/8 it looks complete. Some part
of it needs to be in this patch instead..
>
> Reported-by: Hari Bathini <hbathini@linux.ibm.com>
> Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
> Cc: stable@vger.kernel.org
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> arch/powerpc/net/bpf_jit.h | 4 ++--
> arch/powerpc/net/bpf_jit_comp.c | 39 +++++++++++++++++++++++++++----
> arch/powerpc/net/bpf_jit_comp32.c | 4 ++--
> arch/powerpc/net/bpf_jit_comp64.c | 4 ++--
> 4 files changed, 40 insertions(+), 11 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index f32de8704d4d..71e6e7d01057 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -214,8 +214,8 @@ int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context *
> int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct codegen_context *ctx,
> u32 *addrs, int pass, bool extra_pass);
> void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
> -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
> -void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx);
> +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx);
> +void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx);
> void bpf_jit_realloc_regs(struct codegen_context *ctx);
> int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr);
> void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 7b07b43575f1..42046f73c279 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -49,11 +49,39 @@ asm (
> " .popsection ;"
> );
>
> -void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
> +void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx)
> {
> int ool_stub_idx, long_branch_stub_idx;
> + int ool_stub_sz;
>
> /*
> + * In the final pass, align the mis-aligned dummy_tramp_addr field
> + * in the fimage. The alignment NOP must appear before OOL stub,
> + * to make ool_stub_idx & long_branch_stub_idx constant from end.
> + *
> + * dummy_tramp_addr must be 8-byte aligned for load-register
> + * compatibility. The fimage can be non 8-byte aligned, so final
> + * alignment depends on start of fimage and the stub's instruction
> + * count offset. The OOL stub size is 4 instructions (with
> + * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 3 instructions (without)
> + * before dummy_tramp_addr.
> + *
> + * Emit a NOP here if (ctx->idx + ool_stub_sz) is odd, so that
> + * dummy_tramp_addr lands at an even instruction offset (== 8-byte
> + * aligned from an 8-byte aligned base).
> + *
> + * In pass=0 when image==NULL, conservatively account for space
> + * required to accommodate alignment NOP. In case final pass skips
> + * emitting alignment NOP, the image buffer have 4 spare bytes and
> + * jited_len signifies correct program size.
> + */
> +
> + ool_stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 16 : 12;
> + if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + ool_stub_sz, SZL))
> + EMIT(PPC_RAW_NOP());
> +
> + /*
> + * nop // optional, for alignment of dummy_tramp_addr
> * Out-of-line stub:
> * mflr r0
> * [b|bl] tramp
> @@ -70,7 +98,7 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
>
> /*
> * Long branch stub:
> - * .long <dummy_tramp_addr>
> + * .long <dummy_tramp_addr> // 8-byte aligned
> * mflr r11
> * bcl 20,31,$+4
> * mflr r12
> @@ -81,6 +109,7 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
> */
> if (image)
> *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
> +
> ctx->idx += SZL / 4;
> long_branch_stub_idx = ctx->idx;
> EMIT(PPC_RAW_MFLR(_R11));
> @@ -107,7 +136,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
> PPC_JMP(ctx->alt_exit_addr);
> } else {
> ctx->alt_exit_addr = ctx->idx * 4;
> - bpf_jit_build_epilogue(image, ctx);
> + bpf_jit_build_epilogue(image, NULL, ctx);
> }
>
> return 0;
> @@ -286,7 +315,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> */
> bpf_jit_build_prologue(NULL, &cgctx);
> addrs[fp->len] = cgctx.idx * 4;
> - bpf_jit_build_epilogue(NULL, &cgctx);
> + bpf_jit_build_epilogue(NULL, NULL, &cgctx);
>
> fixup_len = fp->aux->num_exentries * BPF_FIXUP_LEN * 4;
> extable_len = fp->aux->num_exentries * sizeof(struct exception_table_entry);
> @@ -318,7 +347,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> bpf_jit_binary_pack_free(fhdr, hdr);
> goto out_err;
> }
> - bpf_jit_build_epilogue(code_base, &cgctx);
> + bpf_jit_build_epilogue(code_base, fcode_base, &cgctx);
>
> if (bpf_jit_enable > 1)
> pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index bfdc50740da8..95bda0dee925 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -229,7 +229,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
>
> }
>
> -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
> +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx)
> {
> EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0)));
>
> @@ -237,7 +237,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
>
> EMIT(PPC_RAW_BLR());
>
> - bpf_jit_build_fentry_stubs(image, ctx);
> + bpf_jit_build_fentry_stubs(image, fimage, ctx);
> }
>
> /* Relative offset needs to be calculated based on final image location */
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index dab106cae22b..ed78992f4dac 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -398,7 +398,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
> }
> }
>
> -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
> +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx)
> {
> bpf_jit_emit_common_epilogue(image, ctx);
>
> @@ -407,7 +407,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
>
> EMIT(PPC_RAW_BLR());
>
> - bpf_jit_build_fentry_stubs(image, ctx);
> + bpf_jit_build_fentry_stubs(image, fimage, ctx);
> }
>
> /*
- Hari
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub
2026-08-05 6:06 ` [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub Saket Kumar Bhaskar
@ 2026-08-06 17:18 ` Hari Bathini
0 siblings, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:18 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:36 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> Move the long branch address field to the bottom of the long
> branch stub. This allows uninterrupted disassembly until the
> last 8 bytes. The last bytes exclusion is logically necessary to
Instead of "last 8 bytes", should be "last 4/8 bytes"
> prevent disassembly failure, otherwise the actual program layout
> is never altered. Hence no effect on overall program size.
> Also, align dummy_tramp_addr field with 8-byte boundary.
>
> Following is disassembler output for test program with moved down
> dummy_tramp_addr field:
> .....
> .....
> pc:68 left:44 a6 03 08 7c : mtlr 0
> pc:72 left:40 bc ff ff 4b : b .-68
> pc:76 left:36 a6 02 68 7d : mflr 11
> pc:80 left:32 05 00 9f 42 : bcl 20, 31, .+4
> pc:84 left:28 a6 02 88 7d : mflr 12
> pc:88 left:24 14 00 8c e9 : ld 12, 20(12)
> pc:92 left:20 a6 03 89 7d : mtctr 12
> pc:96 left:16 a6 03 68 7d : mtlr 11
> pc:100 left:12 20 04 80 4e : bctr
> pc:104 left:8 c0 34 1d 00 :
>
> Failure log:
> Can't disasm instruction at offset 104: c0 34 1d 00 00 00 00 c0
> Disassembly logic can truncate at 104, ignoring last 8 bytes.
>
> Update the dummy_tramp_addr field offset calculation from the end
> of the program to reflect its new location, for bpf_arch_text_poke()
> to update the actual trampoline's address in this field.
>
> All BPF trampoline selftests continue to pass with this patch applied.
>
> Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> arch/powerpc/net/bpf_jit.h | 3 +-
> arch/powerpc/net/bpf_jit_comp.c | 51 ++++++++++++++++---------------
> arch/powerpc/net/bpf_jit_comp32.c | 3 +-
> arch/powerpc/net/bpf_jit_comp64.c | 3 +-
> 4 files changed, 33 insertions(+), 27 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 71e6e7d01057..6632de9871dd 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -217,7 +217,8 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx);
> void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx);
> void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx);
> void bpf_jit_realloc_regs(struct codegen_context *ctx);
> -int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr);
> +int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx, int tmp_reg,
> + long exit_addr);
This function prototype change, the corresponding call site updates
& the second parameter update in bpf_jit_build_epilogue() call
inside bpf_jit_emit_exit_insn() function belong in the previous patch...
> void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
> int cookie_off, int retval_off);
> void store_func_meta(u32 *image, struct codegen_context *ctx, u64 func_meta, int func_meta_off);
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 42046f73c279..5d559d613f3a 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -52,9 +52,10 @@ asm (
> void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx)
> {
> int ool_stub_idx, long_branch_stub_idx;
> - int ool_stub_sz;
> + int stub_sz;
>
> /*
> + * The dummy_tramp_addr field is placed at bottom of Long branch stub.
> * In the final pass, align the mis-aligned dummy_tramp_addr field
> * in the fimage. The alignment NOP must appear before OOL stub,
> * to make ool_stub_idx & long_branch_stub_idx constant from end.
> @@ -62,13 +63,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
> * dummy_tramp_addr must be 8-byte aligned for load-register
> * compatibility. The fimage can be non 8-byte aligned, so final
> * alignment depends on start of fimage and the stub's instruction
> - * count offset. The OOL stub size is 4 instructions (with
> - * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 3 instructions (without)
> - * before dummy_tramp_addr.
> - *
> - * Emit a NOP here if (ctx->idx + ool_stub_sz) is odd, so that
> - * dummy_tramp_addr lands at an even instruction offset (== 8-byte
> - * aligned from an 8-byte aligned base).
> + * count. The stubs block has 11 instructions (with
> + * CONFIG_PPC_FTRACE_OUT_OF_LINE) or 10 instructions (without)
> + * before dummy_tramp_addr field. Emit a NOP if the address of
> + * dummy_tramp_addr is non aligned.
> *
> * In pass=0 when image==NULL, conservatively account for space
> * required to accommodate alignment NOP. In case final pass skips
> @@ -76,8 +74,8 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
> * jited_len signifies correct program size.
> */
>
> - ool_stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 16 : 12;
> - if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + ool_stub_sz, SZL))
> + stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 44 : 40;
> + if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + stub_sz, SZL))
> EMIT(PPC_RAW_NOP());
>
> /*
> @@ -98,35 +96,37 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
>
> /*
> * Long branch stub:
> - * .long <dummy_tramp_addr> // 8-byte aligned
> * mflr r11
> * bcl 20,31,$+4
> - * mflr r12
> - * ld r12, -8-SZL(r12)
> + * mflr r12 // lr/r12 stores pc of current(this) inst.
> + * ld r12, 20(r12) // offset(dummy_tramp_addr) from prev inst. is 20
> * mtctr r12
> - * mtlr r11 // needed to retain ftrace ABI
> + * mtlr r11 // needed to retain ftrace ABI
> * bctr
> + * .long <dummy_tramp_addr> // 8-byte aligned
Likewise, the comment should be:
"SZL bytes aligned"
> */
> - if (image)
> - *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
> -
> - ctx->idx += SZL / 4;
> long_branch_stub_idx = ctx->idx;
> EMIT(PPC_RAW_MFLR(_R11));
> EMIT(PPC_RAW_BCL4());
> EMIT(PPC_RAW_MFLR(_R12));
> - EMIT(PPC_RAW_LL(_R12, _R12, -8-SZL));
> + EMIT(PPC_RAW_LL(_R12, _R12, 20));
> EMIT(PPC_RAW_MTCTR(_R12));
> EMIT(PPC_RAW_MTLR(_R11));
> EMIT(PPC_RAW_BCTR());
>
> + if (image)
> + *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp;
> +
> + ctx->idx += SZL / 4;
> +
> if (!bpf_jit_ool_stub) {
> bpf_jit_ool_stub = (ctx->idx - ool_stub_idx) * 4;
> bpf_jit_long_branch_stub = (ctx->idx - long_branch_stub_idx) * 4;
> }
> }
>
> -int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr)
> +int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx,
> + int tmp_reg, long exit_addr)
> {
> if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
> PPC_JMP(exit_addr);
> @@ -136,7 +136,7 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg,
> PPC_JMP(ctx->alt_exit_addr);
> } else {
> ctx->alt_exit_addr = ctx->idx * 4;
> - bpf_jit_build_epilogue(image, NULL, ctx);
> + bpf_jit_build_epilogue(image, fimage, ctx);
> }
>
> return 0;
> @@ -1294,6 +1294,7 @@ static void do_isync(void *info __maybe_unused)
> * bpf_func:
> * [nop|b] ool_stub
> * 2. Out-of-line stub:
> + * nop // optional nop for alignment
> * ool_stub:
> * mflr r0
> * [b|bl] <bpf_prog>/<long_branch_stub>
> @@ -1301,14 +1302,14 @@ static void do_isync(void *info __maybe_unused)
> * b bpf_func + 4
> * 3. Long branch stub:
> * long_branch_stub:
> - * .long <branch_addr>/<dummy_tramp>
> * mflr r11
> * bcl 20,31,$+4
> * mflr r12
> - * ld r12, -16(r12)
> + * ld r12, 20(r12)
> * mtctr r12
> * mtlr r11 // needed to retain ftrace ABI
> * bctr
> + * .long <branch_addr>/<dummy_tramp>
> *
> * dummy_tramp is used to reduce synchronization requirements.
> *
> @@ -1410,10 +1411,12 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
> * 1. Update the address in the long branch stub:
> * If new_addr is out of range, we will have to use the long branch stub, so patch new_addr
> * here. Otherwise, revert to dummy_tramp, but only if we had patched old_addr here.
> + *
> + * dummy_tramp_addr moved to bottom of long branch stub.
> */
> if ((new_addr && !is_offset_in_branch_range(new_addr - ip)) ||
> (old_addr && !is_offset_in_branch_range(old_addr - ip)))
> - ret = patch_ulong((void *)(bpf_func_end - bpf_jit_long_branch_stub - SZL),
> + ret = patch_ulong((void *)(bpf_func_end - SZL), /* SZL: dummy_tramp_addr offset */
> (new_addr && !is_offset_in_branch_range(new_addr - ip)) ?
> (unsigned long)new_addr : (unsigned long)dummy_tramp);
> if (ret)
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index 95bda0dee925..f5b9441cf46a 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -1149,7 +1149,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
> * we'll just fall through to the epilogue.
> */
> if (i != flen - 1) {
> - ret = bpf_jit_emit_exit_insn(image, ctx, _R0, exit_addr);
> + ret = bpf_jit_emit_exit_insn(image, fimage,
> + ctx, _R0, exit_addr);
> if (ret)
> return ret;
> }
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index ed78992f4dac..951eb10ca1f6 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -1737,7 +1737,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
> * we'll just fall through to the epilogue.
> */
> if (i != flen - 1) {
> - ret = bpf_jit_emit_exit_insn(image, ctx, tmp1_reg, exit_addr);
> + ret = bpf_jit_emit_exit_insn(image, fimage, ctx,
> + tmp1_reg, exit_addr);
> if (ret)
> return ret;
> }
- Hari
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure
2026-08-05 6:06 ` [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure Saket Kumar Bhaskar
2026-08-05 7:37 ` bot+bpf-ci
@ 2026-08-06 17:19 ` Hari Bathini
2026-08-06 17:20 ` Hari Bathini
1 sibling, 1 reply; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:19 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:36 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> Ensure that the trampoline stubs JITed at the tail of the
> epilogue do not expose the dummy trampoline address stored
> in the last 8 bytes(64-bit) and last 4 bytes(32-bit)
> to the disassembly flow. Prevent the disassembler from
> ingesting this memory address, as it may occasionally decode
> into a seemingly valid but incorrect instruction. Fix this
> issue by truncating the last 8/4 bytes from JITed buffers
> before supplying them for disassembly.
>
> Fixes: b991fc520700 ("selftests/bpf: utility function to get program disassembly after jit")
The fixes tag on this patch doesn't really help. Please drop it.
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> .../selftests/bpf/jit_disasm_helpers.c | 25 ++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c
> index 3558fe10e28c..c4aa1d69d3bb 100644
> --- a/tools/testing/selftests/bpf/jit_disasm_helpers.c
> +++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c
> @@ -179,9 +179,11 @@ int get_jited_program_text(int fd, char *text, size_t text_sz)
> struct bpf_prog_info info = {};
> __u32 info_len = sizeof(info);
> __u32 jited_funcs, len, pc;
> + __u32 trunc_len = 0, disasm_len;
> __u32 *func_lens = NULL;
> FILE *text_out = NULL;
> uint8_t *image = NULL;
> + char *triple = NULL;
> int i, err = 0;
>
> if (!llvm_initialized) {
> @@ -225,9 +227,30 @@ int get_jited_program_text(int fd, char *text, size_t text_sz)
> if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #2"))
> goto out;
>
> + /*
> + * last 8 bytes contains dummy_trampoline address in JIT
> + * output on 64-bit and last 4 bytes on 32-bit powerpc,
> + * which can't disassemble to a valid instruction.
> + */
> + triple = LLVMGetDefaultTargetTriple();
> + if (triple) {
> + if (strstr(triple, "powerpc64") || strstr(triple, "ppc64"))
> + trunc_len = 8;
> + else if (strstr(triple, "powerpc") || strstr(triple, "ppc"))
> + trunc_len = 4;
> + LLVMDisposeMessage(triple);
> + }
> +
> for (pc = 0, i = 0; i < jited_funcs; ++i) {
> +
> fprintf(text_out, "func #%d:\n", i);
> - disasm_one_func(text_out, image + pc, func_lens[i]);
> + /*
> + * Disabled JIT have zero func_lens, hence underflow
> + */
> + disasm_len = func_lens[i] > trunc_len ?
> + func_lens[i] - trunc_len : 0;
> + disasm_one_func(text_out, image + pc, disasm_len);
> +
> fprintf(text_out, "\n");
> pc += func_lens[i];
> }
- Hari
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure
2026-08-06 17:19 ` Hari Bathini
@ 2026-08-06 17:20 ` Hari Bathini
0 siblings, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:20 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 06/08/26 10:49 pm, Hari Bathini wrote:
>
>
> On 05/08/26 11:36 am, Saket Kumar Bhaskar wrote:
>> From: Abhishek Dubey <adubey@linux.ibm.com>
>>
>> Ensure that the trampoline stubs JITed at the tail of the
>> epilogue do not expose the dummy trampoline address stored
>> in the last 8 bytes(64-bit) and last 4 bytes(32-bit)
>> to the disassembly flow. Prevent the disassembler from
>> ingesting this memory address, as it may occasionally decode
>> into a seemingly valid but incorrect instruction. Fix this
>> issue by truncating the last 8/4 bytes from JITed buffers
>> before supplying them for disassembly.
>
>>
>> Fixes: b991fc520700 ("selftests/bpf: utility function to get program
>> disassembly after jit")
>
> The fixes tag on this patch doesn't really help. Please drop it.
With that..
Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
>
>> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
>> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
>> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
>> ---
>> .../selftests/bpf/jit_disasm_helpers.c | 25 ++++++++++++++++++-
>> 1 file changed, 24 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/
>> testing/selftests/bpf/jit_disasm_helpers.c
>> index 3558fe10e28c..c4aa1d69d3bb 100644
>> --- a/tools/testing/selftests/bpf/jit_disasm_helpers.c
>> +++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c
>> @@ -179,9 +179,11 @@ int get_jited_program_text(int fd, char *text,
>> size_t text_sz)
>> struct bpf_prog_info info = {};
>> __u32 info_len = sizeof(info);
>> __u32 jited_funcs, len, pc;
>> + __u32 trunc_len = 0, disasm_len;
>> __u32 *func_lens = NULL;
>> FILE *text_out = NULL;
>> uint8_t *image = NULL;
>> + char *triple = NULL;
>> int i, err = 0;
>> if (!llvm_initialized) {
>> @@ -225,9 +227,30 @@ int get_jited_program_text(int fd, char *text,
>> size_t text_sz)
>> if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd #2"))
>> goto out;
>> + /*
>> + * last 8 bytes contains dummy_trampoline address in JIT
>> + * output on 64-bit and last 4 bytes on 32-bit powerpc,
>> + * which can't disassemble to a valid instruction.
>> + */
>> + triple = LLVMGetDefaultTargetTriple();
>> + if (triple) {
>> + if (strstr(triple, "powerpc64") || strstr(triple, "ppc64"))
>> + trunc_len = 8;
>> + else if (strstr(triple, "powerpc") || strstr(triple, "ppc"))
>> + trunc_len = 4;
>> + LLVMDisposeMessage(triple);
>> + }
>> +
>> for (pc = 0, i = 0; i < jited_funcs; ++i) {
>> +
>> fprintf(text_out, "func #%d:\n", i);
>> - disasm_one_func(text_out, image + pc, func_lens[i]);
>> + /*
>> + * Disabled JIT have zero func_lens, hence underflow
>> + */
>> + disasm_len = func_lens[i] > trunc_len ?
>> + func_lens[i] - trunc_len : 0;
>> + disasm_one_func(text_out, image + pc, disasm_len);
>> +
>> fprintf(text_out, "\n");
>> pc += func_lens[i];
>> }
>
> - Hari
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64
2026-08-05 6:07 ` [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64 Saket Kumar Bhaskar
2026-08-05 7:07 ` bot+bpf-ci
@ 2026-08-06 17:22 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:22 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:37 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> This patch enables arch specifier "__powerpc64" in verifier
s/This patch enables arch specifier "__powerpc64" in/Enable
"__arch_powerpc64" specifier in/
> selftest for ppc64. Power 32-bit would require separate
> handling. Changes tested for 64-bit only.
>
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> tools/testing/selftests/bpf/progs/bpf_misc.h | 1 +
> tools/testing/selftests/bpf/test_loader.c | 5 +++++
> 2 files changed, 6 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
> index b0c441384f20..365008d1ed40 100644
> --- a/tools/testing/selftests/bpf/progs/bpf_misc.h
> +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
> @@ -159,6 +159,7 @@
> #define __arch_riscv64 __arch("RISCV64")
> #define __arch_s390x __arch("s390x")
> #define __arch_loongarch __arch("LOONGARCH")
> +#define __arch_powerpc64 __arch("POWERPC64")
> #define __caps_unpriv(caps) __test_tag("test_caps_unpriv=" EXPAND_QUOTE(caps))
> #define __load_if_JITed() __test_tag("load_mode=jited")
> #define __load_if_no_JITed() __test_tag("load_mode=no_jited")
> diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c
> index 3ce32d134e2c..01b1420097d2 100644
> --- a/tools/testing/selftests/bpf/test_loader.c
> +++ b/tools/testing/selftests/bpf/test_loader.c
> @@ -378,6 +378,7 @@ enum arch {
> ARCH_RISCV64 = 0x8,
> ARCH_S390X = 0x10,
> ARCH_LOONGARCH = 0x20,
> + ARCH_POWERPC64 = 0x40,
> };
>
> static int get_current_arch(void)
> @@ -392,6 +393,8 @@ static int get_current_arch(void)
> return ARCH_S390X;
> #elif defined(__loongarch__)
> return ARCH_LOONGARCH;
> +#elif defined(__powerpc64__)
> + return ARCH_POWERPC64;
> #endif
> return ARCH_UNKNOWN;
> }
> @@ -585,6 +588,8 @@ static int parse_test_spec(struct test_loader *tester,
> arch = ARCH_S390X;
> } else if (strcmp(val, "LOONGARCH") == 0) {
> arch = ARCH_LOONGARCH;
> + } else if (strcmp(val, "POWERPC64") == 0) {
> + arch = ARCH_POWERPC64;
> } else {
> PRINT_FAIL("bad arch spec: '%s'\n", val);
> err = -EINVAL;
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall
2026-08-05 6:07 ` [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall Saket Kumar Bhaskar
@ 2026-08-06 17:24 ` Hari Bathini
0 siblings, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:24 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:37 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> The tail_call_info field can contain either a scalar counter
> value or a 64-bit pointer to the counter, using a 32-bit
> compare (cmplwi) only checks the lower 32 bits, which can lead
> to incorrect comparisions when location of counter is near 4GB
> boundary. Use instruction cmpldi/cmplwi for accurate comparision
> in corresponding cases.
>
> Reported-by: sashiko-bot@kernel.org
> Closes: https://lore.kernel.org/bpf/20260517191450.85AE6C2BCB8@smtp.kernel.org/
> Fixes: 2ed2d8f6fb38 ("powerpc64/bpf: Support tailcalls with subprogs")
Acked-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> arch/powerpc/net/bpf_jit.h | 6 ++++++
> arch/powerpc/net/bpf_jit_comp.c | 2 +-
> arch/powerpc/net/bpf_jit_comp64.c | 8 ++++----
> 3 files changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index 6632de9871dd..af510da12d8e 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -188,6 +188,12 @@ struct codegen_context {
>
> #define bpf_to_ppc(r) (ctx->b2p[r])
>
> +#ifdef CONFIG_PPC64
> +#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLDI(a, i)
> +#else
> +#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLWI(a, i)
> +#endif
> +
> #ifdef CONFIG_PPC32
> #define BPF_FIXUP_LEN 3 /* Three instructions => 12 bytes */
> #else
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 5d559d613f3a..8be5ded13a4a 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -768,7 +768,7 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_conte
> * Setting the tail_call_info in trampoline's frame
> * depending on if previous frame had value or reference.
> */
> - EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT));
> + EMIT(PPC_RAW_CMPLLI(_R3, MAX_TAIL_CALL_CNT));
> PPC_BCC_CONST_SHORT(COND_GT, 8);
> EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL));
>
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index 951eb10ca1f6..e80312171aa7 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -276,7 +276,7 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
> */
> EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, 0));
> EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), -(BPF_PPC_TAILCALL)));
> - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> PPC_BCC_CONST_SHORT(COND_GT, 8);
> EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2),
> -(BPF_PPC_TAILCALL)));
> @@ -662,7 +662,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
> PPC_BCC_SHORT(COND_GE, out);
>
> EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R1, bpf_jit_stack_tailcallinfo_offset(ctx)));
> - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> PPC_BCC_CONST_SHORT(COND_LE, 8);
>
> /* dereference TMP_REG_1 */
> @@ -672,7 +672,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
> * if (tail_call_info == MAX_TAIL_CALL_CNT)
> * goto out;
> */
> - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT));
> PPC_BCC_SHORT(COND_EQ, out);
>
> /*
> @@ -707,7 +707,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o
> * tail_call_info.
> */
> EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, bpf_jit_stack_tailcallinfo_offset(ctx)));
> - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
> + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT));
> PPC_BCC_CONST_SHORT(COND_GT, 8);
>
> /* First get address of tail_call_info */
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
2026-08-05 6:16 ` sashiko-bot
2026-08-05 7:22 ` bot+bpf-ci
@ 2026-08-06 17:26 ` Hari Bathini
2 siblings, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:26 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:37 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> During size calculation in pass-0, exit_addr is 0 since addrs[fp->len]
> is not yet populated. bpf_jit_emit_exit_insn() treats a zero exit_addr
> as in-range and skips bpf_jit_build_epilogue(), so the alternate inline
> epilogue instructions are not counted in alloclen.
>
> In later passes, if the real exit_addr falls outside the 32MB branch
> range, the full inline epilogue is emitted into the already-allocated
> buffer, writing past its end and corrupting adjacent memory.
>
> Fix by ensuring exit_addr is non-zero before treating it as in-range,
> so pass-0 always falls through to bpf_jit_build_epilogue() and
> conservatively accounts for all epilogue instructions in alloclen.
> Also range check alt_exit_addr directly in the else-if condition.
>
> Since exit_addr handling now falls through to the epilogue, two
> related issues in bpf_int_jit_compile() must also be addressed:
>
> 1. Reset cgctx.alt_exit_addr before the second size-calculation pass.
> Without this, a stale alt_exit_addr from the first pass causes the
> second pass to emit a single jump instead of the full epilogue,
> undercounting alloclen and reintroducing the overflow.
>
> 2. Recompute addrs[fp->len] at the end of each code-generation pass.
> The larger pass-0 body can shrink in later passes as out-of-range
> exits settle into in-range jumps; a stale addrs[fp->len] would
> leave exit branches targeting past the real (shrunken) epilogue.
>
> Because shrinkage in a later pass can move the epilogue offset, the
> fixed two-pass loop is no longer sufficient: an exit that was out of
> range in an earlier pass may fall in range once the epilogue offset
> shrinks, shrinking the body further and overwriting the start of the
> epilogue. Convert the code-generation loop to iterate until the
> program size converges, bounded by CODEGEN_MAX_PASSES, and fail the
> JIT if it does not converge.
>
> Reported-by: sashiko-bot@kernel.org
> Closes: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
> Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Link: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> arch/powerpc/net/bpf_jit.h | 7 +++++++
> arch/powerpc/net/bpf_jit_comp.c | 34 +++++++++++++++++++++++++--------
> 2 files changed, 33 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
> index af510da12d8e..4da8bde92e1e 100644
> --- a/arch/powerpc/net/bpf_jit.h
> +++ b/arch/powerpc/net/bpf_jit.h
> @@ -14,6 +14,13 @@
> #include <asm/ppc-opcode.h>
> #include <linux/build_bug.h>
>
> +/*
> + * We need at least 2 passes for proper code generation, and may need
> + * additional passes if code size changes between passes.
> + */
> +#define CODEGEN_MIN_PASSES 2
> +#define CODEGEN_MAX_PASSES 3
> +
> #ifdef CONFIG_PPC64_ELF_ABI_V1
> #define FUNCTION_DESCR_SIZE 24
> #else
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 8be5ded13a4a..3c20bb13cfd7 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -128,11 +128,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context
> int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx,
> int tmp_reg, long exit_addr)
> {
> - if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
> + if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) {
> PPC_JMP(exit_addr);
> - } else if (ctx->alt_exit_addr) {
> - if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4))))
> - return -1;
> + } else if (ctx->alt_exit_addr && is_offset_in_branch_range(
> + (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) {
> PPC_JMP(ctx->alt_exit_addr);
> } else {
> ctx->alt_exit_addr = ctx->idx * 4;
> @@ -303,6 +302,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> */
> if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) {
> cgctx.idx = 0;
> + cgctx.alt_exit_addr = 0;
> if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false))
> goto out_err;
> }
> @@ -335,10 +335,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> code_base = (u32 *)(image + FUNCTION_DESCR_SIZE);
> fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE);
>
> - /* Code generation passes 1-2 */
> - for (pass = 1; pass < 3; pass++) {
> + /* Code generation passes 1-2+, loop until program size converges. */
> + for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) {
> + u32 prev_proglen = proglen;
> +
> /* Now build the prologue, body code & epilogue for real. */
> cgctx.idx = 0;
> + cgctx.exentry_idx = 0;
> cgctx.alt_exit_addr = 0;
> bpf_jit_build_prologue(code_base, &cgctx);
> if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass,
> @@ -347,11 +350,26 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> bpf_jit_binary_pack_free(fhdr, hdr);
> goto out_err;
> }
> + addrs[fp->len] = cgctx.idx * 4;
> bpf_jit_build_epilogue(code_base, fcode_base, &cgctx);
>
> + proglen = cgctx.idx * 4;
> +
> if (bpf_jit_enable > 1)
> pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
> - proglen - (cgctx.idx * 4), cgctx.seen);
> + prev_proglen - proglen, cgctx.seen);
> +
> + /* Check if program size has converged, but ensure minimum passes */
> + if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen)
> + break;
> +
> + if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) {
> + pr_err("BPF JIT: Program did not converge after %d passes\n",
> + CODEGEN_MAX_PASSES);
> + bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size));
> + bpf_jit_binary_pack_free(fhdr, hdr);
> + goto out_err;
> + }
> }
>
> if (bpf_jit_enable > 1)
> @@ -428,7 +446,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
> u32 *fixup;
>
> /* Populate extable entries only in the last pass */
> - if (pass != 2)
> + if (pass >= CODEGEN_MIN_PASSES)
This is wrong. Has to be:
if (pass < CODEGEN_MIN_PASSES)
> return 0;
>
> if (!fp->aux->extable ||
- Hari
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure
2026-08-05 6:07 ` [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure Saket Kumar Bhaskar
2026-08-05 6:18 ` sashiko-bot
@ 2026-08-06 17:27 ` Hari Bathini
1 sibling, 0 replies; 23+ messages in thread
From: Hari Bathini @ 2026-08-06 17:27 UTC (permalink / raw)
To: Saket Kumar Bhaskar, bpf, linuxppc-dev
Cc: maddy, ast, andrii, daniel, shuah, linux-kselftest, stable,
venkat88, yeswanth
On 05/08/26 11:37 am, Saket Kumar Bhaskar wrote:
> From: Abhishek Dubey <adubey@linux.ibm.com>
>
> The existing conditional statement in bpf_int_jit_compile() frees the
> percpu private stack at out_addrs only when the image buffer was never
> allocated.
>
> If bpf_jit_build_body() fails during a code-generation pass, the
> image buffer has already been allocated, so !image is false and the
> percpu stack is not freed.
>
> Because JIT compilation failed, fp->jited remains at 0. The subsequent
> bpf_jit_free() path only frees priv_stack_ptr when fp->jited is set, so
> freeing is skipped here too, leaking the percpu allocation.
>
> Fix implements freeing the private stack whenever fp->jited was not set,
> i.e. compilation did not succeed, instead of keying off !image. !fp->jited
> already covers the !image case, since image is only NULL on early-failure
> paths where fp->jited is likewise 0.
>
> Reported-by: sashiko-bot@kernel.org
> Closes: https://lore.kernel.org/bpf/20260616135426.A06B71F000E9@smtp.kernel.org
> Fixes: 156d985123b6 ("powerpc64/bpf: Implement JIT support for private stack")
> Cc: stable@vger.kernel.org
Acked-by: Hari Bathini <hbathini@linux.ibm.com>
> Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
> Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
> Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
> ---
> arch/powerpc/net/bpf_jit_comp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 3c20bb13cfd7..825999f8717b 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -404,7 +404,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
> (void *)fimage + FUNCTION_DESCR_SIZE);
>
> out_addrs:
> - if (!image && priv_stack_ptr) {
> + if (!fp->jited && priv_stack_ptr) {
> fp->aux->priv_stack_ptr = NULL;
> free_percpu(priv_stack_ptr);
> }
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-08-06 17:27 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1785906979.git.skb99@linux.ibm.com>
2026-08-05 6:06 ` [PATCH v10 1/8] powerpc/bpf: fix alignment of long branch trampoline address Saket Kumar Bhaskar
2026-08-05 6:21 ` sashiko-bot
2026-08-06 17:15 ` Hari Bathini
2026-08-05 6:06 ` [PATCH v10 2/8] powerpc/bpf: Move out dummy_tramp_addr after Long branch stub Saket Kumar Bhaskar
2026-08-06 17:18 ` Hari Bathini
2026-08-05 6:06 ` [PATCH v10 3/8] selftest/bpf: Fixing powerpc JIT disassembly failure Saket Kumar Bhaskar
2026-08-05 7:37 ` bot+bpf-ci
2026-08-06 17:19 ` Hari Bathini
2026-08-06 17:20 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 4/8] selftest/bpf: Enable verifier selftest for powerpc64 Saket Kumar Bhaskar
2026-08-05 7:07 ` bot+bpf-ci
2026-08-06 17:22 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 5/8] powerpc64/bpf: fix compare instruction emitted for tailcall Saket Kumar Bhaskar
2026-08-06 17:24 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 6/8] selftest/bpf: Add tailcall verifier selftest for powerpc64 Saket Kumar Bhaskar
2026-08-05 6:14 ` sashiko-bot
2026-08-05 6:07 ` [PATCH v10 7/8] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Saket Kumar Bhaskar
2026-08-05 6:16 ` sashiko-bot
2026-08-05 7:22 ` bot+bpf-ci
2026-08-06 17:26 ` Hari Bathini
2026-08-05 6:07 ` [PATCH v10 8/8] powerpc64/bpf: fix percpu private stack leak on JIT failure Saket Kumar Bhaskar
2026-08-05 6:18 ` sashiko-bot
2026-08-06 17:27 ` Hari Bathini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox