1*f4b295abSYonghong Song // SPDX-License-Identifier: GPL-2.0 2*f4b295abSYonghong Song 3*f4b295abSYonghong Song #include <vmlinux.h> 4*f4b295abSYonghong Song #include <bpf/bpf_helpers.h> 5*f4b295abSYonghong Song #include "bpf_misc.h" 6*f4b295abSYonghong Song #include "bpf_experimental.h" 7*f4b295abSYonghong Song 8*f4b295abSYonghong Song /* From include/linux/filter.h */ 9*f4b295abSYonghong Song #define MAX_BPF_STACK 512 10*f4b295abSYonghong Song 11*f4b295abSYonghong Song #if defined(__TARGET_ARCH_x86) 12*f4b295abSYonghong Song 13*f4b295abSYonghong Song struct elem { 14*f4b295abSYonghong Song struct bpf_timer t; 15*f4b295abSYonghong Song char pad[256]; 16*f4b295abSYonghong Song }; 17*f4b295abSYonghong Song 18*f4b295abSYonghong Song struct { 19*f4b295abSYonghong Song __uint(type, BPF_MAP_TYPE_ARRAY); 20*f4b295abSYonghong Song __uint(max_entries, 1); 21*f4b295abSYonghong Song __type(key, int); 22*f4b295abSYonghong Song __type(value, struct elem); 23*f4b295abSYonghong Song } array SEC(".maps"); 24*f4b295abSYonghong Song 25*f4b295abSYonghong Song SEC("kprobe") 26*f4b295abSYonghong Song __description("Private stack, single prog") 27*f4b295abSYonghong Song __success 28*f4b295abSYonghong Song __arch_x86_64 29*f4b295abSYonghong Song __jited(" movabsq $0x{{.*}}, %r9") 30*f4b295abSYonghong Song __jited(" addq %gs:0x{{.*}}, %r9") 31*f4b295abSYonghong Song __jited(" movl $0x2a, %edi") 32*f4b295abSYonghong Song __jited(" movq %rdi, -0x100(%r9)") 33*f4b295abSYonghong Song __naked void private_stack_single_prog(void) 34*f4b295abSYonghong Song { 35*f4b295abSYonghong Song asm volatile (" \ 36*f4b295abSYonghong Song r1 = 42; \ 37*f4b295abSYonghong Song *(u64 *)(r10 - 256) = r1; \ 38*f4b295abSYonghong Song r0 = 0; \ 39*f4b295abSYonghong Song exit; \ 40*f4b295abSYonghong Song " ::: __clobber_all); 41*f4b295abSYonghong Song } 42*f4b295abSYonghong Song 43*f4b295abSYonghong Song SEC("raw_tp") 44*f4b295abSYonghong Song __description("No private stack") 45*f4b295abSYonghong Song __success 46*f4b295abSYonghong Song __arch_x86_64 47*f4b295abSYonghong Song __jited(" subq $0x8, %rsp") 48*f4b295abSYonghong Song __naked void no_private_stack_nested(void) 49*f4b295abSYonghong Song { 50*f4b295abSYonghong Song asm volatile (" \ 51*f4b295abSYonghong Song r1 = 42; \ 52*f4b295abSYonghong Song *(u64 *)(r10 - 8) = r1; \ 53*f4b295abSYonghong Song r0 = 0; \ 54*f4b295abSYonghong Song exit; \ 55*f4b295abSYonghong Song " ::: __clobber_all); 56*f4b295abSYonghong Song } 57*f4b295abSYonghong Song 58*f4b295abSYonghong Song __used 59*f4b295abSYonghong Song __naked static void cumulative_stack_depth_subprog(void) 60*f4b295abSYonghong Song { 61*f4b295abSYonghong Song asm volatile (" \ 62*f4b295abSYonghong Song r1 = 41; \ 63*f4b295abSYonghong Song *(u64 *)(r10 - 32) = r1; \ 64*f4b295abSYonghong Song call %[bpf_get_smp_processor_id]; \ 65*f4b295abSYonghong Song exit; \ 66*f4b295abSYonghong Song " : 67*f4b295abSYonghong Song : __imm(bpf_get_smp_processor_id) 68*f4b295abSYonghong Song : __clobber_all); 69*f4b295abSYonghong Song } 70*f4b295abSYonghong Song 71*f4b295abSYonghong Song SEC("kprobe") 72*f4b295abSYonghong Song __description("Private stack, subtree > MAX_BPF_STACK") 73*f4b295abSYonghong Song __success 74*f4b295abSYonghong Song __arch_x86_64 75*f4b295abSYonghong Song /* private stack fp for the main prog */ 76*f4b295abSYonghong Song __jited(" movabsq $0x{{.*}}, %r9") 77*f4b295abSYonghong Song __jited(" addq %gs:0x{{.*}}, %r9") 78*f4b295abSYonghong Song __jited(" movl $0x2a, %edi") 79*f4b295abSYonghong Song __jited(" movq %rdi, -0x200(%r9)") 80*f4b295abSYonghong Song __jited(" pushq %r9") 81*f4b295abSYonghong Song __jited(" callq 0x{{.*}}") 82*f4b295abSYonghong Song __jited(" popq %r9") 83*f4b295abSYonghong Song __jited(" xorl %eax, %eax") 84*f4b295abSYonghong Song __naked void private_stack_nested_1(void) 85*f4b295abSYonghong Song { 86*f4b295abSYonghong Song asm volatile (" \ 87*f4b295abSYonghong Song r1 = 42; \ 88*f4b295abSYonghong Song *(u64 *)(r10 - %[max_bpf_stack]) = r1; \ 89*f4b295abSYonghong Song call cumulative_stack_depth_subprog; \ 90*f4b295abSYonghong Song r0 = 0; \ 91*f4b295abSYonghong Song exit; \ 92*f4b295abSYonghong Song " : 93*f4b295abSYonghong Song : __imm_const(max_bpf_stack, MAX_BPF_STACK) 94*f4b295abSYonghong Song : __clobber_all); 95*f4b295abSYonghong Song } 96*f4b295abSYonghong Song 97*f4b295abSYonghong Song __naked __noinline __used 98*f4b295abSYonghong Song static unsigned long loop_callback(void) 99*f4b295abSYonghong Song { 100*f4b295abSYonghong Song asm volatile (" \ 101*f4b295abSYonghong Song call %[bpf_get_prandom_u32]; \ 102*f4b295abSYonghong Song r1 = 42; \ 103*f4b295abSYonghong Song *(u64 *)(r10 - 512) = r1; \ 104*f4b295abSYonghong Song call cumulative_stack_depth_subprog; \ 105*f4b295abSYonghong Song r0 = 0; \ 106*f4b295abSYonghong Song exit; \ 107*f4b295abSYonghong Song " : 108*f4b295abSYonghong Song : __imm(bpf_get_prandom_u32) 109*f4b295abSYonghong Song : __clobber_common); 110*f4b295abSYonghong Song } 111*f4b295abSYonghong Song 112*f4b295abSYonghong Song SEC("raw_tp") 113*f4b295abSYonghong Song __description("Private stack, callback") 114*f4b295abSYonghong Song __success 115*f4b295abSYonghong Song __arch_x86_64 116*f4b295abSYonghong Song /* for func loop_callback */ 117*f4b295abSYonghong Song __jited("func #1") 118*f4b295abSYonghong Song __jited(" endbr64") 119*f4b295abSYonghong Song __jited(" nopl (%rax,%rax)") 120*f4b295abSYonghong Song __jited(" nopl (%rax)") 121*f4b295abSYonghong Song __jited(" pushq %rbp") 122*f4b295abSYonghong Song __jited(" movq %rsp, %rbp") 123*f4b295abSYonghong Song __jited(" endbr64") 124*f4b295abSYonghong Song __jited(" movabsq $0x{{.*}}, %r9") 125*f4b295abSYonghong Song __jited(" addq %gs:0x{{.*}}, %r9") 126*f4b295abSYonghong Song __jited(" pushq %r9") 127*f4b295abSYonghong Song __jited(" callq") 128*f4b295abSYonghong Song __jited(" popq %r9") 129*f4b295abSYonghong Song __jited(" movl $0x2a, %edi") 130*f4b295abSYonghong Song __jited(" movq %rdi, -0x200(%r9)") 131*f4b295abSYonghong Song __jited(" pushq %r9") 132*f4b295abSYonghong Song __jited(" callq") 133*f4b295abSYonghong Song __jited(" popq %r9") 134*f4b295abSYonghong Song __naked void private_stack_callback(void) 135*f4b295abSYonghong Song { 136*f4b295abSYonghong Song asm volatile (" \ 137*f4b295abSYonghong Song r1 = 1; \ 138*f4b295abSYonghong Song r2 = %[loop_callback]; \ 139*f4b295abSYonghong Song r3 = 0; \ 140*f4b295abSYonghong Song r4 = 0; \ 141*f4b295abSYonghong Song call %[bpf_loop]; \ 142*f4b295abSYonghong Song r0 = 0; \ 143*f4b295abSYonghong Song exit; \ 144*f4b295abSYonghong Song " : 145*f4b295abSYonghong Song : __imm_ptr(loop_callback), 146*f4b295abSYonghong Song __imm(bpf_loop) 147*f4b295abSYonghong Song : __clobber_common); 148*f4b295abSYonghong Song } 149*f4b295abSYonghong Song 150*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9") 151*f4b295abSYonghong Song __description("Private stack, exception in main prog") 152*f4b295abSYonghong Song __success __retval(0) 153*f4b295abSYonghong Song __arch_x86_64 154*f4b295abSYonghong Song __jited(" pushq %r9") 155*f4b295abSYonghong Song __jited(" callq") 156*f4b295abSYonghong Song __jited(" popq %r9") 157*f4b295abSYonghong Song int private_stack_exception_main_prog(void) 158*f4b295abSYonghong Song { 159*f4b295abSYonghong Song asm volatile (" \ 160*f4b295abSYonghong Song r1 = 42; \ 161*f4b295abSYonghong Song *(u64 *)(r10 - 512) = r1; \ 162*f4b295abSYonghong Song " ::: __clobber_common); 163*f4b295abSYonghong Song 164*f4b295abSYonghong Song bpf_throw(0); 165*f4b295abSYonghong Song return 0; 166*f4b295abSYonghong Song } 167*f4b295abSYonghong Song 168*f4b295abSYonghong Song __used static int subprog_exception(void) 169*f4b295abSYonghong Song { 170*f4b295abSYonghong Song bpf_throw(0); 171*f4b295abSYonghong Song return 0; 172*f4b295abSYonghong Song } 173*f4b295abSYonghong Song 174*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9") 175*f4b295abSYonghong Song __description("Private stack, exception in subprog") 176*f4b295abSYonghong Song __success __retval(0) 177*f4b295abSYonghong Song __arch_x86_64 178*f4b295abSYonghong Song __jited(" movq %rdi, -0x200(%r9)") 179*f4b295abSYonghong Song __jited(" pushq %r9") 180*f4b295abSYonghong Song __jited(" callq") 181*f4b295abSYonghong Song __jited(" popq %r9") 182*f4b295abSYonghong Song int private_stack_exception_sub_prog(void) 183*f4b295abSYonghong Song { 184*f4b295abSYonghong Song asm volatile (" \ 185*f4b295abSYonghong Song r1 = 42; \ 186*f4b295abSYonghong Song *(u64 *)(r10 - 512) = r1; \ 187*f4b295abSYonghong Song call subprog_exception; \ 188*f4b295abSYonghong Song " ::: __clobber_common); 189*f4b295abSYonghong Song 190*f4b295abSYonghong Song return 0; 191*f4b295abSYonghong Song } 192*f4b295abSYonghong Song 193*f4b295abSYonghong Song int glob; 194*f4b295abSYonghong Song __noinline static void subprog2(int *val) 195*f4b295abSYonghong Song { 196*f4b295abSYonghong Song glob += val[0] * 2; 197*f4b295abSYonghong Song } 198*f4b295abSYonghong Song 199*f4b295abSYonghong Song __noinline static void subprog1(int *val) 200*f4b295abSYonghong Song { 201*f4b295abSYonghong Song int tmp[64] = {}; 202*f4b295abSYonghong Song 203*f4b295abSYonghong Song tmp[0] = *val; 204*f4b295abSYonghong Song subprog2(tmp); 205*f4b295abSYonghong Song } 206*f4b295abSYonghong Song 207*f4b295abSYonghong Song __noinline static int timer_cb1(void *map, int *key, struct bpf_timer *timer) 208*f4b295abSYonghong Song { 209*f4b295abSYonghong Song subprog1(key); 210*f4b295abSYonghong Song return 0; 211*f4b295abSYonghong Song } 212*f4b295abSYonghong Song 213*f4b295abSYonghong Song __noinline static int timer_cb2(void *map, int *key, struct bpf_timer *timer) 214*f4b295abSYonghong Song { 215*f4b295abSYonghong Song return 0; 216*f4b295abSYonghong Song } 217*f4b295abSYonghong Song 218*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9") 219*f4b295abSYonghong Song __description("Private stack, async callback, not nested") 220*f4b295abSYonghong Song __success __retval(0) 221*f4b295abSYonghong Song __arch_x86_64 222*f4b295abSYonghong Song __jited(" movabsq $0x{{.*}}, %r9") 223*f4b295abSYonghong Song int private_stack_async_callback_1(void) 224*f4b295abSYonghong Song { 225*f4b295abSYonghong Song struct bpf_timer *arr_timer; 226*f4b295abSYonghong Song int array_key = 0; 227*f4b295abSYonghong Song 228*f4b295abSYonghong Song arr_timer = bpf_map_lookup_elem(&array, &array_key); 229*f4b295abSYonghong Song if (!arr_timer) 230*f4b295abSYonghong Song return 0; 231*f4b295abSYonghong Song 232*f4b295abSYonghong Song bpf_timer_init(arr_timer, &array, 1); 233*f4b295abSYonghong Song bpf_timer_set_callback(arr_timer, timer_cb2); 234*f4b295abSYonghong Song bpf_timer_start(arr_timer, 0, 0); 235*f4b295abSYonghong Song subprog1(&array_key); 236*f4b295abSYonghong Song return 0; 237*f4b295abSYonghong Song } 238*f4b295abSYonghong Song 239*f4b295abSYonghong Song SEC("fentry/bpf_fentry_test9") 240*f4b295abSYonghong Song __description("Private stack, async callback, potential nesting") 241*f4b295abSYonghong Song __success __retval(0) 242*f4b295abSYonghong Song __arch_x86_64 243*f4b295abSYonghong Song __jited(" subq $0x100, %rsp") 244*f4b295abSYonghong Song int private_stack_async_callback_2(void) 245*f4b295abSYonghong Song { 246*f4b295abSYonghong Song struct bpf_timer *arr_timer; 247*f4b295abSYonghong Song int array_key = 0; 248*f4b295abSYonghong Song 249*f4b295abSYonghong Song arr_timer = bpf_map_lookup_elem(&array, &array_key); 250*f4b295abSYonghong Song if (!arr_timer) 251*f4b295abSYonghong Song return 0; 252*f4b295abSYonghong Song 253*f4b295abSYonghong Song bpf_timer_init(arr_timer, &array, 1); 254*f4b295abSYonghong Song bpf_timer_set_callback(arr_timer, timer_cb1); 255*f4b295abSYonghong Song bpf_timer_start(arr_timer, 0, 0); 256*f4b295abSYonghong Song subprog1(&array_key); 257*f4b295abSYonghong Song return 0; 258*f4b295abSYonghong Song } 259*f4b295abSYonghong Song 260*f4b295abSYonghong Song #else 261*f4b295abSYonghong Song 262*f4b295abSYonghong Song SEC("kprobe") 263*f4b295abSYonghong Song __description("private stack is not supported, use a dummy test") 264*f4b295abSYonghong Song __success 265*f4b295abSYonghong Song int dummy_test(void) 266*f4b295abSYonghong Song { 267*f4b295abSYonghong Song return 0; 268*f4b295abSYonghong Song } 269*f4b295abSYonghong Song 270*f4b295abSYonghong Song #endif 271*f4b295abSYonghong Song 272*f4b295abSYonghong Song char _license[] SEC("license") = "GPL"; 273