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 */
71static LIST_HEAD(rv_reactors_list);
72
73static 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 */
87static 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
95static void reactors_stop(struct seq_file *m, void *p)
96{
97	mutex_unlock(&rv_interface_lock);
98}
99
100static 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
106static 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 */
114static 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 */
124static int available_reactors_open(struct inode *inode, struct file *file)
125{
126	return seq_open(file, &available_reactors_seq_ops);
127};
128
129static 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 */
139static 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 */
154static 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
161static 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
186static ssize_t
187monitor_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 */
247static 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
270static 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
278static 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 */
307int 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 */
329int rv_unregister_reactor(struct rv_reactor *reactor)
330{
331	struct rv_reactor_def *ptr, *next;
332	int ret = 0;
333
334	mutex_lock(&rv_interface_lock);
335
336	list_for_each_entry_safe(ptr, next, &rv_reactors_list, list) {
337		if (strcmp(reactor->name, ptr->reactor->name) == 0) {
338
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;
349			}
350		}
351	}
352
353	mutex_unlock(&rv_interface_lock);
354	return ret;
355}
356
357/*
358 * reacting_on interface.
359 */
360static bool __read_mostly reacting_on;
361
362/**
363 * rv_reacting_on - checks if reacting is on
364 *
365 * Returns 1 if on, 0 otherwise.
366 */
367bool rv_reacting_on(void)
368{
369	/* Ensures that concurrent monitors read consistent reacting_on */
370	smp_rmb();
371	return READ_ONCE(reacting_on);
372}
373
374static ssize_t reacting_on_read_data(struct file *filp,
375				     char __user *user_buf,
376				     size_t count, loff_t *ppos)
377{
378	char *buff;
379
380	buff = rv_reacting_on() ? "1\n" : "0\n";
381
382	return simple_read_from_buffer(user_buf, count, ppos, buff, strlen(buff)+1);
383}
384
385static void turn_reacting_off(void)
386{
387	WRITE_ONCE(reacting_on, false);
388	/* Ensures that concurrent monitors read consistent reacting_on */
389	smp_wmb();
390}
391
392static void turn_reacting_on(void)
393{
394	WRITE_ONCE(reacting_on, true);
395	/* Ensures that concurrent monitors read consistent reacting_on */
396	smp_wmb();
397}
398
399static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
400				      size_t count, loff_t *ppos)
401{
402	int retval;
403	bool val;
404
405	retval = kstrtobool_from_user(user_buf, count, &val);
406	if (retval)
407		return retval;
408
409	mutex_lock(&rv_interface_lock);
410
411	if (val)
412		turn_reacting_on();
413	else
414		turn_reacting_off();
415
416	/*
417	 * Wait for the execution of all events to finish
418	 * before returning to user-space.
419	 */
420	tracepoint_synchronize_unregister();
421
422	mutex_unlock(&rv_interface_lock);
423
424	return count;
425}
426
427static const struct file_operations reacting_on_fops = {
428	.open   = simple_open,
429	.llseek = no_llseek,
430	.write  = reacting_on_write_data,
431	.read   = reacting_on_read_data,
432};
433
434/**
435 * reactor_populate_monitor - creates per monitor reactors file
436 * @mdef:	monitor's definition.
437 *
438 * Returns 0 if successful, error otherwise.
439 */
440int reactor_populate_monitor(struct rv_monitor_def *mdef)
441{
442	struct dentry *tmp;
443
444	tmp = rv_create_file("reactors", RV_MODE_WRITE, mdef->root_d, mdef, &monitor_reactors_ops);
445	if (!tmp)
446		return -ENOMEM;
447
448	/*
449	 * Configure as the rv_nop reactor.
450	 */
451	mdef->rdef = get_reactor_rdef_by_name("nop");
452	mdef->rdef->counter++;
453	mdef->reacting = false;
454
455	return 0;
456}
457
458/**
459 * reactor_cleanup_monitor - cleanup a monitor reference
460 * @mdef:       monitor's definition.
461 */
462void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
463{
464	lockdep_assert_held(&rv_interface_lock);
465	mdef->rdef->counter--;
466	WARN_ON_ONCE(mdef->rdef->counter < 0);
467}
468
469/*
470 * Nop reactor register
471 */
472static void rv_nop_reaction(char *msg)
473{
474}
475
476static struct rv_reactor rv_nop = {
477	.name = "nop",
478	.description = "no-operation reactor: do nothing.",
479	.react = rv_nop_reaction
480};
481
482int init_rv_reactors(struct dentry *root_dir)
483{
484	struct dentry *available, *reacting;
485	int retval;
486
487	available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
488				   &available_reactors_ops);
489	if (!available)
490		goto out_err;
491
492	reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
493	if (!reacting)
494		goto rm_available;
495
496	retval = __rv_register_reactor(&rv_nop);
497	if (retval)
498		goto rm_reacting;
499
500	turn_reacting_on();
501
502	return 0;
503
504rm_reacting:
505	rv_remove(reacting);
506rm_available:
507	rv_remove(available);
508out_err:
509	return -ENOMEM;
510}
511