Skip to content

Commit fe8d957

Browse files
author
Alexei Starovoitov
committed
bpf, x64: fix stack layout of JITed bpf code
Since commit 177366b the %rbp stopped pointing to %rbp of the previous stack frame. That broke frame pointer based stack unwinding. This commit is a partial revert of it. Note that the location of tail_call_cnt is fixed, since the verifier enforces MAX_BPF_STACK stack size for programs with tail calls. Fixes: 177366b ("bpf: change x86 JITed program stack layout") Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 86723c8 commit fe8d957

File tree

1 file changed

+21
-53
lines changed

1 file changed

+21
-53
lines changed

arch/x86/net/bpf_jit_comp.c

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,7 @@ struct jit_context {
190190
#define BPF_MAX_INSN_SIZE 128
191191
#define BPF_INSN_SAFETY 64
192192

193-
#define AUX_STACK_SPACE 40 /* Space for RBX, R13, R14, R15, tailcnt */
194-
195-
#define PROLOGUE_SIZE 37
193+
#define PROLOGUE_SIZE 20
196194

197195
/*
198196
* Emit x86-64 prologue code for BPF program and check its size.
@@ -203,44 +201,19 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf)
203201
u8 *prog = *pprog;
204202
int cnt = 0;
205203

206-
/* push rbp */
207-
EMIT1(0x55);
208-
209-
/* mov rbp,rsp */
210-
EMIT3(0x48, 0x89, 0xE5);
211-
212-
/* sub rsp, rounded_stack_depth + AUX_STACK_SPACE */
213-
EMIT3_off32(0x48, 0x81, 0xEC,
214-
round_up(stack_depth, 8) + AUX_STACK_SPACE);
215-
216-
/* sub rbp, AUX_STACK_SPACE */
217-
EMIT4(0x48, 0x83, 0xED, AUX_STACK_SPACE);
218-
219-
/* mov qword ptr [rbp+0],rbx */
220-
EMIT4(0x48, 0x89, 0x5D, 0);
221-
/* mov qword ptr [rbp+8],r13 */
222-
EMIT4(0x4C, 0x89, 0x6D, 8);
223-
/* mov qword ptr [rbp+16],r14 */
224-
EMIT4(0x4C, 0x89, 0x75, 16);
225-
/* mov qword ptr [rbp+24],r15 */
226-
EMIT4(0x4C, 0x89, 0x7D, 24);
227-
204+
EMIT1(0x55); /* push rbp */
205+
EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
206+
/* sub rsp, rounded_stack_depth */
207+
EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));
208+
EMIT1(0x53); /* push rbx */
209+
EMIT2(0x41, 0x55); /* push r13 */
210+
EMIT2(0x41, 0x56); /* push r14 */
211+
EMIT2(0x41, 0x57); /* push r15 */
228212
if (!ebpf_from_cbpf) {
229-
/*
230-
* Clear the tail call counter (tail_call_cnt): for eBPF tail
231-
* calls we need to reset the counter to 0. It's done in two
232-
* instructions, resetting RAX register to 0, and moving it
233-
* to the counter location.
234-
*/
235-
236-
/* xor eax, eax */
237-
EMIT2(0x31, 0xc0);
238-
/* mov qword ptr [rbp+32], rax */
239-
EMIT4(0x48, 0x89, 0x45, 32);
240-
213+
/* zero init tail_call_cnt */
214+
EMIT2(0x6a, 0x00);
241215
BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
242216
}
243-
244217
*pprog = prog;
245218
}
246219

@@ -285,13 +258,13 @@ static void emit_bpf_tail_call(u8 **pprog)
285258
* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
286259
* goto out;
287260
*/
288-
EMIT2_off32(0x8B, 0x85, 36); /* mov eax, dword ptr [rbp + 36] */
261+
EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */
289262
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
290263
#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE)
291264
EMIT2(X86_JA, OFFSET2); /* ja out */
292265
label2 = cnt;
293266
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
294-
EMIT2_off32(0x89, 0x85, 36); /* mov dword ptr [rbp + 36], eax */
267+
EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */
295268

296269
/* prog = array->ptrs[index]; */
297270
EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */
@@ -1040,19 +1013,14 @@ xadd: if (is_imm8(insn->off))
10401013
seen_exit = true;
10411014
/* Update cleanup_addr */
10421015
ctx->cleanup_addr = proglen;
1043-
/* mov rbx, qword ptr [rbp+0] */
1044-
EMIT4(0x48, 0x8B, 0x5D, 0);
1045-
/* mov r13, qword ptr [rbp+8] */
1046-
EMIT4(0x4C, 0x8B, 0x6D, 8);
1047-
/* mov r14, qword ptr [rbp+16] */
1048-
EMIT4(0x4C, 0x8B, 0x75, 16);
1049-
/* mov r15, qword ptr [rbp+24] */
1050-
EMIT4(0x4C, 0x8B, 0x7D, 24);
1051-
1052-
/* add rbp, AUX_STACK_SPACE */
1053-
EMIT4(0x48, 0x83, 0xC5, AUX_STACK_SPACE);
1054-
EMIT1(0xC9); /* leave */
1055-
EMIT1(0xC3); /* ret */
1016+
if (!bpf_prog_was_classic(bpf_prog))
1017+
EMIT1(0x5B); /* get rid of tail_call_cnt */
1018+
EMIT2(0x41, 0x5F); /* pop r15 */
1019+
EMIT2(0x41, 0x5E); /* pop r14 */
1020+
EMIT2(0x41, 0x5D); /* pop r13 */
1021+
EMIT1(0x5B); /* pop rbx */
1022+
EMIT1(0xC9); /* leave */
1023+
EMIT1(0xC3); /* ret */
10561024
break;
10571025

10581026
default:

0 commit comments

Comments
 (0)