Skip to content

Commit 7c380d3

Browse files
Automatic merge of 'next-test' into merge-test (2026-01-29 09:09)
2 parents 960c1fd + 33c1c6d commit 7c380d3

File tree

5 files changed

+317
-63
lines changed

5 files changed

+317
-63
lines changed

arch/powerpc/include/asm/kgdb.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
#define BREAK_INSTR_SIZE 4
2727
#define BUFMAX ((NUMREGBYTES * 2) + 512)
28-
#define OUTBUFMAX ((NUMREGBYTES * 2) + 512)
2928

3029
#define BREAK_INSTR 0x7d821008 /* twge r2, r2 */
3130

arch/powerpc/kernel/smp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,8 @@ static int parse_thread_groups(struct device_node *dn,
822822

823823
count = of_property_count_u32_elems(dn, "ibm,thread-groups");
824824
thread_group_array = kcalloc(count, sizeof(u32), GFP_KERNEL);
825+
if (!thread_group_array)
826+
return -ENOMEM;
825827
ret = of_property_read_u32_array(dn, "ibm,thread-groups",
826828
thread_group_array, count);
827829
if (ret)

arch/powerpc/net/bpf_jit.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define SZL sizeof(unsigned long)
2626
#define BPF_INSN_SAFETY 64
27+
#define BPF_PPC_TAILCALL 8
2728

2829
#define PLANT_INSTR(d, idx, instr) \
2930
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
@@ -51,6 +52,13 @@
5152
EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
5253
} while (0)
5354

55+
/* When constant jump offset is known prior */
56+
#define PPC_BCC_CONST_SHORT(cond, offset) \
57+
do { \
58+
BUILD_BUG_ON(offset < -0x8000 || offset > 0x7fff || (offset & 0x3)); \
59+
EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \
60+
} while (0)
61+
5462
/*
5563
* Sign-extended 32-bit immediate load
5664
*
@@ -72,6 +80,10 @@
7280
} } while (0)
7381

7482
#ifdef CONFIG_PPC64
83+
84+
/* for gpr non volatile registers BPG_REG_6 to 10 */
85+
#define BPF_PPC_STACK_SAVE (6 * 8)
86+
7587
/* If dummy pass (!image), account for maximum possible instructions */
7688
#define PPC_LI64(d, i) do { \
7789
if (!image) \
@@ -166,6 +178,9 @@ struct codegen_context {
166178
unsigned int alt_exit_addr;
167179
u64 arena_vm_start;
168180
u64 user_vm_start;
181+
bool is_subprog;
182+
bool exception_boundary;
183+
bool exception_cb;
169184
};
170185

171186
#define bpf_to_ppc(r) (ctx->b2p[r])
@@ -205,6 +220,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
205220
struct codegen_context *ctx, int insn_idx,
206221
int jmp_off, int dst_reg, u32 code);
207222

223+
int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx);
208224
#endif
209225

210226
#endif

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
206206
cgctx.stack_size = round_up(fp->aux->stack_depth, 16);
207207
cgctx.arena_vm_start = bpf_arena_get_kern_vm_start(fp->aux->arena);
208208
cgctx.user_vm_start = bpf_arena_get_user_vm_start(fp->aux->arena);
209+
cgctx.is_subprog = bpf_is_subprog(fp);
210+
cgctx.exception_boundary = fp->aux->exception_boundary;
211+
cgctx.exception_cb = fp->aux->exception_cb;
209212

210213
/* Scouting faux-generate pass 0 */
211214
if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false)) {
@@ -435,6 +438,16 @@ void bpf_jit_free(struct bpf_prog *fp)
435438
bpf_prog_unlock_free(fp);
436439
}
437440

441+
bool bpf_jit_supports_exceptions(void)
442+
{
443+
return IS_ENABLED(CONFIG_PPC64);
444+
}
445+
446+
bool bpf_jit_supports_subprog_tailcalls(void)
447+
{
448+
return IS_ENABLED(CONFIG_PPC64);
449+
}
450+
438451
bool bpf_jit_supports_kfunc_call(void)
439452
{
440453
return true;
@@ -617,15 +630,50 @@ static int invoke_bpf_mod_ret(u32 *image, u32 *ro_image, struct codegen_context
617630
return 0;
618631
}
619632

620-
static void bpf_trampoline_setup_tail_call_cnt(u32 *image, struct codegen_context *ctx,
621-
int func_frame_offset, int r4_off)
633+
/*
634+
* Refer __arch_prepare_bpf_trampoline() for stack component details.
635+
*
636+
* The tailcall count/reference is present in caller's stack frame. The
637+
* tail_call_info is saved at the same offset on the trampoline frame
638+
* for the traced function (BPF subprog/callee) to fetch it.
639+
*/
640+
static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_context *ctx,
641+
int func_frame_offset,
642+
int bpf_dummy_frame_size, int r4_off)
622643
{
623644
if (IS_ENABLED(CONFIG_PPC64)) {
624-
/* See bpf_jit_stack_tailcallcnt() */
625-
int tailcallcnt_offset = 7 * 8;
645+
/* See Generated stack layout */
646+
int tailcallinfo_offset = BPF_PPC_TAILCALL;
647+
648+
/*
649+
* func_frame_offset = ...(1)
650+
* bpf_dummy_frame_size + trampoline_frame_size
651+
*/
652+
EMIT(PPC_RAW_LD(_R4, _R1, func_frame_offset));
653+
EMIT(PPC_RAW_LD(_R3, _R4, -tailcallinfo_offset));
626654

627-
EMIT(PPC_RAW_LL(_R3, _R1, func_frame_offset - tailcallcnt_offset));
628-
EMIT(PPC_RAW_STL(_R3, _R1, -tailcallcnt_offset));
655+
/*
656+
* Setting the tail_call_info in trampoline's frame
657+
* depending on if previous frame had value or reference.
658+
*/
659+
EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT));
660+
PPC_BCC_CONST_SHORT(COND_GT, 8);
661+
EMIT(PPC_RAW_ADDI(_R3, _R4, bpf_jit_stack_tailcallinfo_offset(ctx)));
662+
/*
663+
* From ...(1) above:
664+
* trampoline_frame_bottom = ...(2)
665+
* func_frame_offset - bpf_dummy_frame_size
666+
*
667+
* Using ...(2) derived above:
668+
* trampoline_tail_call_info_offset = ...(3)
669+
* trampoline_frame_bottom - tailcallinfo_offset
670+
*
671+
* From ...(3):
672+
* Use trampoline_tail_call_info_offset to write reference of main's
673+
* tail_call_info in trampoline frame.
674+
*/
675+
EMIT(PPC_RAW_STL(_R3, _R1, (func_frame_offset - bpf_dummy_frame_size)
676+
- tailcallinfo_offset));
629677
} else {
630678
/* See bpf_jit_stack_offsetof() and BPF_PPC_TC */
631679
EMIT(PPC_RAW_LL(_R4, _R1, r4_off));
@@ -635,14 +683,11 @@ static void bpf_trampoline_setup_tail_call_cnt(u32 *image, struct codegen_contex
635683
static void bpf_trampoline_restore_tail_call_cnt(u32 *image, struct codegen_context *ctx,
636684
int func_frame_offset, int r4_off)
637685
{
638-
if (IS_ENABLED(CONFIG_PPC64)) {
639-
/* See bpf_jit_stack_tailcallcnt() */
640-
int tailcallcnt_offset = 7 * 8;
641-
642-
EMIT(PPC_RAW_LL(_R3, _R1, -tailcallcnt_offset));
643-
EMIT(PPC_RAW_STL(_R3, _R1, func_frame_offset - tailcallcnt_offset));
644-
} else {
645-
/* See bpf_jit_stack_offsetof() and BPF_PPC_TC */
686+
if (IS_ENABLED(CONFIG_PPC32)) {
687+
/*
688+
* Restore tailcall for 32-bit powerpc
689+
* See bpf_jit_stack_offsetof() and BPF_PPC_TC
690+
*/
646691
EMIT(PPC_RAW_STL(_R4, _R1, r4_off));
647692
}
648693
}
@@ -731,6 +776,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
731776
* LR save area [ r0 save (64-bit) ] | header
732777
* [ r0 save (32-bit) ] |
733778
* dummy frame for unwind [ back chain 1 ] --
779+
* [ tail_call_info ] optional - 64-bit powerpc
734780
* [ padding ] align stack frame
735781
* r4_off [ r4 (tailcallcnt) ] optional - 32-bit powerpc
736782
* alt_lr_off [ real lr (ool stub)] optional - actual lr
@@ -812,6 +858,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
812858
}
813859
}
814860

861+
/*
862+
* Save tailcall count pointer at the same offset on the
863+
* stack where subprogs expect it
864+
*/
865+
if ((flags & BPF_TRAMP_F_CALL_ORIG) &&
866+
(flags & BPF_TRAMP_F_TAIL_CALL_CTX))
867+
bpf_frame_size += BPF_PPC_TAILCALL;
868+
815869
/* Padding to align stack frame, if any */
816870
bpf_frame_size = round_up(bpf_frame_size, SZL * 2);
817871

@@ -913,7 +967,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
913967

914968
/* Replicate tail_call_cnt before calling the original BPF prog */
915969
if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
916-
bpf_trampoline_setup_tail_call_cnt(image, ctx, func_frame_offset, r4_off);
970+
bpf_trampoline_setup_tail_call_info(image, ctx, func_frame_offset,
971+
bpf_dummy_frame_size, r4_off);
917972

918973
/* Restore args */
919974
bpf_trampoline_restore_args_stack(image, ctx, func_frame_offset, nr_regs, regs_off);

0 commit comments

Comments
 (0)