1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
5 * Runtime reactor interface.
7 * A runtime monitor can cause a reaction to the detection of an
8 * exception on the model's execution. By default, the monitors have
9 * tracing reactions, printing the monitor output via tracepoints.
10 * But other reactions can be added (on-demand) via this interface.
12 * == Registering reactors ==
14 * The struct rv_reactor defines a callback function to be executed
15 * in case of a model exception happens. The callback function
16 * receives a message to be (optionally) printed before executing
19 * A RV reactor is registered via:
20 * int rv_register_reactor(struct rv_reactor *reactor)
21 * And unregistered via:
22 * int rv_unregister_reactor(struct rv_reactor *reactor)
24 * These functions are exported to modules, enabling reactors to be
27 * == User interface ==
29 * The user interface resembles the kernel tracing interface and
30 * presents these files:
32 * "available_reactors"
33 * - List the available reactors, one per line.
36 * # cat available_reactors
42 * - It is an on/off general switch for reactors, disabling
45 * "monitors/MONITOR/reactors"
46 * - List available reactors, with the select reaction for the given
47 * MONITOR inside []. The default one is the nop (no operation)
49 * - Writing the name of an reactor enables it to the given
53 * # cat monitors/wip/reactors
57 * # echo panic > monitors/wip/reactors
58 * # cat monitors/wip/reactors
64 #include <linux/slab.h>
69 * Interface for the reactor register.
71 static LIST_HEAD(rv_reactors_list
);
73 static struct rv_reactor_def
*get_reactor_rdef_by_name(char *name
)
75 struct rv_reactor_def
*r
;
77 list_for_each_entry(r
, &rv_reactors_list
, list
) {
78 if (strcmp(name
, r
->reactor
->name
) == 0)
85 * Available reactors seq functions.
87 static int reactors_show(struct seq_file
*m
, void *p
)
89 struct rv_reactor_def
*rea_def
= p
;
91 seq_printf(m
, "%s\n", rea_def
->reactor
->name
);
95 static void reactors_stop(struct seq_file
*m
, void *p
)
97 mutex_unlock(&rv_interface_lock
);
100 static void *reactors_start(struct seq_file
*m
, loff_t
*pos
)
102 mutex_lock(&rv_interface_lock
);
103 return seq_list_start(&rv_reactors_list
, *pos
);
106 static void *reactors_next(struct seq_file
*m
, void *p
, loff_t
*pos
)
108 return seq_list_next(p
, &rv_reactors_list
, pos
);
112 * available_reactors seq definition.
114 static const struct seq_operations available_reactors_seq_ops
= {
115 .start
= reactors_start
,
116 .next
= reactors_next
,
117 .stop
= reactors_stop
,
118 .show
= reactors_show
122 * available_reactors interface.
124 static int available_reactors_open(struct inode
*inode
, struct file
*file
)
126 return seq_open(file
, &available_reactors_seq_ops
);
129 static const struct file_operations available_reactors_ops
= {
130 .open
= available_reactors_open
,
133 .release
= seq_release
137 * Monitor's reactor file.
139 static int monitor_reactor_show(struct seq_file
*m
, void *p
)
141 struct rv_monitor_def
*mdef
= m
->private;
142 struct rv_reactor_def
*rdef
= p
;
144 if (mdef
->rdef
== rdef
)
145 seq_printf(m
, "[%s]\n", rdef
->reactor
->name
);
147 seq_printf(m
, "%s\n", rdef
->reactor
->name
);
152 * available_reactors seq definition.
154 static const struct seq_operations monitor_reactors_seq_ops
= {
155 .start
= reactors_start
,
156 .next
= reactors_next
,
157 .stop
= reactors_stop
,
158 .show
= monitor_reactor_show
161 static void monitor_swap_reactors(struct rv_monitor_def
*mdef
, struct rv_reactor_def
*rdef
,
164 bool monitor_enabled
;
167 if (mdef
->rdef
== rdef
)
170 monitor_enabled
= mdef
->monitor
->enabled
;
172 rv_disable_monitor(mdef
);
174 /* swap reactor's usage */
175 mdef
->rdef
->counter
--;
179 mdef
->reacting
= reacting
;
180 mdef
->monitor
->react
= rdef
->reactor
->react
;
183 rv_enable_monitor(mdef
);
187 monitor_reactors_write(struct file
*file
, const char __user
*user_buf
,
188 size_t count
, loff_t
*ppos
)
190 char buff
[MAX_RV_REACTOR_NAME_SIZE
+ 2];
191 struct rv_monitor_def
*mdef
;
192 struct rv_reactor_def
*rdef
;
193 struct seq_file
*seq_f
;
194 int retval
= -EINVAL
;
199 if (count
< 1 || count
> MAX_RV_REACTOR_NAME_SIZE
+ 1)
202 memset(buff
, 0, sizeof(buff
));
204 retval
= simple_write_to_buffer(buff
, sizeof(buff
) - 1, ppos
, user_buf
, count
);
215 * See monitor_reactors_open()
217 seq_f
= file
->private_data
;
218 mdef
= seq_f
->private;
220 mutex_lock(&rv_interface_lock
);
224 list_for_each_entry(rdef
, &rv_reactors_list
, list
) {
225 if (strcmp(ptr
, rdef
->reactor
->name
) != 0)
228 if (rdef
== get_reactor_rdef_by_name("nop"))
233 monitor_swap_reactors(mdef
, rdef
, enable
);
239 mutex_unlock(&rv_interface_lock
);
245 * available_reactors interface.
247 static int monitor_reactors_open(struct inode
*inode
, struct file
*file
)
249 struct rv_monitor_def
*mdef
= inode
->i_private
;
250 struct seq_file
*seq_f
;
253 ret
= seq_open(file
, &monitor_reactors_seq_ops
);
258 * seq_open stores the seq_file on the file->private data.
260 seq_f
= file
->private_data
;
263 * Copy the create file "private" data to the seq_file private data.
265 seq_f
->private = mdef
;
270 static const struct file_operations monitor_reactors_ops
= {
271 .open
= monitor_reactors_open
,
274 .release
= seq_release
,
275 .write
= monitor_reactors_write
278 static int __rv_register_reactor(struct rv_reactor
*reactor
)
280 struct rv_reactor_def
*r
;
282 list_for_each_entry(r
, &rv_reactors_list
, list
) {
283 if (strcmp(reactor
->name
, r
->reactor
->name
) == 0) {
284 pr_info("Reactor %s is already registered\n", reactor
->name
);
289 r
= kzalloc(sizeof(struct rv_reactor_def
), GFP_KERNEL
);
293 r
->reactor
= reactor
;
296 list_add_tail(&r
->list
, &rv_reactors_list
);
302 * rv_register_reactor - register a rv reactor.
303 * @reactor: The rv_reactor to be registered.
305 * Returns 0 if successful, error otherwise.
307 int rv_register_reactor(struct rv_reactor
*reactor
)
311 if (strlen(reactor
->name
) >= MAX_RV_REACTOR_NAME_SIZE
) {
312 pr_info("Reactor %s has a name longer than %d\n",
313 reactor
->name
, MAX_RV_MONITOR_NAME_SIZE
);
317 mutex_lock(&rv_interface_lock
);
318 retval
= __rv_register_reactor(reactor
);
319 mutex_unlock(&rv_interface_lock
);
324 * rv_unregister_reactor - unregister a rv reactor.
325 * @reactor: The rv_reactor to be unregistered.
327 * Returns 0 if successful, error otherwise.
329 int rv_unregister_reactor(struct rv_reactor
*reactor
)
331 struct rv_reactor_def
*ptr
, *next
;
334 mutex_lock(&rv_interface_lock
);
336 list_for_each_entry_safe(ptr
, next
, &rv_reactors_list
, list
) {
337 if (strcmp(reactor
->name
, ptr
->reactor
->name
) == 0) {
340 list_del(&ptr
->list
);
343 "rv: the rv_reactor %s is in use by %d monitor(s)\n",
344 ptr
->reactor
->name
, ptr
->counter
);
345 printk(KERN_WARNING
"rv: the rv_reactor %s cannot be removed\n",
353 mutex_unlock(&rv_interface_lock
);
358 * reacting_on interface.
360 static bool __read_mostly reacting_on
;
363 * rv_reacting_on - checks if reacting is on
365 * Returns 1 if on, 0 otherwise.
367 bool rv_reacting_on(void)
369 /* Ensures that concurrent monitors read consistent reacting_on */
371 return READ_ONCE(reacting_on
);
374 static ssize_t
reacting_on_read_data(struct file
*filp
,
375 char __user
*user_buf
,
376 size_t count
, loff_t
*ppos
)
380 buff
= rv_reacting_on() ? "1\n" : "0\n";
382 return simple_read_from_buffer(user_buf
, count
, ppos
, buff
, strlen(buff
)+1);
385 static void turn_reacting_off(void)
387 WRITE_ONCE(reacting_on
, false);
388 /* Ensures that concurrent monitors read consistent reacting_on */
392 static void turn_reacting_on(void)
394 WRITE_ONCE(reacting_on
, true);
395 /* Ensures that concurrent monitors read consistent reacting_on */
399 static ssize_t
reacting_on_write_data(struct file
*filp
, const char __user
*user_buf
,
400 size_t count
, loff_t
*ppos
)
405 retval
= kstrtobool_from_user(user_buf
, count
, &val
);
409 mutex_lock(&rv_interface_lock
);
417 * Wait for the execution of all events to finish
418 * before returning to user-space.
420 tracepoint_synchronize_unregister();
422 mutex_unlock(&rv_interface_lock
);
427 static const struct file_operations reacting_on_fops
= {
429 .write
= reacting_on_write_data
,
430 .read
= reacting_on_read_data
,
434 * reactor_populate_monitor - creates per monitor reactors file
435 * @mdef: monitor's definition.
437 * Returns 0 if successful, error otherwise.
439 int reactor_populate_monitor(struct rv_monitor_def
*mdef
)
443 tmp
= rv_create_file("reactors", RV_MODE_WRITE
, mdef
->root_d
, mdef
, &monitor_reactors_ops
);
448 * Configure as the rv_nop reactor.
450 mdef
->rdef
= get_reactor_rdef_by_name("nop");
451 mdef
->rdef
->counter
++;
452 mdef
->reacting
= false;
458 * reactor_cleanup_monitor - cleanup a monitor reference
459 * @mdef: monitor's definition.
461 void reactor_cleanup_monitor(struct rv_monitor_def
*mdef
)
463 lockdep_assert_held(&rv_interface_lock
);
464 mdef
->rdef
->counter
--;
465 WARN_ON_ONCE(mdef
->rdef
->counter
< 0);
469 * Nop reactor register
471 static void rv_nop_reaction(char *msg
)
475 static struct rv_reactor rv_nop
= {
477 .description
= "no-operation reactor: do nothing.",
478 .react
= rv_nop_reaction
481 int init_rv_reactors(struct dentry
*root_dir
)
483 struct dentry
*available
, *reacting
;
486 available
= rv_create_file("available_reactors", RV_MODE_READ
, root_dir
, NULL
,
487 &available_reactors_ops
);
491 reacting
= rv_create_file("reacting_on", RV_MODE_WRITE
, root_dir
, NULL
, &reacting_on_fops
);
495 retval
= __rv_register_reactor(&rv_nop
);
506 rv_remove(available
);