xref: /linux/kernel/trace/rv/rv_reactors.c (revision 04acadcb4453cf8011dd3d4ce8d97fecac42d325)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
4  *
5  * Runtime reactor interface.
6  *
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.
11  *
12  * == Registering reactors ==
13  *
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.
18  *
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)
23  *
24  * These functions are exported to modules, enabling reactors to be
25  * dynamically loaded.
26  *
27  * == User interface ==
28  *
29  * The user interface resembles the kernel tracing interface and
30  * presents these files:
31  *
32  *  "available_reactors"
33  *    - List the available reactors, one per line.
34  *
35  *    For example:
36  *      # cat available_reactors
37  *      nop
38  *      panic
39  *      printk
40  *
41  *  "reacting_on"
42  *    - It is an on/off general switch for reactors, disabling
43  *    all reactions.
44  *
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.
51  *
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
62  */
63 
64 #include <linux/slab.h>
65 
66 #include "rv.h"
67 
68 /*
69  * Interface for the reactor register.
70  */
71 static LIST_HEAD(rv_reactors_list);
72 
73 static struct rv_reactor_def *get_reactor_rdef_by_name(char *name)
74 {
75 	struct rv_reactor_def *r;
76 
77 	list_for_each_entry(r, &rv_reactors_list, list) {
78 		if (strcmp(name, r->reactor->name) == 0)
79 			return r;
80 	}
81 	return NULL;
82 }
83 
84 /*
85  * Available reactors seq functions.
86  */
87 static int reactors_show(struct seq_file *m, void *p)
88 {
89 	struct rv_reactor_def *rea_def = p;
90 
91 	seq_printf(m, "%s\n", rea_def->reactor->name);
92 	return 0;
93 }
94 
95 static void reactors_stop(struct seq_file *m, void *p)
96 {
97 	mutex_unlock(&rv_interface_lock);
98 }
99 
100 static void *reactors_start(struct seq_file *m, loff_t *pos)
101 {
102 	mutex_lock(&rv_interface_lock);
103 	return seq_list_start(&rv_reactors_list, *pos);
104 }
105 
106 static void *reactors_next(struct seq_file *m, void *p, loff_t *pos)
107 {
108 	return seq_list_next(p, &rv_reactors_list, pos);
109 }
110 
111 /*
112  * available_reactors seq definition.
113  */
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
119 };
120 
121 /*
122  * available_reactors interface.
123  */
124 static int available_reactors_open(struct inode *inode, struct file *file)
125 {
126 	return seq_open(file, &available_reactors_seq_ops);
127 };
128 
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
134 };
135 
136 /*
137  * Monitor's reactor file.
138  */
139 static int monitor_reactor_show(struct seq_file *m, void *p)
140 {
141 	struct rv_monitor_def *mdef = m->private;
142 	struct rv_reactor_def *rdef = p;
143 
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;
149 }
150 
151 /*
152  * available_reactors seq definition.
153  */
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
159 };
160 
161 static void monitor_swap_reactors(struct rv_monitor_def *mdef, struct rv_reactor_def *rdef,
162 				    bool reacting)
163 {
164 	bool monitor_enabled;
165 
166 	/* nothing to do */
167 	if (mdef->rdef == rdef)
168 		return;
169 
170 	monitor_enabled = mdef->monitor->enabled;
171 	if (monitor_enabled)
172 		rv_disable_monitor(mdef);
173 
174 	/* swap reactor's usage */
175 	mdef->rdef->counter--;
176 	rdef->counter++;
177 
178 	mdef->rdef = rdef;
179 	mdef->reacting = reacting;
180 	mdef->monitor->react = rdef->reactor->react;
181 
182 	if (monitor_enabled)
183 		rv_enable_monitor(mdef);
184 }
185 
186 static ssize_t
187 monitor_reactors_write(struct file *file, const char __user *user_buf,
188 		      size_t count, loff_t *ppos)
189 {
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;
198 
199 	if (count < 1 || count > MAX_RV_REACTOR_NAME_SIZE + 1)
200 		return -EINVAL;
201 
202 	memset(buff, 0, sizeof(buff));
203 
204 	retval = simple_write_to_buffer(buff, sizeof(buff) - 1, ppos, user_buf, count);
205 	if (retval < 0)
206 		return -EFAULT;
207 
208 	ptr = strim(buff);
209 
210 	len = strlen(ptr);
211 	if (!len)
212 		return count;
213 
214 	/*
215 	 * See monitor_reactors_open()
216 	 */
217 	seq_f = file->private_data;
218 	mdef = seq_f->private;
219 
220 	mutex_lock(&rv_interface_lock);
221 
222 	retval = -EINVAL;
223 
224 	list_for_each_entry(rdef, &rv_reactors_list, list) {
225 		if (strcmp(ptr, rdef->reactor->name) != 0)
226 			continue;
227 
228 		if (rdef == get_reactor_rdef_by_name("nop"))
229 			enable = false;
230 		else
231 			enable = true;
232 
233 		monitor_swap_reactors(mdef, rdef, enable);
234 
235 		retval = count;
236 		break;
237 	}
238 
239 	mutex_unlock(&rv_interface_lock);
240 
241 	return retval;
242 }
243 
244 /*
245  * available_reactors interface.
246  */
247 static int monitor_reactors_open(struct inode *inode, struct file *file)
248 {
249 	struct rv_monitor_def *mdef = inode->i_private;
250 	struct seq_file *seq_f;
251 	int ret;
252 
253 	ret = seq_open(file, &monitor_reactors_seq_ops);
254 	if (ret < 0)
255 		return ret;
256 
257 	/*
258 	 * seq_open stores the seq_file on the file->private data.
259 	 */
260 	seq_f = file->private_data;
261 
262 	/*
263 	 * Copy the create file "private" data to the seq_file private data.
264 	 */
265 	seq_f->private = mdef;
266 
267 	return 0;
268 };
269 
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
276 };
277 
278 static int __rv_register_reactor(struct rv_reactor *reactor)
279 {
280 	struct rv_reactor_def *r;
281 
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;
286 		}
287 	}
288 
289 	r = kzalloc(sizeof(struct rv_reactor_def), GFP_KERNEL);
290 	if (!r)
291 		return -ENOMEM;
292 
293 	r->reactor = reactor;
294 	r->counter = 0;
295 
296 	list_add_tail(&r->list, &rv_reactors_list);
297 
298 	return 0;
299 }
300 
301 /**
302  * rv_register_reactor - register a rv reactor.
303  * @reactor:	The rv_reactor to be registered.
304  *
305  * Returns 0 if successful, error otherwise.
306  */
307 int rv_register_reactor(struct rv_reactor *reactor)
308 {
309 	int retval = 0;
310 
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;
315 	}
316 
317 	mutex_lock(&rv_interface_lock);
318 	retval = __rv_register_reactor(reactor);
319 	mutex_unlock(&rv_interface_lock);
320 	return retval;
321 }
322 
323 /**
324  * rv_unregister_reactor - unregister a rv reactor.
325  * @reactor:	The rv_reactor to be unregistered.
326  *
327  * Returns 0 if successful, error otherwise.
328  */
329 int rv_unregister_reactor(struct rv_reactor *reactor)
330 {
331 	struct rv_reactor_def *ptr, *next;
332 
333 	mutex_lock(&rv_interface_lock);
334 
335 	list_for_each_entry_safe(ptr, next, &rv_reactors_list, list) {
336 		if (strcmp(reactor->name, ptr->reactor->name) == 0) {
337 
338 			if (!ptr->counter) {
339 				list_del(&ptr->list);
340 			} else {
341 				printk(KERN_WARNING
342 				       "rv: the rv_reactor %s is in use by %d monitor(s)\n",
343 				       ptr->reactor->name, ptr->counter);
344 				printk(KERN_WARNING "rv: the rv_reactor %s cannot be removed\n",
345 				       ptr->reactor->name);
346 				return -EBUSY;
347 			}
348 		}
349 	}
350 
351 	mutex_unlock(&rv_interface_lock);
352 	return 0;
353 }
354 
355 /*
356  * reacting_on interface.
357  */
358 static bool __read_mostly reacting_on;
359 
360 /**
361  * rv_reacting_on - checks if reacting is on
362  *
363  * Returns 1 if on, 0 otherwise.
364  */
365 bool rv_reacting_on(void)
366 {
367 	/* Ensures that concurrent monitors read consistent reacting_on */
368 	smp_rmb();
369 	return READ_ONCE(reacting_on);
370 }
371 
372 static ssize_t reacting_on_read_data(struct file *filp,
373 				     char __user *user_buf,
374 				     size_t count, loff_t *ppos)
375 {
376 	char *buff;
377 
378 	buff = rv_reacting_on() ? "1\n" : "0\n";
379 
380 	return simple_read_from_buffer(user_buf, count, ppos, buff, strlen(buff)+1);
381 }
382 
383 static void turn_reacting_off(void)
384 {
385 	WRITE_ONCE(reacting_on, false);
386 	/* Ensures that concurrent monitors read consistent reacting_on */
387 	smp_wmb();
388 }
389 
390 static void turn_reacting_on(void)
391 {
392 	WRITE_ONCE(reacting_on, true);
393 	/* Ensures that concurrent monitors read consistent reacting_on */
394 	smp_wmb();
395 }
396 
397 static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
398 				      size_t count, loff_t *ppos)
399 {
400 	int retval;
401 	bool val;
402 
403 	retval = kstrtobool_from_user(user_buf, count, &val);
404 	if (retval)
405 		return retval;
406 
407 	mutex_lock(&rv_interface_lock);
408 
409 	if (val)
410 		turn_reacting_on();
411 	else
412 		turn_reacting_off();
413 
414 	/*
415 	 * Wait for the execution of all events to finish
416 	 * before returning to user-space.
417 	 */
418 	tracepoint_synchronize_unregister();
419 
420 	mutex_unlock(&rv_interface_lock);
421 
422 	return count;
423 }
424 
425 static const struct file_operations reacting_on_fops = {
426 	.open   = simple_open,
427 	.llseek = no_llseek,
428 	.write  = reacting_on_write_data,
429 	.read   = reacting_on_read_data,
430 };
431 
432 /**
433  * reactor_populate_monitor - creates per monitor reactors file
434  * @mdef:	monitor's definition.
435  *
436  * Returns 0 if successful, error otherwise.
437  */
438 int reactor_populate_monitor(struct rv_monitor_def *mdef)
439 {
440 	struct dentry *tmp;
441 
442 	tmp = rv_create_file("reactors", RV_MODE_WRITE, mdef->root_d, mdef, &monitor_reactors_ops);
443 	if (!tmp)
444 		return -ENOMEM;
445 
446 	/*
447 	 * Configure as the rv_nop reactor.
448 	 */
449 	mdef->rdef = get_reactor_rdef_by_name("nop");
450 	mdef->rdef->counter++;
451 	mdef->reacting = false;
452 
453 	return 0;
454 }
455 
456 /**
457  * reactor_cleanup_monitor - cleanup a monitor reference
458  * @mdef:       monitor's definition.
459  */
460 void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
461 {
462 	lockdep_assert_held(&rv_interface_lock);
463 	mdef->rdef->counter--;
464 	WARN_ON_ONCE(mdef->rdef->counter < 0);
465 }
466 
467 /*
468  * Nop reactor register
469  */
470 static void rv_nop_reaction(char *msg)
471 {
472 }
473 
474 static struct rv_reactor rv_nop = {
475 	.name = "nop",
476 	.description = "no-operation reactor: do nothing.",
477 	.react = rv_nop_reaction
478 };
479 
480 int init_rv_reactors(struct dentry *root_dir)
481 {
482 	struct dentry *available, *reacting;
483 	int retval;
484 
485 	available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
486 				   &available_reactors_ops);
487 	if (!available)
488 		goto out_err;
489 
490 	reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
491 	if (!reacting)
492 		goto rm_available;
493 
494 	retval = __rv_register_reactor(&rv_nop);
495 	if (retval)
496 		goto rm_reacting;
497 
498 	turn_reacting_on();
499 
500 	return 0;
501 
502 rm_reacting:
503 	rv_remove(reacting);
504 rm_available:
505 	rv_remove(available);
506 out_err:
507 	return -ENOMEM;
508 }
509