linux/tools/testing/selftests/bpf/test_kmods/bpf_testmod.h

120 lines
2.7 KiB
C
Raw Permalink Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2020 Facebook */
#ifndef _BPF_TESTMOD_H
#define _BPF_TESTMOD_H
#include <linux/types.h>
struct task_struct;
struct cgroup;
struct bpf_testmod_test_read_ctx {
char *buf;
loff_t off;
size_t len;
};
struct bpf_testmod_test_write_ctx {
char *buf;
loff_t off;
size_t len;
};
struct bpf_testmod_test_writable_ctx {
bool early_ret;
int val;
};
/* BPF iter that returns *value* *n* times in a row */
struct bpf_iter_testmod_seq {
s64 value;
int cnt;
};
struct bpf_testmod_ops {
int (*test_1)(void);
void (*test_2)(int a, int b);
/* Used to test nullable arguments. */
int (*test_maybe_null)(int dummy, struct task_struct *task);
int (*unsupported_ops)(void);
/* Used to test ref_acquired arguments. */
int (*test_refcounted)(int dummy, struct task_struct *task);
/* Used to test returning referenced kptr. */
struct task_struct *(*test_return_ref_kptr)(int dummy, struct task_struct *task,
struct cgroup *cgrp);
/* The following fields are used to test shadow copies. */
char onebyte;
struct {
int a;
int b;
} unsupported;
int data;
/* The following pointers are used to test the maps having multiple
* pages of trampolines.
*/
int (*tramp_1)(int value);
int (*tramp_2)(int value);
int (*tramp_3)(int value);
int (*tramp_4)(int value);
int (*tramp_5)(int value);
int (*tramp_6)(int value);
int (*tramp_7)(int value);
int (*tramp_8)(int value);
int (*tramp_9)(int value);
int (*tramp_10)(int value);
int (*tramp_11)(int value);
int (*tramp_12)(int value);
int (*tramp_13)(int value);
int (*tramp_14)(int value);
int (*tramp_15)(int value);
int (*tramp_16)(int value);
int (*tramp_17)(int value);
int (*tramp_18)(int value);
int (*tramp_19)(int value);
int (*tramp_20)(int value);
int (*tramp_21)(int value);
int (*tramp_22)(int value);
int (*tramp_23)(int value);
int (*tramp_24)(int value);
int (*tramp_25)(int value);
int (*tramp_26)(int value);
int (*tramp_27)(int value);
int (*tramp_28)(int value);
int (*tramp_29)(int value);
int (*tramp_30)(int value);
int (*tramp_31)(int value);
int (*tramp_32)(int value);
int (*tramp_33)(int value);
int (*tramp_34)(int value);
int (*tramp_35)(int value);
int (*tramp_36)(int value);
int (*tramp_37)(int value);
int (*tramp_38)(int value);
int (*tramp_39)(int value);
int (*tramp_40)(int value);
};
struct bpf_testmod_ops2 {
int (*test_1)(void);
};
selftests/bpf: Add struct_ops prog private stack tests Add three tests for struct_ops using private stack. ./test_progs -t struct_ops_private_stack #336/1 struct_ops_private_stack/private_stack:OK #336/2 struct_ops_private_stack/private_stack_fail:OK #336/3 struct_ops_private_stack/private_stack_recur:OK #336 struct_ops_private_stack:OK The following is a snippet of a struct_ops check_member() implementation: u32 moff = __btf_member_bit_offset(t, member) / 8; switch (moff) { case offsetof(struct bpf_testmod_ops3, test_1): prog->aux->priv_stack_requested = true; prog->aux->recursion_detected = test_1_recursion_detected; fallthrough; default: break; } return 0; The first test is with nested two different callback functions where the first prog has more than 512 byte stack size (including subprogs) with private stack enabled. The second test is a negative test where the second prog has more than 512 byte stack size without private stack enabled. The third test is the same callback function recursing itself. At run time, the jit trampoline recursion check kicks in to prevent the recursion. The recursion_detected() callback function is implemented by the bpf_testmod, the following message in dmesg bpf_testmod: oh no, recursing into test_1, recursion_misses 1 demonstrates the callback function is indeed triggered when recursion miss happens. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20241112163938.2225528-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2024-11-12 08:39:38 -08:00
struct bpf_testmod_ops3 {
int (*test_1)(void);
int (*test_2)(void);
};
selftests/bpf: Test gen_prologue and gen_epilogue This test adds a new struct_ops "bpf_testmod_st_ops" in bpf_testmod. The ops of the bpf_testmod_st_ops is triggered by new kfunc calls "bpf_kfunc_st_ops_test_*logue". These new kfunc calls are primarily used by the SEC("syscall") program. The test triggering sequence is like: SEC("syscall") syscall_prologue(struct st_ops_args *args) bpf_kfunc_st_op_test_prologue(args) st_ops->test_prologue(args) .gen_prologue adds 1000 to args->a .gen_epilogue adds 10000 to args->a .gen_epilogue will also set the r0 to 2 * args->a. The .gen_prologue and .gen_epilogue of the bpf_testmod_st_ops will test the prog->aux->attach_func_name to decide if it needs to generate codes. The main programs of the pro_epilogue.c will call a new kfunc bpf_kfunc_st_ops_inc10 which does "args->a += 10". It will also call a subprog() which does "args->a += 1". This patch uses the test_loader infra to check the __xlated instructions patched after gen_prologue and/or gen_epilogue. The __xlated check is based on Eduard's example (Thanks!) in v1. args->a is returned by the struct_ops prog (either the main prog or the epilogue). Thus, the __retval of the SEC("syscall") prog is checked. For example, when triggering the ops in the 'SEC("struct_ops/test_epilogue") int test_epilogue' The expected args->a is +1 (subprog call) + 10 (kfunc call) + 10000 (.gen_epilogue) = 10011. The expected return value is 2 * 10011 (.gen_epilogue). Suggested-by: Eduard Zingerman <eddyz87@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Link: https://lore.kernel.org/r/20240829210833.388152-7-martin.lau@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2024-08-29 14:08:28 -07:00
struct st_ops_args {
u64 a;
};
struct bpf_testmod_st_ops {
int (*test_prologue)(struct st_ops_args *args);
int (*test_epilogue)(struct st_ops_args *args);
int (*test_pro_epilogue)(struct st_ops_args *args);
struct module *owner;
};
#endif /* _BPF_TESTMOD_H */