From: Wen Yang <[email protected]>

Add a selftest module that register an RV reactor and a test that
exercises the module pinning: rmmod must fail while a monitor is
attached to the reactor and succeed after it is detached. A trap
unloads the module on failure so it does not break the next insmod.

THe module is built through the kselftest TEST_GEN_MODS_DIR mechanism,
like the livepatch selftests.

Signed-off-by: Wen Yang <[email protected]>
---
 tools/testing/selftests/verification/Makefile |  1 +
 tools/testing/selftests/verification/config   |  2 +
 .../test.d/rv_reactor_loadable.tc             | 46 +++++++++++++++++++
 .../verification/test_modules/Makefile        | 16 +++++++
 .../test_modules/rv_test_reactor.c            | 37 +++++++++++++++
 5 files changed, 102 insertions(+)
 create mode 100644 
tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc
 create mode 100644 tools/testing/selftests/verification/test_modules/Makefile
 create mode 100644 
tools/testing/selftests/verification/test_modules/rv_test_reactor.c

diff --git a/tools/testing/selftests/verification/Makefile 
b/tools/testing/selftests/verification/Makefile
index aa8790c22a71..7ff7382d11f0 100644
--- a/tools/testing/selftests/verification/Makefile
+++ b/tools/testing/selftests/verification/Makefile
@@ -3,6 +3,7 @@ all:
 
 TEST_PROGS := verificationtest-ktap
 TEST_FILES := test.d settings
+TEST_GEN_MODS_DIR := test_modules
 EXTRA_CLEAN := $(OUTPUT)/logs/*
 
 include ../lib.mk
diff --git a/tools/testing/selftests/verification/config 
b/tools/testing/selftests/verification/config
index 43072c1c38f4..ddd7581f07b9 100644
--- a/tools/testing/selftests/verification/config
+++ b/tools/testing/selftests/verification/config
@@ -1 +1,3 @@
 CONFIG_RV=y
+CONFIG_MODULES=y
+CONFIG_MODULES_UNLOAD=y
diff --git a/tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc 
b/tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc
new file mode 100644
index 000000000000..ff1691661521
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_reactor_loadable.tc
@@ -0,0 +1,46 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test a loadable module-based reactor
+# requires: available_reactors insmod:program rmmod:program
+
+MODULE_KO="$FTRACETEST_ROOT/test_modules/rv_test_reactor.ko"
+[ -f "$MODULE_KO" ] || exit_unsupported
+[ -f /proc/modules ] || exit_unsupported
+monitor=$(ls monitors | head -n 1)
+[ -n "$monitor" ] || exit_unsupported
+
+cleanup() {
+       if grep -q '^test_reactors$' available_reactors; then
+               echo nop > "monitors/$monitor/reactors" || true
+               rmmod rv_test_reactor || true
+       fi
+}
+trap cleanup EXIT
+
+test_loadable_reactor() {
+       local monitor="$1"
+
+       insmod "$MODULE_KO"
+       grep -q test_reactor available_reactors
+
+       echo test_reactor > "monitors/$monitor/reactors"
+       grep -q "\[test_reactor\]"  "monitors/$monitor/reactors"
+
+       echo 1 > "monitors/$monitor/enable"
+
+       if rmmod rv_test_reactor 2> /dev/null; then
+               echo "FAIL: rmmod succeeded while the reactor is attached to a 
monitor"
+               return 1
+       fi
+       grep -q test_reactor available_reactors
+
+       echo nop > "monitors/$monitor/reactors"
+       grep -q "\[nop\]"  "monitors/$monitor/reactors"
+       grep -q 1 "monitors/$monitor/enable"
+
+       echo 0 > "monitors/$monitor/enable"
+       rmmod rv_test_reactor
+       ! grep -q test_reactor available_reactors
+}
+
+test_loadable_reactor "$monitor"
diff --git a/tools/testing/selftests/verification/test_modules/Makefile 
b/tools/testing/selftests/verification/test_modules/Makefile
new file mode 100644
index 000000000000..0af95207a9a9
--- /dev/null
+++ b/tools/testing/selftests/verification/test_modules/Makefile
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+
+TESTMODS_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
+KDIR ?= /lib/modules/$(shell uname -r)/build
+
+obj-m += rv_test_reactor.o
+
+modules:
+ifneq ("$(wildcard $(KDIR))", "")
+       $(Q)$(MAKE) -C $(KDIR) modules KBUILD_EXTMOD=$(TESTMODS_DIR)
+endif
+
+clean:
+ifneq ("$(wildcard $(KDIR))", "")
+       $(Q)$(MAKE) -C $(KDIR) clean KBUILD_EXTMOD=$(TESTMODS_DIR)
+endif
diff --git 
a/tools/testing/selftests/verification/test_modules/rv_test_reactor.c 
b/tools/testing/selftests/verification/test_modules/rv_test_reactor.c
new file mode 100644
index 000000000000..a243df81fa52
--- /dev/null
+++ b/tools/testing/selftests/verification/test_modules/rv_test_reactor.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Loadable RV reactor for the verification selftests. Register a
+ * reactor with owner = THIS_MODULE so the selftests can exercise the
+ * module pinning: unloading is refused while a monitor is attached
+ * to the reactor.
+ */
+
+#include <linux/module.h>
+#include <linux/rv.h>
+
+__printf(1, 0) static void rv_test_reaction(const char *msg, va_list args)
+{
+}
+
+static struct rv_reactor rv_test_reactor = {
+       .name = "test_reactor",
+       .description = "selftest reactor: exercise module-based reactors.",
+       .react = rv_test_reaction,
+       .owner = THIS_MODULE,
+};
+
+static int __init rv_test_reactor_init(void)
+{
+       return rv_register_reactor(&rv_test_reactor);
+}
+
+static void __exit rv_test_reactor_exit(void)
+{
+       rv_unregister_reactor(&rv_test_reactor);
+}
+
+module_init(rv_test_reactor_init);
+module_exit(rv_test_reactor_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Loadable RV reactor for verification selftests");
-- 
2.25.1


Reply via email to