linux-yocto/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h
Martin KaFai Lau 47e69431b5 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 18:15:45 -07:00

109 lines
2.4 KiB
C

/* 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 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);
/* 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);
};
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 */