printf: Remove unused 'bprintf'
[drm/drm-misc.git] / kernel / trace / rv / rv_reactors.c
blob7b49cbe388d4c400eddbc0a8e97f3223ddafeb0e
1 // SPDX-License-Identifier: GPL-2.0
2 /*
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
17 * the reaction.
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
25 * dynamically loaded.
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.
35 * For example:
36 * # cat available_reactors
37 * nop
38 * panic
39 * printk
41 * "reacting_on"
42 * - It is an on/off general switch for reactors, disabling
43 * all reactions.
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)
48 * reactor.
49 * - Writing the name of an reactor enables it to the given
50 * MONITOR.
52 * For example:
53 * # cat monitors/wip/reactors
54 * [nop]
55 * panic
56 * printk
57 * # echo panic > monitors/wip/reactors
58 * # cat monitors/wip/reactors
59 * nop
60 * [panic]
61 * printk
64 #include <linux/slab.h>
66 #include "rv.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)
79 return r;
81 return NULL;
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);
92 return 0;
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,
131 .read = seq_read,
132 .llseek = seq_lseek,
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);
146 else
147 seq_printf(m, "%s\n", rdef->reactor->name);
148 return 0;
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,
162 bool reacting)
164 bool monitor_enabled;
166 /* nothing to do */
167 if (mdef->rdef == rdef)
168 return;
170 monitor_enabled = mdef->monitor->enabled;
171 if (monitor_enabled)
172 rv_disable_monitor(mdef);
174 /* swap reactor's usage */
175 mdef->rdef->counter--;
176 rdef->counter++;
178 mdef->rdef = rdef;
179 mdef->reacting = reacting;
180 mdef->monitor->react = rdef->reactor->react;
182 if (monitor_enabled)
183 rv_enable_monitor(mdef);
186 static ssize_t
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;
195 bool enable;
196 char *ptr;
197 int len;
199 if (count < 1 || count > MAX_RV_REACTOR_NAME_SIZE + 1)
200 return -EINVAL;
202 memset(buff, 0, sizeof(buff));
204 retval = simple_write_to_buffer(buff, sizeof(buff) - 1, ppos, user_buf, count);
205 if (retval < 0)
206 return -EFAULT;
208 ptr = strim(buff);
210 len = strlen(ptr);
211 if (!len)
212 return count;
215 * See monitor_reactors_open()
217 seq_f = file->private_data;
218 mdef = seq_f->private;
220 mutex_lock(&rv_interface_lock);
222 retval = -EINVAL;
224 list_for_each_entry(rdef, &rv_reactors_list, list) {
225 if (strcmp(ptr, rdef->reactor->name) != 0)
226 continue;
228 if (rdef == get_reactor_rdef_by_name("nop"))
229 enable = false;
230 else
231 enable = true;
233 monitor_swap_reactors(mdef, rdef, enable);
235 retval = count;
236 break;
239 mutex_unlock(&rv_interface_lock);
241 return retval;
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;
251 int ret;
253 ret = seq_open(file, &monitor_reactors_seq_ops);
254 if (ret < 0)
255 return ret;
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;
267 return 0;
270 static const struct file_operations monitor_reactors_ops = {
271 .open = monitor_reactors_open,
272 .read = seq_read,
273 .llseek = seq_lseek,
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);
285 return -EINVAL;
289 r = kzalloc(sizeof(struct rv_reactor_def), GFP_KERNEL);
290 if (!r)
291 return -ENOMEM;
293 r->reactor = reactor;
294 r->counter = 0;
296 list_add_tail(&r->list, &rv_reactors_list);
298 return 0;
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)
309 int retval = 0;
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);
314 return -EINVAL;
317 mutex_lock(&rv_interface_lock);
318 retval = __rv_register_reactor(reactor);
319 mutex_unlock(&rv_interface_lock);
320 return retval;
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;
332 int ret = 0;
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) {
339 if (!ptr->counter) {
340 list_del(&ptr->list);
341 } else {
342 printk(KERN_WARNING
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",
346 ptr->reactor->name);
347 ret = -EBUSY;
348 break;
353 mutex_unlock(&rv_interface_lock);
354 return ret;
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 */
370 smp_rmb();
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)
378 char *buff;
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 */
389 smp_wmb();
392 static void turn_reacting_on(void)
394 WRITE_ONCE(reacting_on, true);
395 /* Ensures that concurrent monitors read consistent reacting_on */
396 smp_wmb();
399 static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
400 size_t count, loff_t *ppos)
402 int retval;
403 bool val;
405 retval = kstrtobool_from_user(user_buf, count, &val);
406 if (retval)
407 return retval;
409 mutex_lock(&rv_interface_lock);
411 if (val)
412 turn_reacting_on();
413 else
414 turn_reacting_off();
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);
424 return count;
427 static const struct file_operations reacting_on_fops = {
428 .open = simple_open,
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)
441 struct dentry *tmp;
443 tmp = rv_create_file("reactors", RV_MODE_WRITE, mdef->root_d, mdef, &monitor_reactors_ops);
444 if (!tmp)
445 return -ENOMEM;
448 * Configure as the rv_nop reactor.
450 mdef->rdef = get_reactor_rdef_by_name("nop");
451 mdef->rdef->counter++;
452 mdef->reacting = false;
454 return 0;
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 = {
476 .name = "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;
484 int retval;
486 available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
487 &available_reactors_ops);
488 if (!available)
489 goto out_err;
491 reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
492 if (!reacting)
493 goto rm_available;
495 retval = __rv_register_reactor(&rv_nop);
496 if (retval)
497 goto rm_reacting;
499 turn_reacting_on();
501 return 0;
503 rm_reacting:
504 rv_remove(reacting);
505 rm_available:
506 rv_remove(available);
507 out_err:
508 return -ENOMEM;