Skip to content

Commit 51b8de4

Browse files
hbathinimaddy-kerneldev
authored andcommitted
powerpc64/bpf: fix handling of BPF stack in exception callback
Exception callback reuses the stack frame of exception boundary. When exception boundary and exception callback programs have different BPF stack depth, the current stack unwind in exception callback will fail. Adjust the stack frame size of exception callback, in its prologue, if its BPF stack depth is different from that of exception boundary. Reported-by: [email protected] Closes: https://lore.kernel.org/bpf/2a310e86a59eb4c44c3ac9e5647814469d9c955580c9c0f1b3d9ca4a44717a34@mail.kernel.org/ Fixes: 11d45ee ("powerpc64/bpf: Additional NVR handling for bpf_throw") Signed-off-by: Hari Bathini <[email protected]> Signed-off-by: Madhavan Srinivasan <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 2d347d1 commit 51b8de4

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@
3232
*
3333
* [ prev sp ] <-------------
3434
* [ tail_call_info ] 8 |
35-
* [ nv gpr save area ] 6*8 + (12*8) |
35+
* [ nv gpr save area ] (6 * 8) |
36+
* [ addl. nv gpr save area] (12 * 8) | <--- exception boundary/callback program
3637
* [ local_tmp_var ] 24 |
3738
* fp (r31) --> [ ebpf stack space ] upto 512 |
3839
* [ frame header ] 32/112 |
3940
* sp (r1) ---> [ stack pointer ] --------------
4041
*
41-
* Additional (12*8) in 'nv gpr save area' only in case of
42-
* exception boundary.
42+
* Additional (12 * 8) in 'nv gpr save area' only in case of
43+
* exception boundary/callback.
4344
*/
4445

4546
/* BPF non-volatile registers save area size */
@@ -51,7 +52,7 @@
5152
* for additional non volatile registers(r14-r25) to be saved
5253
* at exception boundary
5354
*/
54-
#define BPF_PPC_EXC_STACK_SAVE (12*8)
55+
#define BPF_PPC_EXC_STACK_SAVE (12 * 8)
5556

5657
/* stack frame excluding BPF stack, ensure this is quadword aligned */
5758
#define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + \
@@ -128,12 +129,13 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx)
128129
* [ ... ] |
129130
* sp (r1) ---> [ stack pointer ] --------------
130131
* [ tail_call_info ] 8
131-
* [ nv gpr save area ] 6*8 + (12*8)
132+
* [ nv gpr save area ] (6 * 8)
133+
* [ addl. nv gpr save area] (12 * 8) <--- exception boundary/callback program
132134
* [ local_tmp_var ] 24
133135
* [ unused red zone ] 224
134136
*
135-
* Additional (12*8) in 'nv gpr save area' only in case of
136-
* exception boundary.
137+
* Additional (12 * 8) in 'nv gpr save area' only in case of
138+
* exception boundary/callback.
137139
*/
138140
static int bpf_jit_stack_local(struct codegen_context *ctx)
139141
{
@@ -240,10 +242,6 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
240242

241243
if (bpf_has_stack_frame(ctx) && !ctx->exception_cb) {
242244
/*
243-
* exception_cb uses boundary frame after stack walk.
244-
* It can simply use redzone, this optimization reduces
245-
* stack walk loop by one level.
246-
*
247245
* We need a stack frame, but we don't necessarily need to
248246
* save/restore LR unless we call other functions
249247
*/
@@ -287,6 +285,22 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
287285
* program(main prog) as third arg
288286
*/
289287
EMIT(PPC_RAW_MR(_R1, _R5));
288+
/*
289+
* Exception callback reuses the stack frame of exception boundary.
290+
* But BPF stack depth of exception callback and exception boundary
291+
* don't have to be same. If BPF stack depth is different, adjust the
292+
* stack frame size considering BPF stack depth of exception callback.
293+
* The non-volatile register save area remains unchanged. These non-
294+
* volatile registers are restored in exception callback's epilogue.
295+
*/
296+
EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R5, 0));
297+
EMIT(PPC_RAW_SUB(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_1), _R1));
298+
EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2),
299+
-BPF_PPC_EXC_STACKFRAME));
300+
EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), ctx->stack_size));
301+
PPC_BCC_CONST_SHORT(COND_EQ, 12);
302+
EMIT(PPC_RAW_MR(_R1, bpf_to_ppc(TMP_REG_1)));
303+
EMIT(PPC_RAW_STDU(_R1, _R1, -(BPF_PPC_EXC_STACKFRAME + ctx->stack_size)));
290304
}
291305

292306
/*

0 commit comments

Comments
 (0)