linux/kernel/trace/rv/rv_reactors.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <[email protected]>
 *
 * Runtime reactor 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.
 *
 * == Registering reactors ==
 *
 * The struct rv_reactor defines a callback function to be executed
 * in case of a model exception happens. The callback function
 * receives a message to be (optionally) printed before executing
 * the reaction.
 *
 * A RV reactor is registered via:
 *   int rv_register_reactor(struct rv_reactor *reactor)
 * And unregistered via:
 *   int rv_unregister_reactor(struct rv_reactor *reactor)
 *
 * These functions are exported to modules, enabling reactors to be
 * dynamically loaded.
 *
 * == User interface ==
 *
 * The user interface resembles the kernel tracing interface and
 * presents these files:
 *
 *  "available_reactors"
 *    - List 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 an 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
 */

#include <linux/slab.h>

#include "rv.h"

/*
 * Interface for the reactor register.
 */
static LIST_HEAD(rv_reactors_list);

static struct rv_reactor_def *get_reactor_rdef_by_name(char *name)
{}

/*
 * Available reactors seq functions.
 */
static int reactors_show(struct seq_file *m, void *p)
{}

static void reactors_stop(struct seq_file *m, void *p)
{}

static void *reactors_start(struct seq_file *m, loff_t *pos)
{}

static void *reactors_next(struct seq_file *m, void *p, loff_t *pos)
{}

/*
 * available_reactors seq definition.
 */
static const struct seq_operations available_reactors_seq_ops =;

/*
 * available_reactors interface.
 */
static int available_reactors_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &available_reactors_seq_ops);
};

static const struct file_operations available_reactors_ops =;

/*
 * Monitor's reactor file.
 */
static int monitor_reactor_show(struct seq_file *m, void *p)
{}

/*
 * available_reactors seq definition.
 */
static const struct seq_operations monitor_reactors_seq_ops =;

static void monitor_swap_reactors(struct rv_monitor_def *mdef, struct rv_reactor_def *rdef,
				    bool reacting)
{}

static ssize_t
monitor_reactors_write(struct file *file, const char __user *user_buf,
		      size_t count, loff_t *ppos)
{}

/*
 * available_reactors interface.
 */
static int monitor_reactors_open(struct inode *inode, struct file *file)
{
	struct rv_monitor_def *mdef = inode->i_private;
	struct seq_file *seq_f;
	int ret;

	ret = seq_open(file, &monitor_reactors_seq_ops);
	if (ret < 0)
		return ret;

	/*
	 * seq_open stores the seq_file on the file->private data.
	 */
	seq_f = file->private_data;

	/*
	 * Copy the create file "private" data to the seq_file private data.
	 */
	seq_f->private = mdef;

	return 0;
};

static const struct file_operations monitor_reactors_ops =;

static int __rv_register_reactor(struct rv_reactor *reactor)
{}

/**
 * rv_register_reactor - register a rv reactor.
 * @reactor:	The rv_reactor to be registered.
 *
 * Returns 0 if successful, error otherwise.
 */
int rv_register_reactor(struct rv_reactor *reactor)
{}

/**
 * rv_unregister_reactor - unregister a rv reactor.
 * @reactor:	The rv_reactor to be unregistered.
 *
 * Returns 0 if successful, error otherwise.
 */
int rv_unregister_reactor(struct rv_reactor *reactor)
{}

/*
 * reacting_on interface.
 */
static bool __read_mostly reacting_on;

/**
 * rv_reacting_on - checks if reacting is on
 *
 * Returns 1 if on, 0 otherwise.
 */
bool rv_reacting_on(void)
{}

static ssize_t reacting_on_read_data(struct file *filp,
				     char __user *user_buf,
				     size_t count, loff_t *ppos)
{}

static void turn_reacting_off(void)
{}

static void turn_reacting_on(void)
{}

static ssize_t reacting_on_write_data(struct file *filp, const char __user *user_buf,
				      size_t count, loff_t *ppos)
{}

static const struct file_operations reacting_on_fops =;

/**
 * reactor_populate_monitor - creates per monitor reactors file
 * @mdef:	monitor's definition.
 *
 * Returns 0 if successful, error otherwise.
 */
int reactor_populate_monitor(struct rv_monitor_def *mdef)
{}

/**
 * reactor_cleanup_monitor - cleanup a monitor reference
 * @mdef:       monitor's definition.
 */
void reactor_cleanup_monitor(struct rv_monitor_def *mdef)
{}

/*
 * Nop reactor register
 */
static void rv_nop_reaction(char *msg)
{}

static struct rv_reactor rv_nop =;

int init_rv_reactors(struct dentry *root_dir)
{}