tools/testing/selftests/bpf/prog_tests/kfunc_call.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/kfunc_call.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/kfunc_call.c
Extension
.c
Size
9077 bytes
Lines
327
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kfunc_test_params {
	const char *prog_name;
	unsigned long lskel_prog_desc_offset;
	int retval;
	enum kfunc_test_type test_type;
	const char *expected_err_msg;
};

#define __BPF_TEST_SUCCESS(name, __retval, type) \
	{ \
	  .prog_name = #name, \
	  .lskel_prog_desc_offset = offsetof(struct kfunc_call_test_lskel, progs.name), \
	  .retval = __retval, \
	  .test_type = type, \
	  .expected_err_msg = NULL, \
	}

#define __BPF_TEST_FAIL(name, __retval, type, error_msg) \
	{ \
	  .prog_name = #name, \
	  .lskel_prog_desc_offset = 0 /* unused when test is failing */, \
	  .retval = __retval, \
	  .test_type = type, \
	  .expected_err_msg = error_msg, \
	}

#define TC_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, tc_test)
#define SYSCALL_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, syscall_test)
#define SYSCALL_NULL_CTX_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, syscall_null_ctx_test)

#define TC_FAIL(name, retval, error_msg) __BPF_TEST_FAIL(name, retval, tc_test, error_msg)
#define SYSCALL_NULL_CTX_FAIL(name, retval, error_msg) \
	__BPF_TEST_FAIL(name, retval, syscall_null_ctx_test, error_msg)

static struct kfunc_test_params kfunc_tests[] = {
	/* failure cases:
	 * if retval is 0 -> the program will fail to load and the error message is an error
	 * if retval is not 0 -> the program can be loaded but running it will gives the
	 *                       provided return value. The error message is thus the one
	 *                       from a successful load
	 */
	SYSCALL_NULL_CTX_FAIL(kfunc_syscall_test_fail, -EINVAL, "processed 4 insns"),
	SYSCALL_NULL_CTX_FAIL(kfunc_syscall_test_null_fail, -EINVAL, "processed 4 insns"),
	TC_FAIL(kfunc_call_test_get_mem_fail_rdonly, 0, "R0 cannot write into rdonly_mem"),
	TC_FAIL(kfunc_call_test_get_mem_fail_use_after_free, 0, "invalid mem access 'scalar'"),
	TC_FAIL(kfunc_call_test_get_mem_fail_oob, 0, "min value is outside of the allowed memory range"),
	TC_FAIL(kfunc_call_test_get_mem_fail_not_const, 0, "is not a const"),
	TC_FAIL(kfunc_call_test_mem_acquire_fail, 0, "acquire kernel function does not return PTR_TO_BTF_ID"),
	TC_FAIL(kfunc_call_test_pointer_arg_type_mismatch, 0, "R1 expected pointer to ctx, but got scalar"),

	/* success cases */
	TC_TEST(kfunc_call_test1, 12),
	TC_TEST(kfunc_call_test2, 3),
	TC_TEST(kfunc_call_test4, -1234),
	TC_TEST(kfunc_call_test5, 0),
	TC_TEST(kfunc_call_test5_asm, 0),
	TC_TEST(kfunc_call_test_ref_btf_id, 0),
	TC_TEST(kfunc_call_test_get_mem, 42),
	SYSCALL_TEST(kfunc_syscall_test, 0),
	SYSCALL_NULL_CTX_TEST(kfunc_syscall_test_null, 0),
	TC_TEST(kfunc_call_test_static_unused_arg, 0),
	TC_TEST(kfunc_call_ctx, 0),
};

struct syscall_test_args {
	__u8 data[16];
	size_t size;
};

static void verify_success(struct kfunc_test_params *param)
{
	struct kfunc_call_test_lskel *lskel = NULL;
	LIBBPF_OPTS(bpf_test_run_opts, topts);
	struct bpf_prog_desc *lskel_prog;
	struct kfunc_call_test *skel;
	struct bpf_program *prog;
	int prog_fd, err;
	struct syscall_test_args args = {
		.size = 10,
	};

	switch (param->test_type) {
	case syscall_test:
		topts.ctx_in = &args;
		topts.ctx_size_in = sizeof(args);
		/* fallthrough */
	case syscall_null_ctx_test:
		break;
	case tc_test:
		topts.data_in = &pkt_v4;

Annotation

Implementation Notes