cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kgdb_nmi.c (9564B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * KGDB NMI serial console
      4 *
      5 * Copyright 2010 Google, Inc.
      6 *		  Arve Hjønnevåg <arve@android.com>
      7 *		  Colin Cross <ccross@android.com>
      8 * Copyright 2012 Linaro Ltd.
      9 *		  Anton Vorontsov <anton.vorontsov@linaro.org>
     10 */
     11
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/compiler.h>
     15#include <linux/slab.h>
     16#include <linux/errno.h>
     17#include <linux/atomic.h>
     18#include <linux/console.h>
     19#include <linux/tty.h>
     20#include <linux/tty_driver.h>
     21#include <linux/tty_flip.h>
     22#include <linux/serial_core.h>
     23#include <linux/interrupt.h>
     24#include <linux/hrtimer.h>
     25#include <linux/tick.h>
     26#include <linux/kfifo.h>
     27#include <linux/kgdb.h>
     28#include <linux/kdb.h>
     29
     30static int kgdb_nmi_knock = 1;
     31module_param_named(knock, kgdb_nmi_knock, int, 0600);
     32MODULE_PARM_DESC(knock, "if set to 1 (default), the special '$3#33' command " \
     33			"must be used to enter the debugger; when set to 0, " \
     34			"hitting return key is enough to enter the debugger; " \
     35			"when set to -1, the debugger is entered immediately " \
     36			"upon NMI");
     37
     38static char *kgdb_nmi_magic = "$3#33";
     39module_param_named(magic, kgdb_nmi_magic, charp, 0600);
     40MODULE_PARM_DESC(magic, "magic sequence to enter NMI debugger (default $3#33)");
     41
     42static atomic_t kgdb_nmi_num_readers = ATOMIC_INIT(0);
     43
     44static int kgdb_nmi_console_setup(struct console *co, char *options)
     45{
     46	arch_kgdb_ops.enable_nmi(1);
     47
     48	/* The NMI console uses the dbg_io_ops to issue console messages. To
     49	 * avoid duplicate messages during kdb sessions we must inform kdb's
     50	 * I/O utilities that messages sent to the console will automatically
     51	 * be displayed on the dbg_io.
     52	 */
     53	dbg_io_ops->cons = co;
     54
     55	return 0;
     56}
     57
     58static void kgdb_nmi_console_write(struct console *co, const char *s, uint c)
     59{
     60	int i;
     61
     62	for (i = 0; i < c; i++)
     63		dbg_io_ops->write_char(s[i]);
     64}
     65
     66static struct tty_driver *kgdb_nmi_tty_driver;
     67
     68static struct tty_driver *kgdb_nmi_console_device(struct console *co, int *idx)
     69{
     70	*idx = co->index;
     71	return kgdb_nmi_tty_driver;
     72}
     73
     74static struct console kgdb_nmi_console = {
     75	.name	= "ttyNMI",
     76	.setup  = kgdb_nmi_console_setup,
     77	.write	= kgdb_nmi_console_write,
     78	.device	= kgdb_nmi_console_device,
     79	.flags	= CON_PRINTBUFFER | CON_ANYTIME,
     80	.index	= -1,
     81};
     82
     83/*
     84 * This is usually the maximum rate on debug ports. We make fifo large enough
     85 * to make copy-pasting to the terminal usable.
     86 */
     87#define KGDB_NMI_BAUD		115200
     88#define KGDB_NMI_FIFO_SIZE	roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ)
     89
     90struct kgdb_nmi_tty_priv {
     91	struct tty_port port;
     92	struct timer_list timer;
     93	STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo;
     94};
     95
     96static struct tty_port *kgdb_nmi_port;
     97
     98static void kgdb_tty_recv(int ch)
     99{
    100	struct kgdb_nmi_tty_priv *priv;
    101	char c = ch;
    102
    103	if (!kgdb_nmi_port || ch < 0)
    104		return;
    105	/*
    106	 * Can't use port->tty->driver_data as tty might be not there. Timer
    107	 * will check for tty and will get the ref, but here we don't have to
    108	 * do that, and actually, we can't: we're in NMI context, no locks are
    109	 * possible.
    110	 */
    111	priv = container_of(kgdb_nmi_port, struct kgdb_nmi_tty_priv, port);
    112	kfifo_in(&priv->fifo, &c, 1);
    113}
    114
    115static int kgdb_nmi_poll_one_knock(void)
    116{
    117	static int n;
    118	int c;
    119	const char *magic = kgdb_nmi_magic;
    120	size_t m = strlen(magic);
    121	bool printch = false;
    122
    123	c = dbg_io_ops->read_char();
    124	if (c == NO_POLL_CHAR)
    125		return c;
    126
    127	if (!kgdb_nmi_knock && (c == '\r' || c == '\n')) {
    128		return 1;
    129	} else if (c == magic[n]) {
    130		n = (n + 1) % m;
    131		if (!n)
    132			return 1;
    133		printch = true;
    134	} else {
    135		n = 0;
    136	}
    137
    138	if (atomic_read(&kgdb_nmi_num_readers)) {
    139		kgdb_tty_recv(c);
    140		return 0;
    141	}
    142
    143	if (printch) {
    144		kdb_printf("%c", c);
    145		return 0;
    146	}
    147
    148	kdb_printf("\r%s %s to enter the debugger> %*s",
    149		   kgdb_nmi_knock ? "Type" : "Hit",
    150		   kgdb_nmi_knock ? magic  : "<return>", (int)m, "");
    151	while (m--)
    152		kdb_printf("\b");
    153	return 0;
    154}
    155
    156/**
    157 * kgdb_nmi_poll_knock - Check if it is time to enter the debugger
    158 *
    159 * "Serial ports are often noisy, especially when muxed over another port (we
    160 * often use serial over the headset connector). Noise on the async command
    161 * line just causes characters that are ignored, on a command line that blocked
    162 * execution noise would be catastrophic." -- Colin Cross
    163 *
    164 * So, this function implements KGDB/KDB knocking on the serial line: we won't
    165 * enter the debugger until we receive a known magic phrase (which is actually
    166 * "$3#33", known as "escape to KDB" command. There is also a relaxed variant
    167 * of knocking, i.e. just pressing the return key is enough to enter the
    168 * debugger. And if knocking is disabled, the function always returns 1.
    169 */
    170bool kgdb_nmi_poll_knock(void)
    171{
    172	if (kgdb_nmi_knock < 0)
    173		return true;
    174
    175	while (1) {
    176		int ret;
    177
    178		ret = kgdb_nmi_poll_one_knock();
    179		if (ret == NO_POLL_CHAR)
    180			return false;
    181		else if (ret == 1)
    182			break;
    183	}
    184	return true;
    185}
    186
    187/*
    188 * The tasklet is cheap, it does not cause wakeups when reschedules itself,
    189 * instead it waits for the next tick.
    190 */
    191static void kgdb_nmi_tty_receiver(struct timer_list *t)
    192{
    193	struct kgdb_nmi_tty_priv *priv = from_timer(priv, t, timer);
    194	char ch;
    195
    196	priv->timer.expires = jiffies + (HZ/100);
    197	add_timer(&priv->timer);
    198
    199	if (likely(!atomic_read(&kgdb_nmi_num_readers) ||
    200		   !kfifo_len(&priv->fifo)))
    201		return;
    202
    203	while (kfifo_out(&priv->fifo, &ch, 1))
    204		tty_insert_flip_char(&priv->port, ch, TTY_NORMAL);
    205	tty_flip_buffer_push(&priv->port);
    206}
    207
    208static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty)
    209{
    210	struct kgdb_nmi_tty_priv *priv =
    211	    container_of(port, struct kgdb_nmi_tty_priv, port);
    212
    213	kgdb_nmi_port = port;
    214	priv->timer.expires = jiffies + (HZ/100);
    215	add_timer(&priv->timer);
    216
    217	return 0;
    218}
    219
    220static void kgdb_nmi_tty_shutdown(struct tty_port *port)
    221{
    222	struct kgdb_nmi_tty_priv *priv =
    223	    container_of(port, struct kgdb_nmi_tty_priv, port);
    224
    225	del_timer(&priv->timer);
    226	kgdb_nmi_port = NULL;
    227}
    228
    229static const struct tty_port_operations kgdb_nmi_tty_port_ops = {
    230	.activate	= kgdb_nmi_tty_activate,
    231	.shutdown	= kgdb_nmi_tty_shutdown,
    232};
    233
    234static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty)
    235{
    236	struct kgdb_nmi_tty_priv *priv;
    237	int ret;
    238
    239	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
    240	if (!priv)
    241		return -ENOMEM;
    242
    243	INIT_KFIFO(priv->fifo);
    244	timer_setup(&priv->timer, kgdb_nmi_tty_receiver, 0);
    245	tty_port_init(&priv->port);
    246	priv->port.ops = &kgdb_nmi_tty_port_ops;
    247	tty->driver_data = priv;
    248
    249	ret = tty_port_install(&priv->port, drv, tty);
    250	if (ret) {
    251		pr_err("%s: can't install tty port: %d\n", __func__, ret);
    252		goto err;
    253	}
    254	return 0;
    255err:
    256	tty_port_destroy(&priv->port);
    257	kfree(priv);
    258	return ret;
    259}
    260
    261static void kgdb_nmi_tty_cleanup(struct tty_struct *tty)
    262{
    263	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
    264
    265	tty->driver_data = NULL;
    266	tty_port_destroy(&priv->port);
    267	kfree(priv);
    268}
    269
    270static int kgdb_nmi_tty_open(struct tty_struct *tty, struct file *file)
    271{
    272	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
    273	unsigned int mode = file->f_flags & O_ACCMODE;
    274	int ret;
    275
    276	ret = tty_port_open(&priv->port, tty, file);
    277	if (!ret && (mode == O_RDONLY || mode == O_RDWR))
    278		atomic_inc(&kgdb_nmi_num_readers);
    279
    280	return ret;
    281}
    282
    283static void kgdb_nmi_tty_close(struct tty_struct *tty, struct file *file)
    284{
    285	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
    286	unsigned int mode = file->f_flags & O_ACCMODE;
    287
    288	if (mode == O_RDONLY || mode == O_RDWR)
    289		atomic_dec(&kgdb_nmi_num_readers);
    290
    291	tty_port_close(&priv->port, tty, file);
    292}
    293
    294static void kgdb_nmi_tty_hangup(struct tty_struct *tty)
    295{
    296	struct kgdb_nmi_tty_priv *priv = tty->driver_data;
    297
    298	tty_port_hangup(&priv->port);
    299}
    300
    301static unsigned int kgdb_nmi_tty_write_room(struct tty_struct *tty)
    302{
    303	/* Actually, we can handle any amount as we use polled writes. */
    304	return 2048;
    305}
    306
    307static int kgdb_nmi_tty_write(struct tty_struct *tty, const unchar *buf, int c)
    308{
    309	int i;
    310
    311	for (i = 0; i < c; i++)
    312		dbg_io_ops->write_char(buf[i]);
    313	return c;
    314}
    315
    316static const struct tty_operations kgdb_nmi_tty_ops = {
    317	.open		= kgdb_nmi_tty_open,
    318	.close		= kgdb_nmi_tty_close,
    319	.install	= kgdb_nmi_tty_install,
    320	.cleanup	= kgdb_nmi_tty_cleanup,
    321	.hangup		= kgdb_nmi_tty_hangup,
    322	.write_room	= kgdb_nmi_tty_write_room,
    323	.write		= kgdb_nmi_tty_write,
    324};
    325
    326int kgdb_register_nmi_console(void)
    327{
    328	int ret;
    329
    330	if (!arch_kgdb_ops.enable_nmi)
    331		return 0;
    332
    333	kgdb_nmi_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
    334	if (IS_ERR(kgdb_nmi_tty_driver)) {
    335		pr_err("%s: cannot allocate tty\n", __func__);
    336		return PTR_ERR(kgdb_nmi_tty_driver);
    337	}
    338	kgdb_nmi_tty_driver->driver_name	= "ttyNMI";
    339	kgdb_nmi_tty_driver->name		= "ttyNMI";
    340	kgdb_nmi_tty_driver->num		= 1;
    341	kgdb_nmi_tty_driver->type		= TTY_DRIVER_TYPE_SERIAL;
    342	kgdb_nmi_tty_driver->subtype		= SERIAL_TYPE_NORMAL;
    343	kgdb_nmi_tty_driver->init_termios	= tty_std_termios;
    344	tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios,
    345				     KGDB_NMI_BAUD, KGDB_NMI_BAUD);
    346	tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops);
    347
    348	ret = tty_register_driver(kgdb_nmi_tty_driver);
    349	if (ret) {
    350		pr_err("%s: can't register tty driver: %d\n", __func__, ret);
    351		goto err_drv_reg;
    352	}
    353
    354	register_console(&kgdb_nmi_console);
    355
    356	return 0;
    357err_drv_reg:
    358	tty_driver_kref_put(kgdb_nmi_tty_driver);
    359	return ret;
    360}
    361EXPORT_SYMBOL_GPL(kgdb_register_nmi_console);
    362
    363int kgdb_unregister_nmi_console(void)
    364{
    365	int ret;
    366
    367	if (!arch_kgdb_ops.enable_nmi)
    368		return 0;
    369	arch_kgdb_ops.enable_nmi(0);
    370
    371	ret = unregister_console(&kgdb_nmi_console);
    372	if (ret)
    373		return ret;
    374
    375	tty_unregister_driver(kgdb_nmi_tty_driver);
    376	tty_driver_kref_put(kgdb_nmi_tty_driver);
    377
    378	return 0;
    379}
    380EXPORT_SYMBOL_GPL(kgdb_unregister_nmi_console);