[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250919-rv-reactor-signal-v1-1-fb0012034158@linutronix.de>
Date: Fri, 19 Sep 2025 12:49:56 +0200
From: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
To: Gabriele Monaco <gmonaco@...hat.com>, Nam Cao <namcao@...utronix.de>,
Steven Rostedt <rostedt@...dmis.org>,
Masami Hiramatsu <mhiramat@...nel.org>,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
Cc: linux-kernel@...r.kernel.org, linux-trace-kernel@...r.kernel.org,
Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Subject: [PATCH] rv: Add signal reactor
Reactions of the existing reactors are not easily detectable from programs
and also not easily attributable to the triggering task.
This makes it hard to test the monitors themselves programmatically.
The signal reactors allows applications to validate the correct operations
of monitors either by installing custom signal handlers or by forking a
child and waiting for the expected exit code.
For now only SIGBUS is supported, but additional signals can be added.
As the reactors are called from tracepoints they need to be able to run in
any context. To avoid taking any of the looks used during signal delivery
from an invalid context, schedule it through task_work. The delivery will
be delayed, for example when then sleep monitor detects an invalid sleep.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
---
kernel/trace/rv/Kconfig | 8 +++
kernel/trace/rv/Makefile | 1 +
kernel/trace/rv/reactor_signal.c | 114 +++++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+)
diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig
index 5b4be87ba59d3fa5123a64efa746320c9e8b73b1..dc7b546615a67c811ce94c43bb1db2826cd00c77 100644
--- a/kernel/trace/rv/Kconfig
+++ b/kernel/trace/rv/Kconfig
@@ -93,3 +93,11 @@ config RV_REACT_PANIC
help
Enables the panic reactor. The panic reactor emits a printk()
message if an exception is found and panic()s the system.
+
+config RV_REACT_SIGNAL
+ bool "Signal reactor"
+ depends on RV_REACTORS
+ default y
+ help
+ Enables the signal reactor. The signal reactors sends a signal to the
+ task triggering an exception.
diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile
index 42ff5d5aa9dde3ed2964e0b8d4ab7b236f498319..adf56bbd03ffa0d48de1f0d86ca5fcce1628bdba 100644
--- a/kernel/trace/rv/Makefile
+++ b/kernel/trace/rv/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_RV_MON_OPID) += monitors/opid/opid.o
obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o
+obj-$(CONFIG_RV_REACT_SIGNAL) += reactor_signal.o
diff --git a/kernel/trace/rv/reactor_signal.c b/kernel/trace/rv/reactor_signal.c
new file mode 100644
index 0000000000000000000000000000000000000000..e123786d94371a240beb63b2d1b2f3044a466404
--- /dev/null
+++ b/kernel/trace/rv/reactor_signal.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Thomas Weißschuh, Linutronix GmbH
+ *
+ * Signal RV reactor:
+ * Prints the exception msg to the kernel message log and sends a signal to the offending task.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/mempool.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/rv.h>
+#include <linux/sched/signal.h>
+#include <linux/task_work.h>
+
+struct rv_signal_work {
+ struct callback_head twork;
+ int signal;
+ char message[256];
+};
+
+static mempool_t *rv_signal_task_work_pool;
+
+static void rv_signal_force_sig(int signal, const char *message)
+{
+ /* The message already contains a subsystem prefix, so use raw printk() */
+ printk(KERN_WARNING "%s", message);
+ pr_warn("Killing PID %d with signal %d", task_pid_nr(current), signal);
+ force_sig(signal);
+}
+
+static void rv_signal_task_work(struct callback_head *cbh)
+{
+ struct rv_signal_work *work = container_of_const(cbh, struct rv_signal_work, twork);
+
+ rv_signal_force_sig(work->signal, work->message);
+
+ mempool_free(work, rv_signal_task_work_pool);
+}
+
+static void rv_reaction_signal(int signal, const char *fmt, va_list args)
+{
+ struct rv_signal_work *work;
+ char message[256];
+
+ work = mempool_alloc_preallocated(rv_signal_task_work_pool);
+ if (!work) {
+ pr_warn_ratelimited("Unable to signal through task_work, sending directly\n");
+ vsnprintf(message, sizeof(message), fmt, args);
+ rv_signal_force_sig(signal, message);
+ return;
+ }
+
+ init_task_work(&work->twork, rv_signal_task_work);
+ work->signal = signal;
+ vsnprintf(work->message, sizeof(work->message), fmt, args);
+
+ /*
+ * The reactor can be called from any context through tracepoints.
+ * To avoid any locking or other operations not usable from all contexts, use TWA_RESUME.
+ * The signal might be delayed, but that shouldn't be an issue.
+ */
+ task_work_add(current, &work->twork, TWA_RESUME);
+}
+
+__printf(1, 2)
+static void rv_reaction_sigbus(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ rv_reaction_signal(SIGBUS, fmt, args);
+ va_end(args);
+}
+
+static struct rv_reactor rv_sigbus = {
+ .name = "sigbus",
+ .description = "Kill the current task with SIGBUS",
+ .react = rv_reaction_sigbus,
+};
+
+static int __init register_react_signal(void)
+{
+ int ret;
+
+ rv_signal_task_work_pool = mempool_create_kmalloc_pool(num_possible_cpus(),
+ sizeof(struct rv_signal_work));
+ if (!rv_signal_task_work_pool)
+ return -ENOMEM;
+
+ ret = rv_register_reactor(&rv_sigbus);
+ if (ret) {
+ mempool_destroy(rv_signal_task_work_pool);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit unregister_react_signal(void)
+{
+ rv_unregister_reactor(&rv_sigbus);
+ mempool_destroy(rv_signal_task_work_pool);
+}
+
+module_init(register_react_signal);
+module_exit(unregister_react_signal);
+
+MODULE_AUTHOR("Thomas Weißschuh <thomas.weissschuh@...utronix.de>");
+MODULE_DESCRIPTION("signal rv reactor: send a signal if an exception is found.");
---
base-commit: adbdaac63f5024a9a117ef8ce9732a4272fbc931
change-id: 20250901-rv-reactor-signal-b5568e0722a9
Best regards,
--
Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Powered by blists - more mailing lists