diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 42ffc24..3a7e3f2 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -3,6 +3,14 @@ include ../../../build/Build.include
 include ../../../scripts/Makefile.arch
 include ../../../scripts/Makefile.include
 
+# needed for Makile.feature
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
 CXX ?= $(CROSS_COMPILE)g++
 
 CURDIR := $(abspath .)
@@ -32,6 +40,26 @@ ifneq ($(LLVM),)
 CFLAGS += -Wno-unused-command-line-argument
 endif
 
+FEATURE_USER = .bpftest
+FEATURE_TESTS = sdt
+FEATURE_DISPLAY = sdt
+
+check_feat := 1
+NON_CHECK_FEAT_TARGETS := clean docs docs-clean
+ifdef MAKECMDGOALS
+ifeq ($(filter-out $(NON_CHECK_FEAT_TARGETS),$(MAKECMDGOALS)),)
+  check_feat := 0
+endif
+endif
+
+ifeq ($(check_feat),1)
+ifeq ($(FEATURES_DUMP),)
+include $(srctree)/tools/build/Makefile.feature
+else
+include $(FEATURES_DUMP)
+endif
+endif
+
 # Order correspond to 'make run_tests' order
 TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
 	test_verifier_log test_dev_cgroup \
@@ -108,6 +136,7 @@ override define CLEAN
 	$(Q)$(RM) -r $(TEST_GEN_PROGS)
 	$(Q)$(RM) -r $(TEST_GEN_PROGS_EXTENDED)
 	$(Q)$(RM) -r $(TEST_GEN_FILES)
+	$(Q)$(RM) -r $(OUTPUT)FEATURE-DUMP.bpf
 	$(Q)$(RM) -r $(EXTRA_CLEAN)
 	$(Q)$(MAKE) -C bpf_testmod clean
 	$(Q)$(MAKE) docs-clean
@@ -434,6 +463,11 @@ $(TRUNNER_TESTS_HDR): $(TRUNNER_TESTS_DIR)/*.c
 		 ) > $$@)
 endif
 
+# support for adding USDT probes?
+ifeq ($(feature-sdt), 1)
+CFLAGS += -DHAVE_SDT_EVENT
+endif
+
 # compile individual test files
 # Note: we cd into output directory to ensure embedded BPF object is found
 $(TRUNNER_TEST_OBJS): $(TRUNNER_OUTPUT)/%.test.o:			\
diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
index 521d7bd..5bb24927 100644
--- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c
+++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c
@@ -2,6 +2,17 @@
 #include <test_progs.h>
 #include "test_attach_probe.skel.h"
 
+#if defined(HAVE_SDT_EVENT)
+#include <sys/sdt.h>
+
+static void usdt_method(void)
+{
+	DTRACE_PROBE(bpftest, probe1);
+	return;
+}
+
+#endif /* HAVE_SDT_EVENT */
+
 /* this is how USDT semaphore is actually defined, except volatile modifier */
 volatile unsigned short uprobe_ref_ctr __attribute__((unused)) __attribute((section(".probes")));
 
@@ -22,6 +33,7 @@ void test_attach_probe(void)
 	struct bpf_link *kprobe_link, *kretprobe_link;
 	struct bpf_link *uprobe_link, *uretprobe_link;
 	struct bpf_link *uprobe_byname_link, *uretprobe_byname_link;
+	struct bpf_link *usdtprobe_byname_link;
 	struct test_attach_probe* skel;
 	size_t uprobe_offset;
 	ssize_t base_addr, ref_ctr_offset;
@@ -121,6 +133,27 @@ void test_attach_probe(void)
 		goto cleanup;
 	skel->links.handle_uretprobe_byname = uretprobe_byname_link;
 
+#if defined(HAVE_SDT_EVENT)
+	uprobe_opts.usdt_provider = "bpftest";
+	uprobe_opts.usdt_name = "probe1";
+	uprobe_opts.func_name = NULL;
+	uprobe_opts.retprobe = false;
+	usdtprobe_byname_link = bpf_program__attach_uprobe_opts(skel->progs.handle_usdtprobe_byname,
+								0 /* this pid */,
+								"/proc/self/exe",
+								0, &uprobe_opts);
+	if (!ASSERT_OK_PTR(usdtprobe_byname_link, "attach_usdtprobe_byname"))
+		goto cleanup;
+	skel->links.handle_usdtprobe_byname = usdtprobe_byname_link;
+
+	/* trigger and validate usdt probe */
+	usdt_method();
+
+	if (CHECK(skel->bss->usdtprobe_byname_res != 7, "check_usdtprobe_byname_res",
+		  "wrong usdtprobe_byname res: %d\n", skel->bss->usdtprobe_byname_res))
+		goto cleanup;
+#endif /* HAVE_SDT_EVENT */
+
 	/* trigger & validate kprobe && kretprobe && uretprobe by name */
 	usleep(1);
 
diff --git a/tools/testing/selftests/bpf/progs/test_attach_probe.c b/tools/testing/selftests/bpf/progs/test_attach_probe.c
index efa56bd..0c93191 100644
--- a/tools/testing/selftests/bpf/progs/test_attach_probe.c
+++ b/tools/testing/selftests/bpf/progs/test_attach_probe.c
@@ -12,6 +12,7 @@
 int uretprobe_res = 0;
 int uprobe_byname_res = 0;
 int uretprobe_byname_res = 0;
+int usdtprobe_byname_res = 0;
 
 SEC("kprobe/sys_nanosleep")
 int handle_kprobe(struct pt_regs *ctx)
@@ -55,4 +56,11 @@ int handle_uretprobe_byname(struct pt_regs *ctx)
 	return 0;
 }
 
+SEC("uprobe/trigger_usdt_byname")
+int handle_usdtprobe_byname(struct pt_regs *ctx)
+{
+	usdtprobe_byname_res = 7;
+	return 0;
+}
+
 char _license[] SEC("license") = "GPL";
