* [PATCH bpf-next 1/4] selftests/bpf: ensure consistent test failure output
2020-03-13 7:54 [PATCH bpf-next 0/4] CO-RE candidate matching fix and tracing test Andrii Nakryiko
@ 2020-03-13 7:54 ` Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 2/4] libbpf: ignore incompatible types with matching name during CO-RE relocation Andrii Nakryiko
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Andrii Nakryiko @ 2020-03-13 7:54 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko
printf() doesn't seem to honor using overwritten stdout/stderr (as part of
stdio hijacking), so ensure all "standard" invocations of printf() do
fprintf(stdout, ...) instead.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/testing/selftests/bpf/test_progs.c | 10 +++++-----
tools/testing/selftests/bpf/test_progs.h | 8 ++++----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index b6201dd82edf..f85a06512541 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -216,7 +216,7 @@ int bpf_find_map(const char *test, struct bpf_object *obj, const char *name)
map = bpf_object__find_map_by_name(obj, name);
if (!map) {
- printf("%s:FAIL:map '%s' not found\n", test, name);
+ fprintf(stdout, "%s:FAIL:map '%s' not found\n", test, name);
test__fail();
return -1;
}
@@ -387,7 +387,7 @@ static int libbpf_print_fn(enum libbpf_print_level level,
{
if (env.verbosity < VERBOSE_VERY && level == LIBBPF_DEBUG)
return 0;
- vprintf(format, args);
+ vfprintf(stdout, format, args);
return 0;
}
@@ -633,7 +633,7 @@ int cd_flavor_subdir(const char *exec_name)
if (!flavor)
return 0;
flavor++;
- printf("Switching to flavor '%s' subdirectory...\n", flavor);
+ fprintf(stdout, "Switching to flavor '%s' subdirectory...\n", flavor);
return chdir(flavor);
}
@@ -716,8 +716,8 @@ int main(int argc, char **argv)
cleanup_cgroup_environment();
}
stdio_restore();
- printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n",
- env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt);
+ fprintf(stdout, "Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n",
+ env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt);
free(env.test_selector.blacklist.strs);
free(env.test_selector.whitelist.strs);
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
index bcfa9ef23fda..fd85fa61dbf7 100644
--- a/tools/testing/selftests/bpf/test_progs.h
+++ b/tools/testing/selftests/bpf/test_progs.h
@@ -109,10 +109,10 @@ extern struct ipv6_packet pkt_v6;
int __save_errno = errno; \
if (__ret) { \
test__fail(); \
- printf("%s:FAIL:%s ", __func__, tag); \
- printf(format); \
+ fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \
+ fprintf(stdout, ##format); \
} else { \
- printf("%s:PASS:%s %d nsec\n", \
+ fprintf(stdout, "%s:PASS:%s %d nsec\n", \
__func__, tag, duration); \
} \
errno = __save_errno; \
@@ -124,7 +124,7 @@ extern struct ipv6_packet pkt_v6;
int __save_errno = errno; \
if (__ret) { \
test__fail(); \
- printf("%s:FAIL:%d\n", __func__, __LINE__); \
+ fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \
} \
errno = __save_errno; \
__ret; \
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 2/4] libbpf: ignore incompatible types with matching name during CO-RE relocation
2020-03-13 7:54 [PATCH bpf-next 0/4] CO-RE candidate matching fix and tracing test Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 1/4] selftests/bpf: ensure consistent test failure output Andrii Nakryiko
@ 2020-03-13 7:54 ` Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 3/4] libbpf: provide CO-RE variants of PT_REGS macros Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls Andrii Nakryiko
3 siblings, 0 replies; 8+ messages in thread
From: Andrii Nakryiko @ 2020-03-13 7:54 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko
When finding target type candidates, ignore forward declarations, functions,
and other named types of incompatible kind. Not doing this can cause false
errors. See [0] for one such case (due to struct pt_regs forward
declaration).
[0] https://github.com/iovisor/bcc/pull/2806#issuecomment-598543645
Fixes: ddc7c3042614 ("libbpf: implement BPF CO-RE offset relocation algorithm")
Reported-by: Wenbo Zhang <ethercflow@gmail.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/lib/bpf/libbpf.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 1a787a2faf58..085e41f9b68e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -3873,6 +3873,10 @@ static struct ids_vec *bpf_core_find_cands(const struct btf *local_btf,
if (str_is_empty(targ_name))
continue;
+ t = skip_mods_and_typedefs(targ_btf, i, NULL);
+ if (!btf_is_composite(t) && !btf_is_array(t))
+ continue;
+
targ_essent_len = bpf_core_essential_name_len(targ_name);
if (targ_essent_len != local_essent_len)
continue;
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 3/4] libbpf: provide CO-RE variants of PT_REGS macros
2020-03-13 7:54 [PATCH bpf-next 0/4] CO-RE candidate matching fix and tracing test Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 1/4] selftests/bpf: ensure consistent test failure output Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 2/4] libbpf: ignore incompatible types with matching name during CO-RE relocation Andrii Nakryiko
@ 2020-03-13 7:54 ` Andrii Nakryiko
2020-03-13 7:54 ` [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls Andrii Nakryiko
3 siblings, 0 replies; 8+ messages in thread
From: Andrii Nakryiko @ 2020-03-13 7:54 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko
Syscall raw tracepoints have struct pt_regs pointer as tracepoint's first
argument. After that, reading any of pt_regs fields requires bpf_probe_read(),
even for tp_btf programs. Due to that, PT_REGS_PARMx macros are not usable as
is. This patch adds CO-RE variants of those macros that use BPF_CORE_READ() to
read necessary fields. This provides relocatable architecture-agnostic pt_regs
field accesses.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/lib/bpf/bpf_tracing.h | 103 ++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
index 379d03b211ea..b0c9ae5c73b5 100644
--- a/tools/lib/bpf/bpf_tracing.h
+++ b/tools/lib/bpf/bpf_tracing.h
@@ -50,6 +50,7 @@
#if defined(bpf_target_x86)
#if defined(__KERNEL__) || defined(__VMLINUX_H__)
+
#define PT_REGS_PARM1(x) ((x)->di)
#define PT_REGS_PARM2(x) ((x)->si)
#define PT_REGS_PARM3(x) ((x)->dx)
@@ -60,7 +61,20 @@
#define PT_REGS_RC(x) ((x)->ax)
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->ip)
+
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), di)
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), si)
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), dx)
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), cx)
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8)
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), sp)
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), bp)
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), ax)
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), ip)
+
#else
+
#ifdef __i386__
/* i386 kernel is built with -mregparm=3 */
#define PT_REGS_PARM1(x) ((x)->eax)
@@ -73,7 +87,20 @@
#define PT_REGS_RC(x) ((x)->eax)
#define PT_REGS_SP(x) ((x)->esp)
#define PT_REGS_IP(x) ((x)->eip)
+
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), eax)
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), edx)
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), ecx)
+#define PT_REGS_PARM4_CORE(x) 0
+#define PT_REGS_PARM5_CORE(x) 0
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), esp)
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), ebp)
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), eax)
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), esp)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), eip)
+
#else
+
#define PT_REGS_PARM1(x) ((x)->rdi)
#define PT_REGS_PARM2(x) ((x)->rsi)
#define PT_REGS_PARM3(x) ((x)->rdx)
@@ -84,6 +111,18 @@
#define PT_REGS_RC(x) ((x)->rax)
#define PT_REGS_SP(x) ((x)->rsp)
#define PT_REGS_IP(x) ((x)->rip)
+
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), rdi)
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), rsi)
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), rdx)
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), rcx)
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8)
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), rsp)
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), rbp)
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), rax)
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), rsp)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), rip)
+
#endif
#endif
@@ -104,6 +143,17 @@ struct pt_regs;
#define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15])
#define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr)
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[3])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[4])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[5])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[6])
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), grps[14])
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[11])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[15])
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), pdw.addr)
+
#elif defined(bpf_target_arm)
#define PT_REGS_PARM1(x) ((x)->uregs[0])
@@ -117,6 +167,17 @@ struct pt_regs;
#define PT_REGS_SP(x) ((x)->uregs[13])
#define PT_REGS_IP(x) ((x)->uregs[12])
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), uregs[0])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), uregs[1])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), uregs[2])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), uregs[3])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), uregs[4])
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), uregs[14])
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), uregs[11])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), uregs[0])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), uregs[13])
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), uregs[12])
+
#elif defined(bpf_target_arm64)
/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
@@ -134,6 +195,17 @@ struct pt_regs;
#define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
#define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc)
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[1])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[2])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[3])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[4])
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[30])
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[29])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), sp)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), pc)
+
#elif defined(bpf_target_mips)
#define PT_REGS_PARM1(x) ((x)->regs[4])
@@ -147,6 +219,17 @@ struct pt_regs;
#define PT_REGS_SP(x) ((x)->regs[29])
#define PT_REGS_IP(x) ((x)->cp0_epc)
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), regs[4])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), regs[5])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), regs[6])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), regs[7])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), regs[8])
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), regs[31])
+#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), regs[30])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), regs[1])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), regs[29])
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), cp0_epc)
+
#elif defined(bpf_target_powerpc)
#define PT_REGS_PARM1(x) ((x)->gpr[3])
@@ -158,6 +241,15 @@ struct pt_regs;
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->nip)
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), gpr[3])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), gpr[4])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), gpr[5])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), gpr[6])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), gpr[7])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), gpr[3])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), nip)
+
#elif defined(bpf_target_sparc)
#define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0])
@@ -169,11 +261,22 @@ struct pt_regs;
#define PT_REGS_RC(x) ((x)->u_regs[UREG_I0])
#define PT_REGS_SP(x) ((x)->u_regs[UREG_FP])
+#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0])
+#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I1])
+#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I2])
+#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I3])
+#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I4])
+#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I7])
+#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0])
+#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), u_regs[UREG_FP])
+
/* Should this also be a bpf_target check for the sparc case? */
#if defined(__arch64__)
#define PT_REGS_IP(x) ((x)->tpc)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), tpc)
#else
#define PT_REGS_IP(x) ((x)->pc)
+#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc)
#endif
#endif
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls
2020-03-13 7:54 [PATCH bpf-next 0/4] CO-RE candidate matching fix and tracing test Andrii Nakryiko
` (2 preceding siblings ...)
2020-03-13 7:54 ` [PATCH bpf-next 3/4] libbpf: provide CO-RE variants of PT_REGS macros Andrii Nakryiko
@ 2020-03-13 7:54 ` Andrii Nakryiko
2020-03-13 17:02 ` [Potential Spoof] " Martin KaFai Lau
3 siblings, 1 reply; 8+ messages in thread
From: Andrii Nakryiko @ 2020-03-13 7:54 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko
Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added
test_vmlinux to trace nanosleep syscall using 5 different types of programs:
- tracepoint;
- raw tracepoint;
- raw tracepoint w/ direct memory reads (tp_btf);
- kprobe;
- fentry.
These programs are realistic variants of real-life tracing programs,
excercising vmlinux.h's usage with tracing applications.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/testing/selftests/bpf/Makefile | 7 +-
.../selftests/bpf/prog_tests/vmlinux.c | 43 ++++++++
.../selftests/bpf/progs/test_vmlinux.c | 98 +++++++++++++++++++
3 files changed, 147 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/vmlinux.c
create mode 100644 tools/testing/selftests/bpf/progs/test_vmlinux.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index da4389dde9f7..3bbda8eb57aa 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -135,7 +135,7 @@ VMLINUX_BTF_PATHS := $(if $(O),$(O)/vmlinux) \
../../../../vmlinux \
/sys/kernel/btf/vmlinux \
/boot/vmlinux-$(shell uname -r)
-VMLINUX_BTF:= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
+VMLINUX_BTF := $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
$(OUTPUT)/runqslower: $(BPFOBJ)
$(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower \
@@ -176,6 +176,10 @@ $(BUILD_DIR)/libbpf $(BUILD_DIR)/bpftool $(INCLUDE_DIR):
$(call msg,MKDIR,,$@)
mkdir -p $@
+$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) | $(BPFTOOL) $(INCLUDE_DIR)
+ $(call msg,GEN,,$@)
+ $(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
+
# Get Clang's default includes on this system, as opposed to those seen by
# '-target bpf'. This fixes "missing" files on some architectures/distros,
# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc.
@@ -284,6 +288,7 @@ $(TRUNNER_BPF_PROGS_DIR)$(if $2,-)$2-bpfobjs := y
$(TRUNNER_BPF_OBJS): $(TRUNNER_OUTPUT)/%.o: \
$(TRUNNER_BPF_PROGS_DIR)/%.c \
$(TRUNNER_BPF_PROGS_DIR)/*.h \
+ $$(INCLUDE_DIR)/vmlinux.h \
$$(BPFOBJ) | $(TRUNNER_OUTPUT)
$$(call $(TRUNNER_BPF_BUILD_RULE),$$<,$$@, \
$(TRUNNER_BPF_CFLAGS), \
diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
new file mode 100644
index 000000000000..04939eda1325
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 Facebook */
+
+#include <test_progs.h>
+#include <time.h>
+#include "test_vmlinux.skel.h"
+
+#define MY_TV_NSEC 1337
+
+static void nsleep()
+{
+ struct timespec ts = { .tv_nsec = MY_TV_NSEC };
+
+ (void)nanosleep(&ts, NULL);
+}
+
+void test_vmlinux(void)
+{
+ int duration = 0, err;
+ struct test_vmlinux* skel;
+ struct test_vmlinux__bss *bss;
+
+ skel = test_vmlinux__open_and_load();
+ if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
+ return;
+ bss = skel->bss;
+
+ err = test_vmlinux__attach(skel);
+ if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
+ goto cleanup;
+
+ /* trigger everything */
+ nsleep();
+
+ CHECK(!bss->tp_called, "tp", "not called\n");
+ CHECK(!bss->raw_tp_called, "raw_tp", "not called\n");
+ CHECK(!bss->tp_btf_called, "tp_btf", "not called\n");
+ CHECK(!bss->kprobe_called, "kprobe", "not called\n");
+ CHECK(!bss->fentry_called, "fentry", "not called\n");
+
+cleanup:
+ test_vmlinux__destroy(skel);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c
new file mode 100644
index 000000000000..5cc2bf8011b0
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 Facebook */
+
+#include "vmlinux.h"
+#include <asm/unistd.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_core_read.h>
+
+#define MY_TV_NSEC 1337
+
+bool tp_called = false;
+bool raw_tp_called = false;
+bool tp_btf_called = false;
+bool kprobe_called = false;
+bool fentry_called = false;
+
+SEC("tp/syscalls/sys_enter_nanosleep")
+int handle__tp(struct trace_event_raw_sys_enter *args)
+{
+ struct __kernel_timespec *ts;
+
+ if (args->id != __NR_nanosleep)
+ return 0;
+
+ ts = (void *)args->args[0];
+ if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
+ return 0;
+
+ tp_called = true;
+ return 0;
+}
+
+static bool __always_inline handle_probed(struct pt_regs *regs, long id)
+{
+ struct __kernel_timespec *ts;
+
+ if (id != __NR_nanosleep)
+ return false;
+
+ ts = (void *)PT_REGS_PARM1_CORE(regs);
+ if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
+ return false;
+
+ return true;
+}
+
+SEC("raw_tp/sys_enter")
+int BPF_PROG(handle__raw_tp, struct pt_regs *regs, long id)
+{
+ struct __kernel_timespec *ts;
+
+ if (id != __NR_nanosleep)
+ return 0;
+
+ ts = (void *)PT_REGS_PARM1_CORE(regs);
+ if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
+ return 0;
+
+ raw_tp_called = true;
+ return 0;
+}
+
+SEC("tp_btf/sys_enter")
+int BPF_PROG(handle__tp_btf, struct pt_regs *regs, long id)
+{
+ struct __kernel_timespec *ts;
+
+ if (id != __NR_nanosleep)
+ return 0;
+
+ ts = (void *)PT_REGS_PARM1_CORE(regs);
+ if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
+ return 0;
+
+ tp_btf_called = true;
+ return 0;
+}
+
+SEC("kprobe/hrtimer_nanosleep")
+int BPF_KPROBE(handle__kprobe,
+ ktime_t rqtp, enum hrtimer_mode mode, clockid_t clockid)
+{
+ if (rqtp == MY_TV_NSEC)
+ kprobe_called = true;
+ return 0;
+}
+
+SEC("fentry/hrtimer_nanosleep")
+int BPF_PROG(handle__fentry,
+ ktime_t rqtp, enum hrtimer_mode mode, clockid_t clockid)
+{
+ if (rqtp == MY_TV_NSEC)
+ fentry_called = true;
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Potential Spoof] [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls
2020-03-13 7:54 ` [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls Andrii Nakryiko
@ 2020-03-13 17:02 ` Martin KaFai Lau
2020-03-13 17:16 ` Andrii Nakryiko
0 siblings, 1 reply; 8+ messages in thread
From: Martin KaFai Lau @ 2020-03-13 17:02 UTC (permalink / raw)
To: Andrii Nakryiko; +Cc: bpf, netdev, ast, daniel, andrii.nakryiko, kernel-team
On Fri, Mar 13, 2020 at 12:54:41AM -0700, Andrii Nakryiko wrote:
> Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added
> test_vmlinux to trace nanosleep syscall using 5 different types of programs:
> - tracepoint;
> - raw tracepoint;
> - raw tracepoint w/ direct memory reads (tp_btf);
> - kprobe;
> - fentry.
>
> These programs are realistic variants of real-life tracing programs,
> excercising vmlinux.h's usage with tracing applications.
>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---
[ ... ]
> diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
> new file mode 100644
> index 000000000000..04939eda1325
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2020 Facebook */
> +
> +#include <test_progs.h>
> +#include <time.h>
> +#include "test_vmlinux.skel.h"
> +
> +#define MY_TV_NSEC 1337
> +
> +static void nsleep()
> +{
> + struct timespec ts = { .tv_nsec = MY_TV_NSEC };
> +
> + (void)nanosleep(&ts, NULL);
> +}
> +
> +void test_vmlinux(void)
> +{
> + int duration = 0, err;
> + struct test_vmlinux* skel;
> + struct test_vmlinux__bss *bss;
> +
> + skel = test_vmlinux__open_and_load();
> + if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
> + return;
> + bss = skel->bss;
> +
> + err = test_vmlinux__attach(skel);
> + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
> + goto cleanup;
> +
> + /* trigger everything */
> + nsleep();
> +
> + CHECK(!bss->tp_called, "tp", "not called\n");
> + CHECK(!bss->raw_tp_called, "raw_tp", "not called\n");
> + CHECK(!bss->tp_btf_called, "tp_btf", "not called\n");
> + CHECK(!bss->kprobe_called, "kprobe", "not called\n");
> + CHECK(!bss->fentry_called, "fentry", "not called\n");
> +
> +cleanup:
> + test_vmlinux__destroy(skel);
> +}
> diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c
> new file mode 100644
> index 000000000000..5cc2bf8011b0
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2020 Facebook */
> +
> +#include "vmlinux.h"
> +#include <asm/unistd.h>
> +#include <bpf/bpf_helpers.h>
> +#include <bpf/bpf_tracing.h>
> +#include <bpf/bpf_core_read.h>
> +
> +#define MY_TV_NSEC 1337
> +
> +bool tp_called = false;
> +bool raw_tp_called = false;
> +bool tp_btf_called = false;
> +bool kprobe_called = false;
> +bool fentry_called = false;
> +
> +SEC("tp/syscalls/sys_enter_nanosleep")
> +int handle__tp(struct trace_event_raw_sys_enter *args)
> +{
> + struct __kernel_timespec *ts;
> +
> + if (args->id != __NR_nanosleep)
> + return 0;
> +
> + ts = (void *)args->args[0];
> + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
> + return 0;
> +
> + tp_called = true;
> + return 0;
> +}
> +
> +static bool __always_inline handle_probed(struct pt_regs *regs, long id)
It is not used, may be removing it?
> +{
> + struct __kernel_timespec *ts;
> +
> + if (id != __NR_nanosleep)
> + return false;
> +
> + ts = (void *)PT_REGS_PARM1_CORE(regs);
> + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
> + return false;
> +
> + return true;
> +}
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Potential Spoof] [PATCH bpf-next 4/4] selftests/bpf: add vmlinux.h selftest exercising tracing of syscalls
2020-03-13 17:02 ` [Potential Spoof] " Martin KaFai Lau
@ 2020-03-13 17:16 ` Andrii Nakryiko
0 siblings, 0 replies; 8+ messages in thread
From: Andrii Nakryiko @ 2020-03-13 17:16 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
Daniel Borkmann, Kernel Team
On Fri, Mar 13, 2020 at 10:02 AM Martin KaFai Lau <kafai@fb.com> wrote:
>
> On Fri, Mar 13, 2020 at 12:54:41AM -0700, Andrii Nakryiko wrote:
> > Add vmlinux.h generation to selftest/bpf's Makefile. Use it from newly added
> > test_vmlinux to trace nanosleep syscall using 5 different types of programs:
> > - tracepoint;
> > - raw tracepoint;
> > - raw tracepoint w/ direct memory reads (tp_btf);
> > - kprobe;
> > - fentry.
> >
> > These programs are realistic variants of real-life tracing programs,
> > excercising vmlinux.h's usage with tracing applications.
> >
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > ---
> [ ... ]
>
> > diff --git a/tools/testing/selftests/bpf/prog_tests/vmlinux.c b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
> > new file mode 100644
> > index 000000000000..04939eda1325
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/prog_tests/vmlinux.c
> > @@ -0,0 +1,43 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/* Copyright (c) 2020 Facebook */
> > +
> > +#include <test_progs.h>
> > +#include <time.h>
> > +#include "test_vmlinux.skel.h"
> > +
> > +#define MY_TV_NSEC 1337
> > +
> > +static void nsleep()
> > +{
> > + struct timespec ts = { .tv_nsec = MY_TV_NSEC };
> > +
> > + (void)nanosleep(&ts, NULL);
> > +}
> > +
> > +void test_vmlinux(void)
> > +{
> > + int duration = 0, err;
> > + struct test_vmlinux* skel;
> > + struct test_vmlinux__bss *bss;
> > +
> > + skel = test_vmlinux__open_and_load();
> > + if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
> > + return;
> > + bss = skel->bss;
> > +
> > + err = test_vmlinux__attach(skel);
> > + if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
> > + goto cleanup;
> > +
> > + /* trigger everything */
> > + nsleep();
> > +
> > + CHECK(!bss->tp_called, "tp", "not called\n");
> > + CHECK(!bss->raw_tp_called, "raw_tp", "not called\n");
> > + CHECK(!bss->tp_btf_called, "tp_btf", "not called\n");
> > + CHECK(!bss->kprobe_called, "kprobe", "not called\n");
> > + CHECK(!bss->fentry_called, "fentry", "not called\n");
> > +
> > +cleanup:
> > + test_vmlinux__destroy(skel);
> > +}
> > diff --git a/tools/testing/selftests/bpf/progs/test_vmlinux.c b/tools/testing/selftests/bpf/progs/test_vmlinux.c
> > new file mode 100644
> > index 000000000000..5cc2bf8011b0
> > --- /dev/null
> > +++ b/tools/testing/selftests/bpf/progs/test_vmlinux.c
> > @@ -0,0 +1,98 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/* Copyright (c) 2020 Facebook */
> > +
> > +#include "vmlinux.h"
> > +#include <asm/unistd.h>
> > +#include <bpf/bpf_helpers.h>
> > +#include <bpf/bpf_tracing.h>
> > +#include <bpf/bpf_core_read.h>
> > +
> > +#define MY_TV_NSEC 1337
> > +
> > +bool tp_called = false;
> > +bool raw_tp_called = false;
> > +bool tp_btf_called = false;
> > +bool kprobe_called = false;
> > +bool fentry_called = false;
> > +
> > +SEC("tp/syscalls/sys_enter_nanosleep")
> > +int handle__tp(struct trace_event_raw_sys_enter *args)
> > +{
> > + struct __kernel_timespec *ts;
> > +
> > + if (args->id != __NR_nanosleep)
> > + return 0;
> > +
> > + ts = (void *)args->args[0];
> > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
> > + return 0;
> > +
> > + tp_called = true;
> > + return 0;
> > +}
> > +
> > +static bool __always_inline handle_probed(struct pt_regs *regs, long id)
> It is not used, may be removing it?
>
Oh, did I really leave it around?... Sigh, will post v2 without it.
> > +{
> > + struct __kernel_timespec *ts;
> > +
> > + if (id != __NR_nanosleep)
> > + return false;
> > +
> > + ts = (void *)PT_REGS_PARM1_CORE(regs);
> > + if (BPF_CORE_READ(ts, tv_nsec) != MY_TV_NSEC)
> > + return false;
> > +
> > + return true;
> > +}
^ permalink raw reply [flat|nested] 8+ messages in thread