History

bpf, x64: rework pro/epilogue and tailcall handling in JIT

This commit serves two things: 1) it optimizes BPF prologue/epilogue generation 2) it makes possible to have tailcalls within BPF subprogram Both points are related to each other since without 1), 2) could not be achieved. In [1], Alexei says: "The prologue will look like: nop5 xor eax,eax  // two new bytes if bpf_tail_call() is used in this // function push rbp mov rbp, rsp sub rsp, rounded_stack_depth push rax // zero init tail_call counter variable number of push rbx,r13,r14,r15 Then bpf_tail_call will pop variable number rbx,.. and final 'pop rax' Then 'add rsp, size_of_current_stack_frame' jmp to next function and skip over 'nop5; xor eax,eax; push rpb; mov rbp, rsp' This way new function will set its own stack size and will init tail call counter with whatever value the parent had. If next function doesn't use bpf_tail_call it won't have 'xor eax,eax'. Instead it would need to have 'nop2' in there." Implement that suggestion. Since the layout of stack is changed, tail call counter handling can not rely anymore on popping it to rbx just like it have been handled for constant prologue case and later overwrite of rbx with actual value of rbx pushed to stack. Therefore, let's use one of the register (%rcx) that is considered to be volatile/caller-saved and pop the value of tail call counter in there in the epilogue. Drop the BUILD_BUG_ON in emit_prologue and in emit_bpf_tail_call_indirect where instruction layout is not constant anymore. Introduce new poke target, 'tailcall_bypass' to poke descriptor that is dedicated for skipping the register pops and stack unwind that are generated right before the actual jump to target program. For case when the target program is not present, BPF program will skip the pop instructions and nop5 dedicated for jmpq $target. An example of such state when only R6 of callee saved registers is used by program: ffffffffc0513aa1: e9 0e 00 00 00 jmpq 0xffffffffc0513ab4 ffffffffc0513aa6: 5b pop %rbx ffffffffc0513aa7: 58 pop %rax ffffffffc0513aa8: 48 81 c4 00 00 00 00 add $0x0,%rsp ffffffffc0513aaf: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ffffffffc0513ab4: 48 89 df mov %rbx,%rdi When target program is inserted, the jump that was there to skip pops/nop5 will become the nop5, so CPU will go over pops and do the actual tailcall. One might ask why there simply can not be pushes after the nop5? In the following example snippet: ffffffffc037030c: 48 89 fb mov %rdi,%rbx (...) ffffffffc0370332: 5b pop %rbx ffffffffc0370333: 58 pop %rax ffffffffc0370334: 48 81 c4 00 00 00 00 add $0x0,%rsp ffffffffc037033b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ffffffffc0370340: 48 81 ec 00 00 00 00 sub $0x0,%rsp ffffffffc0370347: 50 push %rax ffffffffc0370348: 53 push %rbx ffffffffc0370349: 48 89 df mov %rbx,%rdi ffffffffc037034c: e8 f7 21 00 00 callq 0xffffffffc0372548 There is the bpf2bpf call (at ffffffffc037034c) right after the tailcall and jump target is not present. ctx is in %rbx register and BPF subprogram that we will call into on ffffffffc037034c is relying on it, e.g. it will pick ctx from there. Such code layout is therefore broken as we would overwrite the content of %rbx with the value that was pushed on the prologue. That is the reason for the 'bypass' approach. Special care needs to be taken during the install/update/remove of tailcall target. In case when target program is not present, the CPU must not execute the pop instructions that precede the tailcall. To address that, the following states can be defined: A nop, unwind, nop B nop, unwind, tail C skip, unwind, nop D skip, unwind, tail A is forbidden (lead to incorrectness). The state transitions between tailcall install/update/remove will work as follows: First install tail call f: C->D->B(f) * poke the tailcall, after that get rid of the skip Update tail call f to f': B(f)->B(f') * poke the tailcall (poke->tailcall_target) and do NOT touch the poke->tailcall_bypass Remove tail call: B(f')->C(f') * poke->tailcall_bypass is poked back to jump, then we wait the RCU grace period so that other programs will finish its execution and after that we are safe to remove the poke->tailcall_target Install new tail call (f''): C(f')->D(f'')->B(f''). * same as first step This way CPU can never be exposed to "unwind, tail" state. Last but not least, when tailcalls get mixed with bpf2bpf calls, it would be possible to encounter the endless loop due to clearing the tailcall counter if for example we would use the tailcall3-like from BPF selftests program that would be subprogram-based, meaning the tailcall would be present within the BPF subprogram. This test, broken down to particular steps, would do: entry -> set tailcall counter to 0, bump it by 1, tailcall to func0 func0 -> call subprog_tail (we are NOT skipping the first 11 bytes of prologue and this subprogram has a tailcall, therefore we clear the counter...) subprog -> do the same thing as entry and then loop forever. To address this, the idea is to go through the call chain of bpf2bpf progs and look for a tailcall presence throughout whole chain. If we saw a single tail call then each node in this call chain needs to be marked as a subprog that can reach the tailcall. We would later feed the JIT with this info and: - set eax to 0 only when tailcall is reachable and this is the entry prog - if tailcall is reachable but there's no tailcall in insns of currently JITed prog then push rax anyway, so that it will be possible to propagate further down the call chain - finally if tailcall is reachable, then we need to precede the 'call' insn with mov rax, [rbp - (stack_depth + 8)] Tail call related cases from test_verifier kselftest are also working fine. Sample BPF programs that utilize tail calls (sockex3, tracex5) work properly as well. [1]: https://lore.kernel.org/bpf/20200517043227.2gpq22ifoq37ogst@ast-mbp.dhcp.thefacebook.com/

Maciej Fijalkowski committed 6 years ago

Commit ebf7d1f1 parent 7f6e4316 files · +244 −55Browse files

Unified · Split

6 files
  1. arch/x86/net/bpf_jit_comp.c +189 −48
  2. include/linux/bpf.h +3 −0
  3. include/linux/bpf_verifier.h +1 −0
  4. kernel/bpf/arraymap.c +34 −6
  5. kernel/bpf/core.c +1 −1
  6. kernel/bpf/verifier.c +16 −0
arch/x86/net/bpf_jit_comp.c+189−48
@@ -221,14 +221,48 @@ struct jit_context { · 220 unmodified lines
221 221
222/* Number of bytes emit_patch() needs to generate instructions */222/* Number of bytes emit_patch() needs to generate instructions */
223#define X86_PATCH_SIZE 5223#define X86_PATCH_SIZE 5
224/* Number of bytes that will be skipped on tailcall */
225#define X86_TAIL_CALL_OFFSET 11
224 226
225#define PROLOGUE_SIZE 25227static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
228{
229 u8 *prog = *pprog;
230 int cnt = 0;
231
232 if (callee_regs_used[0])
233 EMIT1(0x53); /* push rbx */
234 if (callee_regs_used[1])
235 EMIT2(0x41, 0x55); /* push r13 */
236 if (callee_regs_used[2])
237 EMIT2(0x41, 0x56); /* push r14 */
238 if (callee_regs_used[3])
239 EMIT2(0x41, 0x57); /* push r15 */
240 *pprog = prog;
241}
242
243static void pop_callee_regs(u8 **pprog, bool *callee_regs_used)
244{
245 u8 *prog = *pprog;
246 int cnt = 0;
247
248 if (callee_regs_used[3])
249 EMIT2(0x41, 0x5F); /* pop r15 */
250 if (callee_regs_used[2])
251 EMIT2(0x41, 0x5E); /* pop r14 */
252 if (callee_regs_used[1])
253 EMIT2(0x41, 0x5D); /* pop r13 */
254 if (callee_regs_used[0])
255 EMIT1(0x5B); /* pop rbx */
256 *pprog = prog;
257}
226 258
227/*259/*
228 * Emit x86-64 prologue code for BPF program and check its size.260 * Emit x86-64 prologue code for BPF program.
229 * bpf_tail_call helper will skip it while jumping into another program261 * bpf_tail_call helper will skip the first X86_TAIL_CALL_OFFSET bytes
262 * while jumping to another program
230 */263 */
231static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf)264static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
265 bool tail_call_reachable, bool is_subprog)
232{266{
233 u8 *prog = *pprog;267 u8 *prog = *pprog;
234 int cnt = X86_PATCH_SIZE;268 int cnt = X86_PATCH_SIZE;
@@ -238,19 +272,18 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf) · 3 unmodified lines
238 */272 */
239 memcpy(prog, ideal_nops[NOP_ATOMIC5], cnt);273 memcpy(prog, ideal_nops[NOP_ATOMIC5], cnt);
240 prog += cnt;274 prog += cnt;
275 if (!ebpf_from_cbpf) {
276 if (tail_call_reachable && !is_subprog)
277 EMIT2(0x31, 0xC0); /* xor eax, eax */
278 else
279 EMIT2(0x66, 0x90); /* nop2 */
280 }
241 EMIT1(0x55); /* push rbp */281 EMIT1(0x55); /* push rbp */
242 EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */282 EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
243 /* sub rsp, rounded_stack_depth */283 /* sub rsp, rounded_stack_depth */
244 EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));284 EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));
245 EMIT1(0x53); /* push rbx */285 if (tail_call_reachable)
246 EMIT2(0x41, 0x55); /* push r13 */286 EMIT1(0x50); /* push rax */
247 EMIT2(0x41, 0x56); /* push r14 */
248 EMIT2(0x41, 0x57); /* push r15 */
249 if (!ebpf_from_cbpf) {
250 /* zero init tail_call_cnt */
251 EMIT2(0x6a, 0x00);
252 BUILD_BUG_ON(cnt != PROLOGUE_SIZE);
253 }
254 *pprog = prog;287 *pprog = prog;
255}288}
256 289
@@ -314,13 +347,14 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, · 57 unmodified lines
314 mutex_lock(&text_mutex);347 mutex_lock(&text_mutex);
315 if (memcmp(ip, old_insn, X86_PATCH_SIZE))348 if (memcmp(ip, old_insn, X86_PATCH_SIZE))
316 goto out;349 goto out;
350 ret = 1;
317 if (memcmp(ip, new_insn, X86_PATCH_SIZE)) {351 if (memcmp(ip, new_insn, X86_PATCH_SIZE)) {
318 if (text_live)352 if (text_live)
319 text_poke_bp(ip, new_insn, X86_PATCH_SIZE, NULL);353 text_poke_bp(ip, new_insn, X86_PATCH_SIZE, NULL);
320 else354 else
321 memcpy(ip, new_insn, X86_PATCH_SIZE);355 memcpy(ip, new_insn, X86_PATCH_SIZE);
356 ret = 0;
322 }357 }
323 ret = 0;
324out:358out:
325 mutex_unlock(&text_mutex);359 mutex_unlock(&text_mutex);
326 return ret;360 return ret;
@@ -337,6 +371,22 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, · 10 unmodified lines
337 return __bpf_arch_text_poke(ip, t, old_addr, new_addr, true);371 return __bpf_arch_text_poke(ip, t, old_addr, new_addr, true);
338}372}
339 373
374static int get_pop_bytes(bool *callee_regs_used)
375{
376 int bytes = 0;
377
378 if (callee_regs_used[3])
379 bytes += 2;
380 if (callee_regs_used[2])
381 bytes += 2;
382 if (callee_regs_used[1])
383 bytes += 2;
384 if (callee_regs_used[0])
385 bytes += 1;
386
387 return bytes;
388}
389
340/*390/*
341 * Generate the following code:391 * Generate the following code:
342 *392 *
@@ -351,12 +401,26 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, · 8 unmodified lines
351 * goto *(prog->bpf_func + prologue_size);401 * goto *(prog->bpf_func + prologue_size);
352 * out:402 * out:
353 */403 */
354static void emit_bpf_tail_call_indirect(u8 **pprog)404static void emit_bpf_tail_call_indirect(u8 **pprog, bool *callee_regs_used,
405 u32 stack_depth)
355{406{
407 int tcc_off = -4 - round_up(stack_depth, 8);
356 u8 *prog = *pprog;408 u8 *prog = *pprog;
357 int label1, label2, label3;409 int pop_bytes = 0;
410 int off1 = 49;
411 int off2 = 38;
412 int off3 = 16;
358 int cnt = 0;413 int cnt = 0;
359 414
415 /* count the additional bytes used for popping callee regs from stack
416 * that need to be taken into account for each of the offsets that
417 * are used for bailing out of the tail call
418 */
419 pop_bytes = get_pop_bytes(callee_regs_used);
420 off1 += pop_bytes;
421 off2 += pop_bytes;
422 off3 += pop_bytes;
423
360 /*424 /*
361 * rdi - pointer to ctx425 * rdi - pointer to ctx
362 * rsi - pointer to bpf_array426 * rsi - pointer to bpf_array
@@ -370,21 +434,19 @@ static void emit_bpf_tail_call_indirect(u8 **pprog) · 7 unmodified lines
370 EMIT2(0x89, 0xD2); /* mov edx, edx */434 EMIT2(0x89, 0xD2); /* mov edx, edx */
371 EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */435 EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */
372 offsetof(struct bpf_array, map.max_entries));436 offsetof(struct bpf_array, map.max_entries));
373#define OFFSET1 (41 + RETPOLINE_RCX_BPF_JIT_SIZE) /* Number of bytes to jump */437#define OFFSET1 (off1 + RETPOLINE_RCX_BPF_JIT_SIZE) /* Number of bytes to jump */
374 EMIT2(X86_JBE, OFFSET1); /* jbe out */438 EMIT2(X86_JBE, OFFSET1); /* jbe out */
375 label1 = cnt;
376 439
377 /*440 /*
378 * if (tail_call_cnt > MAX_TAIL_CALL_CNT)441 * if (tail_call_cnt > MAX_TAIL_CALL_CNT)
379 * goto out;442 * goto out;
380 */443 */
381 EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */444 EMIT2_off32(0x8B, 0x85, tcc_off); /* mov eax, dword ptr [rbp - tcc_off] */
382 EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */445 EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
383#define OFFSET2 (30 + RETPOLINE_RCX_BPF_JIT_SIZE)446#define OFFSET2 (off2 + RETPOLINE_RCX_BPF_JIT_SIZE)
384 EMIT2(X86_JA, OFFSET2); /* ja out */447 EMIT2(X86_JA, OFFSET2); /* ja out */
385 label2 = cnt;
386 EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */448 EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
387 EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */449 EMIT2_off32(0x89, 0x85, tcc_off); /* mov dword ptr [rbp - tcc_off], eax */
388 450
389 /* prog = array->ptrs[index]; */451 /* prog = array->ptrs[index]; */
390 EMIT4_off32(0x48, 0x8B, 0x8C, 0xD6, /* mov rcx, [rsi + rdx * 8 + offsetof(...)] */452 EMIT4_off32(0x48, 0x8B, 0x8C, 0xD6, /* mov rcx, [rsi + rdx * 8 + offsetof(...)] */
@@ -394,48 +456,84 @@ static void emit_bpf_tail_call_indirect(u8 **pprog) · 3 unmodified lines
394 * if (prog == NULL)456 * if (prog == NULL)
395 * goto out;457 * goto out;
396 */458 */
397 EMIT3(0x48, 0x85, 0xC9); /* test rcx,rcx */459 EMIT3(0x48, 0x85, 0xC9); /* test rcx,rcx */
398#define OFFSET3 (8 + RETPOLINE_RCX_BPF_JIT_SIZE)460#define OFFSET3 (off3 + RETPOLINE_RCX_BPF_JIT_SIZE)
399 EMIT2(X86_JE, OFFSET3); /* je out */461 EMIT2(X86_JE, OFFSET3); /* je out */
400 label3 = cnt;
401 462
402 /* goto *(prog->bpf_func + prologue_size); */463 *pprog = prog;
464 pop_callee_regs(pprog, callee_regs_used);
465 prog = *pprog;
466
467 EMIT1(0x58); /* pop rax */
468 EMIT3_off32(0x48, 0x81, 0xC4, /* add rsp, sd */
469 round_up(stack_depth, 8));
470
471 /* goto *(prog->bpf_func + X86_TAIL_CALL_OFFSET); */
403 EMIT4(0x48, 0x8B, 0x49, /* mov rcx, qword ptr [rcx + 32] */472 EMIT4(0x48, 0x8B, 0x49, /* mov rcx, qword ptr [rcx + 32] */
404 offsetof(struct bpf_prog, bpf_func));473 offsetof(struct bpf_prog, bpf_func));
405 EMIT4(0x48, 0x83, 0xC1, PROLOGUE_SIZE); /* add rcx, prologue_size */474 EMIT4(0x48, 0x83, 0xC1, /* add rcx, X86_TAIL_CALL_OFFSET */
406 475 X86_TAIL_CALL_OFFSET);
407 /*476 /*
408 * Now we're ready to jump into next BPF program477 * Now we're ready to jump into next BPF program
409 * rdi == ctx (1st arg)478 * rdi == ctx (1st arg)
410 * rcx == prog->bpf_func + prologue_size479 * rcx == prog->bpf_func + X86_TAIL_CALL_OFFSET
411 */480 */
412 RETPOLINE_RCX_BPF_JIT();481 RETPOLINE_RCX_BPF_JIT();
413 482
414 /* out: */483 /* out: */
415 BUILD_BUG_ON(cnt - label1 != OFFSET1);
416 BUILD_BUG_ON(cnt - label2 != OFFSET2);
417 BUILD_BUG_ON(cnt - label3 != OFFSET3);
418 *pprog = prog;484 *pprog = prog;
419}485}
420 486
421static void emit_bpf_tail_call_direct(struct bpf_jit_poke_descriptor *poke,487static void emit_bpf_tail_call_direct(struct bpf_jit_poke_descriptor *poke,
422 u8 **pprog, int addr, u8 *image)488 u8 **pprog, int addr, u8 *image,
489 bool *callee_regs_used, u32 stack_depth)
423{490{
491 int tcc_off = -4 - round_up(stack_depth, 8);
424 u8 *prog = *pprog;492 u8 *prog = *pprog;
493 int pop_bytes = 0;
494 int off1 = 27;
495 int poke_off;
425 int cnt = 0;496 int cnt = 0;
426 497
498 /* count the additional bytes used for popping callee regs to stack
499 * that need to be taken into account for jump offset that is used for
500 * bailing out from of the tail call when limit is reached
501 */
502 pop_bytes = get_pop_bytes(callee_regs_used);
503 off1 += pop_bytes;
504
505 /*
506 * total bytes for:
507 * - nop5/ jmpq $off
508 * - pop callee regs
509 * - sub rsp, $val
510 * - pop rax
511 */
512 poke_off = X86_PATCH_SIZE + pop_bytes + 7 + 1;
513
427 /*514 /*
428 * if (tail_call_cnt > MAX_TAIL_CALL_CNT)515 * if (tail_call_cnt > MAX_TAIL_CALL_CNT)
429 * goto out;516 * goto out;
430 */517 */
431 EMIT2_off32(0x8B, 0x85, -36 - MAX_BPF_STACK); /* mov eax, dword ptr [rbp - 548] */518 EMIT2_off32(0x8B, 0x85, tcc_off); /* mov eax, dword ptr [rbp - tcc_off] */
432 EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */519 EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
433 EMIT2(X86_JA, 14); /* ja out */520 EMIT2(X86_JA, off1); /* ja out */
434 EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */521 EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
435 EMIT2_off32(0x89, 0x85, -36 - MAX_BPF_STACK); /* mov dword ptr [rbp -548], eax */522 EMIT2_off32(0x89, 0x85, tcc_off); /* mov dword ptr [rbp - tcc_off], eax */
436 523
524 poke->tailcall_bypass = image + (addr - poke_off - X86_PATCH_SIZE);
525 poke->adj_off = X86_TAIL_CALL_OFFSET;
437 poke->tailcall_target = image + (addr - X86_PATCH_SIZE);526 poke->tailcall_target = image + (addr - X86_PATCH_SIZE);
438 poke->adj_off = PROLOGUE_SIZE;527 poke->bypass_addr = (u8 *)poke->tailcall_target + X86_PATCH_SIZE;
528
529 emit_jump(&prog, (u8 *)poke->tailcall_target + X86_PATCH_SIZE,
530 poke->tailcall_bypass);
531
532 *pprog = prog;
533 pop_callee_regs(pprog, callee_regs_used);
534 prog = *pprog;
535 EMIT1(0x58); /* pop rax */
536 EMIT3_off32(0x48, 0x81, 0xC4, round_up(stack_depth, 8));
439 537
440 memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE);538 memcpy(prog, ideal_nops[NOP_ATOMIC5], X86_PATCH_SIZE);
441 prog += X86_PATCH_SIZE;539 prog += X86_PATCH_SIZE;
@@ -476,6 +574,11 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog) · 34 unmodified lines
476 (u8 *)target->bpf_func +574 (u8 *)target->bpf_func +
477 poke->adj_off, false);575 poke->adj_off, false);
478 BUG_ON(ret < 0);576 BUG_ON(ret < 0);
577 ret = __bpf_arch_text_poke(poke->tailcall_bypass,
578 BPF_MOD_JUMP,
579 (u8 *)poke->tailcall_target +
580 X86_PATCH_SIZE, NULL, false);
581 BUG_ON(ret < 0);
479 }582 }
480 WRITE_ONCE(poke->tailcall_target_stable, true);583 WRITE_ONCE(poke->tailcall_target_stable, true);
481 mutex_unlock(&array->aux->poke_mutex);584 mutex_unlock(&array->aux->poke_mutex);
@@ -654,19 +757,49 @@ static bool ex_handler_bpf(const struct exception_table_entry *x, · 172 unmodified lines
654 return true;757 return true;
655}758}
656 759
760static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt,
761 bool *regs_used, bool *tail_call_seen)
762{
763 int i;
764
765 for (i = 1; i <= insn_cnt; i++, insn++) {
766 if (insn->code == (BPF_JMP | BPF_TAIL_CALL))
767 *tail_call_seen = true;
768 if (insn->dst_reg == BPF_REG_6 || insn->src_reg == BPF_REG_6)
769 regs_used[0] = true;
770 if (insn->dst_reg == BPF_REG_7 || insn->src_reg == BPF_REG_7)
771 regs_used[1] = true;
772 if (insn->dst_reg == BPF_REG_8 || insn->src_reg == BPF_REG_8)
773 regs_used[2] = true;
774 if (insn->dst_reg == BPF_REG_9 || insn->src_reg == BPF_REG_9)
775 regs_used[3] = true;
776 }
777}
778
657static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,779static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
658 int oldproglen, struct jit_context *ctx)780 int oldproglen, struct jit_context *ctx)
659{781{
782 bool tail_call_reachable = bpf_prog->aux->tail_call_reachable;
660 struct bpf_insn *insn = bpf_prog->insnsi;783 struct bpf_insn *insn = bpf_prog->insnsi;
784 bool callee_regs_used[4] = {};
661 int insn_cnt = bpf_prog->len;785 int insn_cnt = bpf_prog->len;
786 bool tail_call_seen = false;
662 bool seen_exit = false;787 bool seen_exit = false;
663 u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];788 u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];
664 int i, cnt = 0, excnt = 0;789 int i, cnt = 0, excnt = 0;
665 int proglen = 0;790 int proglen = 0;
666 u8 *prog = temp;791 u8 *prog = temp;
667 792
793 detect_reg_usage(insn, insn_cnt, callee_regs_used,
794 &tail_call_seen);
795
796 /* tail call's presence in current prog implies it is reachable */
797 tail_call_reachable |= tail_call_seen;
798
668 emit_prologue(&prog, bpf_prog->aux->stack_depth,799 emit_prologue(&prog, bpf_prog->aux->stack_depth,
669 bpf_prog_was_classic(bpf_prog));800 bpf_prog_was_classic(bpf_prog), tail_call_reachable,
801 bpf_prog->aux->func_idx != 0);
802 push_callee_regs(&prog, callee_regs_used);
670 addrs[0] = prog - temp;803 addrs[0] = prog - temp;
671 804
672 for (i = 1; i <= insn_cnt; i++, insn++) {805 for (i = 1; i <= insn_cnt; i++, insn++) {
@@ -1104,16 +1237,27 @@ xadd: if (is_imm8(insn->off)) · 431 unmodified lines
1104 /* call */1237 /* call */
1105 case BPF_JMP | BPF_CALL:1238 case BPF_JMP | BPF_CALL:
1106 func = (u8 *) __bpf_call_base + imm32;1239 func = (u8 *) __bpf_call_base + imm32;
1107 if (!imm32 || emit_call(&prog, func, image + addrs[i - 1]))1240 if (tail_call_reachable) {
1108 return -EINVAL;1241 EMIT3_off32(0x48, 0x8B, 0x85,
1242 -(bpf_prog->aux->stack_depth + 8));
1243 if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7))
1244 return -EINVAL;
1245 } else {
1246 if (!imm32 || emit_call(&prog, func, image + addrs[i - 1]))
1247 return -EINVAL;
1248 }
1109 break;1249 break;
1110 1250
1111 case BPF_JMP | BPF_TAIL_CALL:1251 case BPF_JMP | BPF_TAIL_CALL:
1112 if (imm32)1252 if (imm32)
1113 emit_bpf_tail_call_direct(&bpf_prog->aux->poke_tab[imm32 - 1],1253 emit_bpf_tail_call_direct(&bpf_prog->aux->poke_tab[imm32 - 1],
1114 &prog, addrs[i], image);1254 &prog, addrs[i], image,
1255 callee_regs_used,
1256 bpf_prog->aux->stack_depth);
1115 else1257 else
1116 emit_bpf_tail_call_indirect(&prog);1258 emit_bpf_tail_call_indirect(&prog,
1259 callee_regs_used,
1260 bpf_prog->aux->stack_depth);
1117 break;1261 break;
1118 1262
1119 /* cond jump */1263 /* cond jump */
@@ -1296,12 +1440,9 @@ emit_jmp: · 176 unmodified lines
1296 seen_exit = true;1440 seen_exit = true;
1297 /* Update cleanup_addr */1441 /* Update cleanup_addr */
1298 ctx->cleanup_addr = proglen;1442 ctx->cleanup_addr = proglen;
1299 if (!bpf_prog_was_classic(bpf_prog))1443 pop_callee_regs(&prog, callee_regs_used);
1300 EMIT1(0x5B); /* get rid of tail_call_cnt */1444 if (tail_call_reachable)
1301 EMIT2(0x41, 0x5F); /* pop r15 */1445 EMIT1(0x59); /* pop rcx, get rid of tail_call_cnt */
1302 EMIT2(0x41, 0x5E); /* pop r14 */
1303 EMIT2(0x41, 0x5D); /* pop r13 */
1304 EMIT1(0x5B); /* pop rbx */
1305 EMIT1(0xC9); /* leave */1446 EMIT1(0xC9); /* leave */
1306 EMIT1(0xC3); /* ret */1447 EMIT1(0xC3); /* ret */
1307 break;1448 break;
include/linux/bpf.h+3−0
@@ -698,6 +698,8 @@ enum bpf_jit_poke_reason { · 697 unmodified lines
698/* Descriptor of pokes pointing /into/ the JITed image. */698/* Descriptor of pokes pointing /into/ the JITed image. */
699struct bpf_jit_poke_descriptor {699struct bpf_jit_poke_descriptor {
700 void *tailcall_target;700 void *tailcall_target;
701 void *tailcall_bypass;
702 void *bypass_addr;
701 union {703 union {
702 struct {704 struct {
703 struct bpf_map *map;705 struct bpf_map *map;
@@ -738,6 +740,7 @@ struct bpf_prog_aux { · 34 unmodified lines
738 bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */740 bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
739 bool func_proto_unreliable;741 bool func_proto_unreliable;
740 bool sleepable;742 bool sleepable;
743 bool tail_call_reachable;
741 enum bpf_tramp_prog_type trampoline_prog_type;744 enum bpf_tramp_prog_type trampoline_prog_type;
742 struct bpf_trampoline *trampoline;745 struct bpf_trampoline *trampoline;
743 struct hlist_node tramp_hlist;746 struct hlist_node tramp_hlist;
include/linux/bpf_verifier.h+1−0
@@ -359,6 +359,7 @@ struct bpf_subprog_info { · 358 unmodified lines
359 u32 linfo_idx; /* The idx to the main_prog->aux->linfo */359 u32 linfo_idx; /* The idx to the main_prog->aux->linfo */
360 u16 stack_depth; /* max. stack depth used by this function */360 u16 stack_depth; /* max. stack depth used by this function */
361 bool has_tail_call;361 bool has_tail_call;
362 bool tail_call_reachable;
362};363};
363 364
364/* single container for all structs365/* single container for all structs
kernel/bpf/arraymap.c+34−6
@@ -898,6 +898,7 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key, · 897 unmodified lines
898 struct bpf_prog *old,898 struct bpf_prog *old,
899 struct bpf_prog *new)899 struct bpf_prog *new)
900{900{
901 u8 *old_addr, *new_addr, *old_bypass_addr;
901 struct prog_poke_elem *elem;902 struct prog_poke_elem *elem;
902 struct bpf_array_aux *aux;903 struct bpf_array_aux *aux;
903 904
@@ -949,12 +950,39 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key, · 45 unmodified lines
949 poke->tail_call.key != key)950 poke->tail_call.key != key)
950 continue;951 continue;
951 952
952 ret = bpf_arch_text_poke(poke->tailcall_target, BPF_MOD_JUMP,953 old_bypass_addr = old ? NULL : poke->bypass_addr;
953 old ? (u8 *)old->bpf_func +954 old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL;
954 poke->adj_off : NULL,955 new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL;
955 new ? (u8 *)new->bpf_func +956
956 poke->adj_off : NULL);957 if (new) {
957 BUG_ON(ret < 0 && ret != -EINVAL);958 ret = bpf_arch_text_poke(poke->tailcall_target,
959 BPF_MOD_JUMP,
960 old_addr, new_addr);
961 BUG_ON(ret < 0 && ret != -EINVAL);
962 if (!old) {
963 ret = bpf_arch_text_poke(poke->tailcall_bypass,
964 BPF_MOD_JUMP,
965 poke->bypass_addr,
966 NULL);
967 BUG_ON(ret < 0 && ret != -EINVAL);
968 }
969 } else {
970 ret = bpf_arch_text_poke(poke->tailcall_bypass,
971 BPF_MOD_JUMP,
972 old_bypass_addr,
973 poke->bypass_addr);
974 BUG_ON(ret < 0 && ret != -EINVAL);
975 /* let other CPUs finish the execution of program
976 * so that it will not possible to expose them
977 * to invalid nop, stack unwind, nop state
978 */
979 if (!ret)
980 synchronize_rcu();
981 ret = bpf_arch_text_poke(poke->tailcall_target,
982 BPF_MOD_JUMP,
983 old_addr, NULL);
984 BUG_ON(ret < 0 && ret != -EINVAL);
985 }
958 }986 }
959 }987 }
960}988}
kernel/bpf/core.c+1−1
@@ -776,7 +776,7 @@ int bpf_jit_add_poke_descriptor(struct bpf_prog *prog, · 775 unmodified lines
776 if (size > poke_tab_max)776 if (size > poke_tab_max)
777 return -ENOSPC;777 return -ENOSPC;
778 if (poke->tailcall_target || poke->tailcall_target_stable ||778 if (poke->tailcall_target || poke->tailcall_target_stable ||
779 poke->adj_off)779 poke->tailcall_bypass || poke->adj_off || poke->bypass_addr)
780 return -EINVAL;780 return -EINVAL;
781 781
782 switch (poke->reason) {782 switch (poke->reason) {
kernel/bpf/verifier.c+16−0
@@ -2983,8 +2983,10 @@ static int check_max_stack_depth(struct bpf_verifier_env *env) · 2982 unmodified lines
2983 int depth = 0, frame = 0, idx = 0, i = 0, subprog_end;2983 int depth = 0, frame = 0, idx = 0, i = 0, subprog_end;
2984 struct bpf_subprog_info *subprog = env->subprog_info;2984 struct bpf_subprog_info *subprog = env->subprog_info;
2985 struct bpf_insn *insn = env->prog->insnsi;2985 struct bpf_insn *insn = env->prog->insnsi;
2986 bool tail_call_reachable = false;
2986 int ret_insn[MAX_CALL_FRAMES];2987 int ret_insn[MAX_CALL_FRAMES];
2987 int ret_prog[MAX_CALL_FRAMES];2988 int ret_prog[MAX_CALL_FRAMES];
2989 int j;
2988 2990
2989process_func:2991process_func:
2990 /* protect against potential stack overflow that might happen when2992 /* protect against potential stack overflow that might happen when
@@ -3040,6 +3042,10 @@ continue_func: · 49 unmodified lines
3040 i);3042 i);
3041 return -EFAULT;3043 return -EFAULT;
3042 }3044 }
3045
3046 if (subprog[idx].has_tail_call)
3047 tail_call_reachable = true;
3048
3043 frame++;3049 frame++;
3044 if (frame >= MAX_CALL_FRAMES) {3050 if (frame >= MAX_CALL_FRAMES) {
3045 verbose(env, "the call stack of %d frames is too deep !\n",3051 verbose(env, "the call stack of %d frames is too deep !\n",
@@ -3048,6 +3054,15 @@ continue_func: · 2 unmodified lines
3048 }3054 }
3049 goto process_func;3055 goto process_func;
3050 }3056 }
3057 /* if tail call got detected across bpf2bpf calls then mark each of the
3058 * currently present subprog frames as tail call reachable subprogs;
3059 * this info will be utilized by JIT so that we will be preserving the
3060 * tail call counter throughout bpf2bpf calls combined with tailcalls
3061 */
3062 if (tail_call_reachable)
3063 for (j = 0; j < frame; j++)
3064 subprog[ret_prog[j]].tail_call_reachable = true;
3065
3051 /* end of for() loop means the last insn of the 'subprog'3066 /* end of for() loop means the last insn of the 'subprog'
3052 * was reached. Doesn't matter whether it was JA or EXIT3067 * was reached. Doesn't matter whether it was JA or EXIT
3053 */3068 */
@@ -10322,6 +10337,7 @@ static int jit_subprogs(struct bpf_verifier_env *env) · 7268 unmodified lines
10322 num_exentries++;10337 num_exentries++;
10323 }10338 }
10324 func[i]->aux->num_exentries = num_exentries;10339 func[i]->aux->num_exentries = num_exentries;
10340 func[i]->aux->tail_call_reachable = env->subprog_info[i].tail_call_reachable;
10325 func[i] = bpf_int_jit_compile(func[i]);10341 func[i] = bpf_int_jit_compile(func[i]);
10326 if (!func[i]->jited) {10342 if (!func[i]->jited) {
10327 err = -ENOTSUPP;10343 err = -ENOTSUPP;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t