Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 105 lines 2.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/bpf.h> 3#include <bpf/bpf_helpers.h> 4#include "bpf_misc.h" 5 6int main(void); 7 8struct { 9 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 10 __uint(max_entries, 1); 11 __uint(key_size, sizeof(__u32)); 12 __array(values, void (void)); 13} jmp_table SEC(".maps") = { 14 .values = { 15 [0] = (void *) &main, 16 }, 17}; 18 19__noinline __auxiliary 20static __naked int sub(void) 21{ 22 asm volatile ( 23 "r2 = %[jmp_table] ll;" 24 "r3 = 0;" 25 "call 12;" 26 "exit;" 27 : 28 : __imm_addr(jmp_table) 29 : __clobber_all); 30} 31 32__success 33__arch_x86_64 34/* program entry for main(), regular function prologue */ 35__jited(" endbr64") 36__jited(" nopl (%rax,%rax)") 37__jited(" xorq %rax, %rax") 38__jited(" pushq %rbp") 39__jited(" movq %rsp, %rbp") 40/* tail call prologue for program: 41 * - establish memory location for tail call counter at &rbp[-8]; 42 * - spill tail_call_cnt_ptr at &rbp[-16]; 43 * - expect tail call counter to be passed in rax; 44 * - for entry program rax is a raw counter, value < 33; 45 * - for tail called program rax is tail_call_cnt_ptr (value > 33). 46 */ 47__jited(" endbr64") 48__jited(" cmpq $0x21, %rax") 49__jited(" ja L0") 50__jited(" pushq %rax") 51__jited(" movq %rsp, %rax") 52__jited(" jmp L1") 53__jited("L0: pushq %rax") /* rbp[-8] = rax */ 54__jited("L1: pushq %rax") /* rbp[-16] = rax */ 55/* on subprogram call restore rax to be tail_call_cnt_ptr from rbp[-16] 56 * (cause original rax might be clobbered by this point) 57 */ 58__jited(" movq -0x10(%rbp), %rax") 59__jited(" callq 0x{{.*}}") /* call to sub() */ 60__jited(" xorl %eax, %eax") 61__jited(" leave") 62__jited(" {{(retq|jmp 0x)}}") /* return or jump to rethunk */ 63__jited("...") 64/* subprogram entry for sub(), regular function prologue */ 65__jited(" endbr64") 66__jited(" nopl (%rax,%rax)") 67__jited(" nopl (%rax)") 68__jited(" pushq %rbp") 69__jited(" movq %rsp, %rbp") 70/* tail call prologue for subprogram address of tail call counter 71 * stored at rbp[-16]. 72 */ 73__jited(" endbr64") 74__jited(" pushq %rax") /* rbp[-8] = rax */ 75__jited(" pushq %rax") /* rbp[-16] = rax */ 76__jited(" movabsq ${{.*}}, %rsi") /* r2 = &jmp_table */ 77__jited(" xorl %edx, %edx") /* r3 = 0 */ 78/* bpf_tail_call implementation: 79 * - load tail_call_cnt_ptr from rbp[-16]; 80 * - if *tail_call_cnt_ptr < 33, increment it and jump to target; 81 * - otherwise do nothing. 82 */ 83__jited(" movq -0x10(%rbp), %rax") 84__jited(" cmpq $0x21, (%rax)") 85__jited(" jae L0") 86__jited(" nopl (%rax,%rax)") 87__jited(" addq $0x1, (%rax)") /* *tail_call_cnt_ptr += 1 */ 88__jited(" popq %rax") 89__jited(" popq %rax") 90__jited(" jmp {{.*}}") /* jump to tail call tgt */ 91__jited("L0: leave") 92__jited(" {{(retq|jmp 0x)}}") /* return or jump to rethunk */ 93SEC("tc") 94__naked int main(void) 95{ 96 asm volatile ( 97 "call %[sub];" 98 "r0 = 0;" 99 "exit;" 100 : 101 : __imm(sub) 102 : __clobber_all); 103} 104 105char __license[] SEC("license") = "GPL";