@@ -89,7 +89,9 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx)
8989 * - the bpf program uses its stack area
9090 * The latter condition is deduced from the usage of BPF_REG_FP
9191 */
92- return ctx -> seen & SEEN_FUNC || bpf_is_seen_register (ctx , bpf_to_ppc (BPF_REG_FP ));
92+ return ctx -> seen & SEEN_FUNC ||
93+ bpf_is_seen_register (ctx , bpf_to_ppc (BPF_REG_FP )) ||
94+ ctx -> exception_cb ;
9395}
9496
9597/*
@@ -161,8 +163,13 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
161163 EMIT (PPC_RAW_LI (bpf_to_ppc (TMP_REG_1 ), 0 ));
162164 /* this goes in the redzone */
163165 EMIT (PPC_RAW_STD (bpf_to_ppc (TMP_REG_1 ), _R1 , - (BPF_PPC_TAILCALL )));
164- } else {
166+ } else if (! ctx -> exception_cb ) {
165167 /*
168+ * Tailcall jitting for non exception_cb progs only.
169+ * exception_cb won't require tail_call_info to be setup.
170+ *
171+ * tail_call_info interpretation logic:
172+ *
166173 * if tail_call_info < MAX_TAIL_CALL_CNT
167174 * main prog calling first subprog -> copy reference
168175 * else
@@ -177,8 +184,12 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
177184 EMIT (PPC_RAW_STD (bpf_to_ppc (TMP_REG_1 ), _R1 , - (BPF_PPC_TAILCALL )));
178185 }
179186
180- if (bpf_has_stack_frame (ctx )) {
187+ if (bpf_has_stack_frame (ctx ) && ! ctx -> exception_cb ) {
181188 /*
189+ * exception_cb uses boundary frame after stack walk.
190+ * It can simply use redzone, this optimization reduces
191+ * stack walk loop by one level.
192+ *
182193 * We need a stack frame, but we don't necessarily need to
183194 * save/restore LR unless we call other functions
184195 */
@@ -190,23 +201,35 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx)
190201 EMIT (PPC_RAW_STDU (_R1 , _R1 , - (BPF_PPC_STACKFRAME + ctx -> stack_size )));
191202 }
192203
193- /*
194- * Back up non-volatile regs -- BPF registers 6-10
195- * If we haven't created our own stack frame, we save these
196- * in the protected zone below the previous stack frame
197- */
198- for (i = BPF_REG_6 ; i <= BPF_REG_10 ; i ++ )
199- if (bpf_is_seen_register (ctx , bpf_to_ppc (i )))
200- EMIT (PPC_RAW_STD (bpf_to_ppc (i ), _R1 , bpf_jit_stack_offsetof (ctx , bpf_to_ppc (i ))));
204+ if (!ctx -> exception_cb ) {
205+ /*
206+ * Back up non-volatile regs -- BPF registers 6-10
207+ * If we haven't created our own stack frame, we save these
208+ * in the protected zone below the previous stack frame
209+ */
210+ for (i = BPF_REG_6 ; i <= BPF_REG_10 ; i ++ )
211+ if (ctx -> exception_boundary || bpf_is_seen_register (ctx , bpf_to_ppc (i )))
212+ EMIT (PPC_RAW_STD (bpf_to_ppc (i ), _R1 ,
213+ bpf_jit_stack_offsetof (ctx , bpf_to_ppc (i ))));
201214
202- if (ctx -> arena_vm_start )
203- EMIT (PPC_RAW_STD (bpf_to_ppc (ARENA_VM_START ), _R1 ,
215+ if (ctx -> exception_boundary || ctx -> arena_vm_start )
216+ EMIT (PPC_RAW_STD (bpf_to_ppc (ARENA_VM_START ), _R1 ,
204217 bpf_jit_stack_offsetof (ctx , bpf_to_ppc (ARENA_VM_START ))));
218+ } else {
219+ /*
220+ * Exception callback receives Frame Pointer of boundary
221+ * program(main prog) as third arg
222+ */
223+ EMIT (PPC_RAW_MR (_R1 , _R5 ));
224+ }
205225
206- /* Setup frame pointer to point to the bpf stack area */
226+ /*
227+ * Exception_cb not restricted from using stack area or arena.
228+ * Setup frame pointer to point to the bpf stack area
229+ */
207230 if (bpf_is_seen_register (ctx , bpf_to_ppc (BPF_REG_FP )))
208231 EMIT (PPC_RAW_ADDI (bpf_to_ppc (BPF_REG_FP ), _R1 ,
209- STACK_FRAME_MIN_SIZE + ctx -> stack_size ));
232+ STACK_FRAME_MIN_SIZE + ctx -> stack_size ));
210233
211234 if (ctx -> arena_vm_start )
212235 PPC_LI64 (bpf_to_ppc (ARENA_VM_START ), ctx -> arena_vm_start );
@@ -218,17 +241,17 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx
218241
219242 /* Restore NVRs */
220243 for (i = BPF_REG_6 ; i <= BPF_REG_10 ; i ++ )
221- if (bpf_is_seen_register (ctx , bpf_to_ppc (i )))
244+ if (ctx -> exception_cb || bpf_is_seen_register (ctx , bpf_to_ppc (i )))
222245 EMIT (PPC_RAW_LD (bpf_to_ppc (i ), _R1 , bpf_jit_stack_offsetof (ctx , bpf_to_ppc (i ))));
223246
224- if (ctx -> arena_vm_start )
247+ if (ctx -> exception_cb || ctx -> arena_vm_start )
225248 EMIT (PPC_RAW_LD (bpf_to_ppc (ARENA_VM_START ), _R1 ,
226249 bpf_jit_stack_offsetof (ctx , bpf_to_ppc (ARENA_VM_START ))));
227250
228251 /* Tear down our stack frame */
229252 if (bpf_has_stack_frame (ctx )) {
230253 EMIT (PPC_RAW_ADDI (_R1 , _R1 , BPF_PPC_STACKFRAME + ctx -> stack_size ));
231- if (ctx -> seen & SEEN_FUNC ) {
254+ if (ctx -> seen & SEEN_FUNC || ctx -> exception_cb ) {
232255 EMIT (PPC_RAW_LD (_R0 , _R1 , PPC_LR_STKOFF ));
233256 EMIT (PPC_RAW_MTLR (_R0 ));
234257 }
0 commit comments