Skip to content

Commit

Permalink
selftests/bpf: Add tracing prog private stack tests
Browse files Browse the repository at this point in the history
Some private stack tests are added including:
  - prog with stack size greater than BPF_PSTACK_MIN_SUBTREE_SIZE.
  - prog with stack size less than BPF_PSTACK_MIN_SUBTREE_SIZE.
  - prog with one subprog having MAX_BPF_STACK stack size and another
    subprog having non-zero stack size.
  - prog with callback function.
  - prog with exception in main prog or subprog.

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
  • Loading branch information
Yonghong Song authored and intel-lab-lkp committed Oct 20, 2024
1 parent fe9312f commit 888a46e
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "verifier_or_jmp32_k.skel.h"
#include "verifier_precision.skel.h"
#include "verifier_prevent_map_lookup.skel.h"
#include "verifier_private_stack.skel.h"
#include "verifier_raw_stack.skel.h"
#include "verifier_raw_tp_writable.skel.h"
#include "verifier_reg_equal.skel.h"
Expand Down Expand Up @@ -185,6 +186,7 @@ void test_verifier_bpf_fastcall(void) { RUN(verifier_bpf_fastcall); }
void test_verifier_or_jmp32_k(void) { RUN(verifier_or_jmp32_k); }
void test_verifier_precision(void) { RUN(verifier_precision); }
void test_verifier_prevent_map_lookup(void) { RUN(verifier_prevent_map_lookup); }
void test_verifier_private_stack(void) { RUN(verifier_private_stack); }
void test_verifier_raw_stack(void) { RUN(verifier_raw_stack); }
void test_verifier_raw_tp_writable(void) { RUN(verifier_raw_tp_writable); }
void test_verifier_reg_equal(void) { RUN(verifier_reg_equal); }
Expand Down
216 changes: 216 additions & 0 deletions tools/testing/selftests/bpf/progs/verifier_private_stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
// SPDX-License-Identifier: GPL-2.0

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"

/* From include/linux/filter.h */
#define MAX_BPF_STACK 512

#if defined(__TARGET_ARCH_x86)

SEC("kprobe")
__description("Private stack, single prog")
__success
__arch_x86_64
__jited(" movabsq $0x{{.*}}, %r9")
__jited(" addq %gs:0x{{.*}}, %r9")
__jited(" movl $0x2a, %edi")
__jited(" movq %rdi, -0x100(%r9)")
__naked void private_stack_single_prog(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - 256) = r1;"
"r0 = 0;"
"exit;"
:
:
: __clobber_all);
}

__used
__naked static void cumulative_stack_depth_subprog(void)
{
asm volatile (
"r1 = 41;"
"*(u64 *)(r10 - 32) = r1;"
"call %[bpf_get_smp_processor_id];"
"exit;"
:: __imm(bpf_get_smp_processor_id)
: __clobber_all);
}

SEC("kprobe")
__description("Private stack, subtree > MAX_BPF_STACK")
__success
__arch_x86_64
/* private stack fp for the main prog */
__jited(" movabsq $0x{{.*}}, %r9")
__jited(" addq %gs:0x{{.*}}, %r9")
__jited(" movl $0x2a, %edi")
__jited(" movq %rdi, -0x200(%r9)")
__jited(" pushq %r9")
__jited(" callq 0x{{.*}}")
__jited(" popq %r9")
__jited(" xorl %eax, %eax")
__naked void private_stack_nested_1(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - %[max_bpf_stack]) = r1;"
"call cumulative_stack_depth_subprog;"
"r0 = 0;"
"exit;"
:
: __imm_const(max_bpf_stack, MAX_BPF_STACK)
: __clobber_all);
}

SEC("kprobe")
__description("Private stack, subtree > MAX_BPF_STACK")
__success
__arch_x86_64
/* private stack fp for the subprog */
__jited(" addq $0x20, %r9")
__naked void private_stack_nested_2(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - %[max_bpf_stack]) = r1;"
"call cumulative_stack_depth_subprog;"
"r0 = 0;"
"exit;"
:
: __imm_const(max_bpf_stack, MAX_BPF_STACK)
: __clobber_all);
}

SEC("raw_tp")
__description("No private stack, nested")
__success
__arch_x86_64
__jited(" subq $0x8, %rsp")
__naked void no_private_stack_nested(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - 8) = r1;"
"call cumulative_stack_depth_subprog;"
"r0 = 0;"
"exit;"
:
:
: __clobber_all);
}

__naked __noinline __used
static unsigned long loop_callback(void)
{
asm volatile (
"call %[bpf_get_prandom_u32];"
"r1 = 42;"
"*(u64 *)(r10 - 512) = r1;"
"call cumulative_stack_depth_subprog;"
"r0 = 0;"
"exit;"
:
: __imm(bpf_get_prandom_u32)
: __clobber_common);
}

SEC("raw_tp")
__description("Private stack, callback")
__success
__arch_x86_64
/* for func loop_callback */
__jited("func #1")
__jited(" endbr64")
__jited(" nopl (%rax,%rax)")
__jited(" nopl (%rax)")
__jited(" pushq %rbp")
__jited(" movq %rsp, %rbp")
__jited(" endbr64")
__jited(" movabsq $0x{{.*}}, %r9")
__jited(" addq %gs:0x{{.*}}, %r9")
__jited(" pushq %r9")
__jited(" callq")
__jited(" popq %r9")
__jited(" movl $0x2a, %edi")
__jited(" movq %rdi, -0x200(%r9)")
__jited(" pushq %r9")
__jited(" callq")
__jited(" popq %r9")
__naked void private_stack_callback(void)
{
asm volatile (
"r1 = 1;"
"r2 = %[loop_callback];"
"r3 = 0;"
"r4 = 0;"
"call %[bpf_loop];"
"r0 = 0;"
"exit;"
:
: __imm_ptr(loop_callback),
__imm(bpf_loop)
: __clobber_common);
}

SEC("fentry/bpf_fentry_test9")
__description("Private stack, exception in main prog")
__success __retval(0)
__arch_x86_64
__jited(" pushq %r9")
__jited(" callq")
__jited(" popq %r9")
int private_stack_exception_main_prog(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - 512) = r1;"
::: __clobber_common);

bpf_throw(0);
return 0;
}

__used static int subprog_exception(void)
{
bpf_throw(0);
return 0;
}

SEC("fentry/bpf_fentry_test9")
__description("Private stack, exception in subprog")
__success __retval(0)
__arch_x86_64
__jited(" movq %rdi, -0x200(%r9)")
__jited(" pushq %r9")
__jited(" callq")
__jited(" popq %r9")
int private_stack_exception_sub_prog(void)
{
asm volatile (
"r1 = 42;"
"*(u64 *)(r10 - 512) = r1;"
"call subprog_exception;"
::: __clobber_common);

return 0;
}

#else

SEC("kprobe")
__description("private stack is not supported, use a dummy test")
__success
int dummy_test(void)
{
return 0;
}

#endif

char _license[] SEC("license") = "GPL";

0 comments on commit 888a46e

Please sign in to comment.