struct pt_regs is not exported to userspace on all archs. arm64 and s390 export "user_pt_regs" instead, which causes build failure at the moment:
progs/test_task_pt_regs.c:8:16: error: variable has incomplete type 'struct pt_regs' struct pt_regs current_regs = {};
Use the multi-arch macros defined by tools/lib/bpf/bpf_tracing.h to copy the pt_regs into a locally-defined struct.
Copying the user_pt_regs struct on arm64 wouldn't work because the struct is too large and the compiler complains about using too much stack.
Fixes: 576d47bb1a92 ("bpf: selftests: Add bpf_task_pt_regs() selftest") Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org --- .../selftests/bpf/bpf_pt_regs_helpers.h | 30 +++++++++++++++++++ .../selftests/bpf/prog_tests/task_pt_regs.c | 1 + .../selftests/bpf/progs/test_task_pt_regs.c | 10 ++++--- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tools/testing/selftests/bpf/bpf_pt_regs_helpers.h
diff --git a/tools/testing/selftests/bpf/bpf_pt_regs_helpers.h b/tools/testing/selftests/bpf/bpf_pt_regs_helpers.h new file mode 100644 index 000000000000..7531f4824ead --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_pt_regs_helpers.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __BPF_PT_REGS_HELPERS +#define __BPF_PT_REGS_HELPERS + +#include <bpf/bpf_tracing.h> + +struct bpf_pt_regs { + unsigned long long parm[5]; + unsigned long long ret; + unsigned long long fp; + unsigned long long rc; + unsigned long long sp; + unsigned long long ip; +}; + +static inline void bpf_copy_pt_regs(struct bpf_pt_regs *dest, struct pt_regs *src) +{ + dest->parm[0] = PT_REGS_PARM1(src); + dest->parm[1] = PT_REGS_PARM2(src); + dest->parm[2] = PT_REGS_PARM3(src); + dest->parm[3] = PT_REGS_PARM4(src); + dest->parm[4] = PT_REGS_PARM5(src); + dest->ret = PT_REGS_RET(src); + dest->fp = PT_REGS_FP(src); + dest->rc = PT_REGS_RC(src); + dest->sp = PT_REGS_SP(src); + dest->ip = PT_REGS_IP(src); +} + +#endif /* __BPF_PT_REGS_HELPERS */ diff --git a/tools/testing/selftests/bpf/prog_tests/task_pt_regs.c b/tools/testing/selftests/bpf/prog_tests/task_pt_regs.c index 53f0e0fa1a53..196453b75937 100644 --- a/tools/testing/selftests/bpf/prog_tests/task_pt_regs.c +++ b/tools/testing/selftests/bpf/prog_tests/task_pt_regs.c @@ -2,6 +2,7 @@ #define _GNU_SOURCE #include <test_progs.h> #include <linux/ptrace.h> +#include "bpf_pt_regs_helpers.h" #include "test_task_pt_regs.skel.h"
void test_task_pt_regs(void) diff --git a/tools/testing/selftests/bpf/progs/test_task_pt_regs.c b/tools/testing/selftests/bpf/progs/test_task_pt_regs.c index 6c059f1cfa1b..348da3509093 100644 --- a/tools/testing/selftests/bpf/progs/test_task_pt_regs.c +++ b/tools/testing/selftests/bpf/progs/test_task_pt_regs.c @@ -5,8 +5,10 @@ #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h>
-struct pt_regs current_regs = {}; -struct pt_regs ctx_regs = {}; +#include "bpf_pt_regs_helpers.h" + +struct bpf_pt_regs current_regs = {}; +struct bpf_pt_regs ctx_regs = {}; int uprobe_res = 0;
SEC("uprobe/trigger_func") @@ -17,8 +19,8 @@ int handle_uprobe(struct pt_regs *ctx)
current = bpf_get_current_task_btf(); regs = (struct pt_regs *) bpf_task_pt_regs(current); - __builtin_memcpy(¤t_regs, regs, sizeof(*regs)); - __builtin_memcpy(&ctx_regs, ctx, sizeof(*ctx)); + bpf_copy_pt_regs(¤t_regs, regs); + bpf_copy_pt_regs(&ctx_regs, ctx);
/* Prove that uprobe was run */ uprobe_res = 1;