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

nfcon.c (3484B)


      1/*
      2 * ARAnyM console driver
      3 *
      4 * This file is subject to the terms and conditions of the GNU General Public
      5 * License.  See the file COPYING in the main directory of this archive
      6 * for more details.
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/init.h>
     11#include <linux/console.h>
     12#include <linux/tty.h>
     13#include <linux/tty_driver.h>
     14#include <linux/tty_flip.h>
     15#include <linux/slab.h>
     16#include <linux/err.h>
     17#include <linux/uaccess.h>
     18#include <linux/io.h>
     19
     20#include <asm/natfeat.h>
     21
     22static int stderr_id;
     23static struct tty_port nfcon_tty_port;
     24static struct tty_driver *nfcon_tty_driver;
     25
     26static void nfputs(const char *str, unsigned int count)
     27{
     28	char buf[68];
     29	unsigned long phys = virt_to_phys(buf);
     30
     31	buf[64] = 0;
     32	while (count > 64) {
     33		memcpy(buf, str, 64);
     34		nf_call(stderr_id, phys);
     35		str += 64;
     36		count -= 64;
     37	}
     38	memcpy(buf, str, count);
     39	buf[count] = 0;
     40	nf_call(stderr_id, phys);
     41}
     42
     43static void nfcon_write(struct console *con, const char *str,
     44			unsigned int count)
     45{
     46	nfputs(str, count);
     47}
     48
     49static struct tty_driver *nfcon_device(struct console *con, int *index)
     50{
     51	*index = 0;
     52	return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
     53}
     54
     55static struct console nf_console = {
     56	.name	= "nfcon",
     57	.write	= nfcon_write,
     58	.device	= nfcon_device,
     59	.flags	= CON_PRINTBUFFER,
     60	.index	= -1,
     61};
     62
     63
     64static int nfcon_tty_open(struct tty_struct *tty, struct file *filp)
     65{
     66	return 0;
     67}
     68
     69static void nfcon_tty_close(struct tty_struct *tty, struct file *filp)
     70{
     71}
     72
     73static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf,
     74			   int count)
     75{
     76	nfputs(buf, count);
     77	return count;
     78}
     79
     80static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch)
     81{
     82	char temp[2] = { ch, 0 };
     83
     84	nf_call(stderr_id, virt_to_phys(temp));
     85	return 1;
     86}
     87
     88static unsigned int nfcon_tty_write_room(struct tty_struct *tty)
     89{
     90	return 64;
     91}
     92
     93static const struct tty_operations nfcon_tty_ops = {
     94	.open		= nfcon_tty_open,
     95	.close		= nfcon_tty_close,
     96	.write		= nfcon_tty_write,
     97	.put_char	= nfcon_tty_put_char,
     98	.write_room	= nfcon_tty_write_room,
     99};
    100
    101#ifndef MODULE
    102
    103static int __init nf_debug_setup(char *arg)
    104{
    105	if (strcmp(arg, "nfcon"))
    106		return 0;
    107
    108	stderr_id = nf_get_id("NF_STDERR");
    109	if (stderr_id) {
    110		nf_console.flags |= CON_ENABLED;
    111		register_console(&nf_console);
    112	}
    113
    114	return 0;
    115}
    116
    117early_param("debug", nf_debug_setup);
    118
    119#endif /* !MODULE */
    120
    121static int __init nfcon_init(void)
    122{
    123	struct tty_driver *driver;
    124	int res;
    125
    126	stderr_id = nf_get_id("NF_STDERR");
    127	if (!stderr_id)
    128		return -ENODEV;
    129
    130	driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
    131	if (IS_ERR(driver))
    132		return PTR_ERR(driver);
    133
    134	tty_port_init(&nfcon_tty_port);
    135
    136	driver->driver_name = "nfcon";
    137	driver->name = "nfcon";
    138	driver->type = TTY_DRIVER_TYPE_SYSTEM;
    139	driver->subtype = SYSTEM_TYPE_TTY;
    140	driver->init_termios = tty_std_termios;
    141
    142	tty_set_operations(driver, &nfcon_tty_ops);
    143	tty_port_link_device(&nfcon_tty_port, driver, 0);
    144	res = tty_register_driver(driver);
    145	if (res) {
    146		pr_err("failed to register nfcon tty driver\n");
    147		tty_driver_kref_put(driver);
    148		tty_port_destroy(&nfcon_tty_port);
    149		return res;
    150	}
    151
    152	nfcon_tty_driver = driver;
    153
    154	if (!(nf_console.flags & CON_ENABLED))
    155		register_console(&nf_console);
    156
    157	return 0;
    158}
    159
    160static void __exit nfcon_exit(void)
    161{
    162	unregister_console(&nf_console);
    163	tty_unregister_driver(nfcon_tty_driver);
    164	tty_driver_kref_put(nfcon_tty_driver);
    165	tty_port_destroy(&nfcon_tty_port);
    166}
    167
    168module_init(nfcon_init);
    169module_exit(nfcon_exit);
    170
    171MODULE_LICENSE("GPL");