Commit 04acadcb authored by Daniel Bristot de Oliveira's avatar Daniel Bristot de Oliveira Committed by Steven Rostedt (Google)

rv: Add runtime reactors interface

A runtime monitor can cause a reaction to the detection of an
exception on the model's execution. By default, the monitors have
tracing reactions, printing the monitor output via tracepoints.
But other reactions can be added (on-demand) via this interface.

The user interface resembles the kernel tracing interface and
presents these files:

"available_reactors"
  - Reading shows the available reactors, one per line.

   For example:
     # cat available_reactors
     nop
     panic
     printk

 "reacting_on"
   - It is an on/off general switch for reactors, disabling
   all reactions.

 "monitors/MONITOR/reactors"
   - List available reactors, with the select reaction for the given
   MONITOR inside []. The default one is the nop (no operation)
   reactor.
   - Writing the name of a reactor enables it to the given
   MONITOR.

   For example:
     # cat monitors/wip/reactors
     [nop]
     panic
     printk
     # echo panic > monitors/wip/reactors
     # cat monitors/wip/reactors
     nop
     [panic]
     printk

Link: https://lkml.kernel.org/r/1794eb994637457bdeaa6bad0b8263d2f7eece0c.1659052063.git.bristot@kernel.org

Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marco Elver <elver@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Gabriele Paoloni <gpaoloni@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Cc: Tao Zhou <tao.zhou@linux.dev>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-trace-devel@vger.kernel.org
Signed-off-by: default avatarDaniel Bristot de Oliveira <bristot@kernel.org>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 102227b9
...@@ -24,6 +24,14 @@ ...@@ -24,6 +24,14 @@
union rv_task_monitor { union rv_task_monitor {
}; };
#ifdef CONFIG_RV_REACTORS
struct rv_reactor {
const char *name;
const char *description;
void (*react)(char *msg);
};
#endif
struct rv_monitor { struct rv_monitor {
const char *name; const char *name;
const char *description; const char *description;
...@@ -31,6 +39,9 @@ struct rv_monitor { ...@@ -31,6 +39,9 @@ struct rv_monitor {
int (*enable)(void); int (*enable)(void);
void (*disable)(void); void (*disable)(void);
void (*reset)(void); void (*reset)(void);
#ifdef CONFIG_RV_REACTORS
void (*react)(char *msg);
#endif
}; };
bool rv_monitoring_on(void); bool rv_monitoring_on(void);
...@@ -39,5 +50,11 @@ int rv_register_monitor(struct rv_monitor *monitor); ...@@ -39,5 +50,11 @@ int rv_register_monitor(struct rv_monitor *monitor);
int rv_get_task_monitor_slot(void); int rv_get_task_monitor_slot(void);
void rv_put_task_monitor_slot(int slot); void rv_put_task_monitor_slot(int slot);
#ifdef CONFIG_RV_REACTORS
bool rv_reacting_on(void);
int rv_unregister_reactor(struct rv_reactor *reactor);
int rv_register_reactor(struct rv_reactor *reactor);
#endif /* CONFIG_RV_REACTORS */
#endif /* CONFIG_RV */ #endif /* CONFIG_RV */
#endif /* _LINUX_RV_H */ #endif /* _LINUX_RV_H */
...@@ -10,3 +10,14 @@ menuconfig RV ...@@ -10,3 +10,14 @@ menuconfig RV
theorem proving). RV works by analyzing the trace of the system's theorem proving). RV works by analyzing the trace of the system's
actual execution, comparing it against a formal specification of actual execution, comparing it against a formal specification of
the system behavior. the system behavior.
config RV_REACTORS
bool "Runtime verification reactors"
default y
depends on RV
help
Enables the online runtime verification reactors. A runtime
monitor can cause a reaction to the detection of an exception
on the model's execution. By default, the monitors have
tracing reactions, printing the monitor output via tracepoints,
but other reactions can be added (on-demand) via this interface.
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RV) += rv.o obj-$(CONFIG_RV) += rv.o
obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
...@@ -353,6 +353,10 @@ static int create_monitor_dir(struct rv_monitor_def *mdef) ...@@ -353,6 +353,10 @@ static int create_monitor_dir(struct rv_monitor_def *mdef)
goto out_remove_root; goto out_remove_root;
} }
retval = reactor_populate_monitor(mdef);
if (retval)
goto out_remove_root;
return 0; return 0;
out_remove_root: out_remove_root:
...@@ -669,6 +673,7 @@ static const struct file_operations monitoring_on_fops = { ...@@ -669,6 +673,7 @@ static const struct file_operations monitoring_on_fops = {
static void destroy_monitor_dir(struct rv_monitor_def *mdef) static void destroy_monitor_dir(struct rv_monitor_def *mdef)
{ {
reactor_cleanup_monitor(mdef);
rv_remove(mdef->root_d); rv_remove(mdef->root_d);
} }
...@@ -747,6 +752,7 @@ int rv_unregister_monitor(struct rv_monitor *monitor) ...@@ -747,6 +752,7 @@ int rv_unregister_monitor(struct rv_monitor *monitor)
int __init rv_init_interface(void) int __init rv_init_interface(void)
{ {
struct dentry *tmp; struct dentry *tmp;
int retval;
rv_root.root_dir = rv_create_dir("rv", NULL); rv_root.root_dir = rv_create_dir("rv", NULL);
if (!rv_root.root_dir) if (!rv_root.root_dir)
...@@ -770,6 +776,9 @@ int __init rv_init_interface(void) ...@@ -770,6 +776,9 @@ int __init rv_init_interface(void)
&monitoring_on_fops); &monitoring_on_fops);
if (!tmp) if (!tmp)
goto out_err; goto out_err;
retval = init_rv_reactors(rv_root.root_dir);
if (retval)
goto out_err;
turn_monitoring_on(); turn_monitoring_on();
......
...@@ -18,16 +18,51 @@ struct rv_interface { ...@@ -18,16 +18,51 @@ struct rv_interface {
#define rv_remove tracefs_remove #define rv_remove tracefs_remove
#define MAX_RV_MONITOR_NAME_SIZE 32 #define MAX_RV_MONITOR_NAME_SIZE 32
#define MAX_RV_REACTOR_NAME_SIZE 32
extern struct mutex rv_interface_lock; extern struct mutex rv_interface_lock;
#ifdef CONFIG_RV_REACTORS
struct rv_reactor_def {
struct list_head list;
struct rv_reactor *reactor;
/* protected by the monitor interface lock */
int counter;
};
#endif
struct rv_monitor_def { struct rv_monitor_def {
struct list_head list; struct list_head list;
struct rv_monitor *monitor; struct rv_monitor *monitor;
struct dentry *root_d; struct dentry *root_d;
#ifdef CONFIG_RV_REACTORS
struct rv_reactor_def *rdef;
bool reacting;
#endif
bool task_monitor; bool task_monitor;
}; };
struct dentry *get_monitors_root(void); struct dentry *get_monitors_root(void);
int rv_disable_monitor(struct rv_monitor_def *mdef); int rv_disable_monitor(struct rv_monitor_def *mdef);
int rv_enable_monitor(struct rv_monitor_def *mdef); int rv_enable_monitor(struct rv_monitor_def *mdef);
#ifdef CONFIG_RV_REACTORS
int reactor_populate_monitor(struct rv_monitor_def *mdef);
void reactor_cleanup_monitor(struct rv_monitor_def *mdef);
int init_rv_reactors(struct dentry *root_dir);
#else
static inline int reactor_populate_monitor(struct rv_monitor_def *mdef)
{
return 0;
}
static inline void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
{
return;
}
static inline int init_rv_reactors(struct dentry *root_dir)
{
return 0;
}
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment