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

msr.c (7321B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* ----------------------------------------------------------------------- *
      3 *
      4 *   Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
      5 *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
      6 *
      7 * ----------------------------------------------------------------------- */
      8
      9/*
     10 * x86 MSR access device
     11 *
     12 * This device is accessed by lseek() to the appropriate register number
     13 * and then read/write in chunks of 8 bytes.  A larger size means multiple
     14 * reads or writes of the same register.
     15 *
     16 * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
     17 * an SMP box will direct the access to CPU %d.
     18 */
     19
     20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     21
     22#include <linux/module.h>
     23
     24#include <linux/types.h>
     25#include <linux/errno.h>
     26#include <linux/fcntl.h>
     27#include <linux/init.h>
     28#include <linux/poll.h>
     29#include <linux/smp.h>
     30#include <linux/major.h>
     31#include <linux/fs.h>
     32#include <linux/device.h>
     33#include <linux/cpu.h>
     34#include <linux/notifier.h>
     35#include <linux/uaccess.h>
     36#include <linux/gfp.h>
     37#include <linux/security.h>
     38
     39#include <asm/cpufeature.h>
     40#include <asm/msr.h>
     41
     42static struct class *msr_class;
     43static enum cpuhp_state cpuhp_msr_state;
     44
     45enum allow_write_msrs {
     46	MSR_WRITES_ON,
     47	MSR_WRITES_OFF,
     48	MSR_WRITES_DEFAULT,
     49};
     50
     51static enum allow_write_msrs allow_writes = MSR_WRITES_DEFAULT;
     52
     53static ssize_t msr_read(struct file *file, char __user *buf,
     54			size_t count, loff_t *ppos)
     55{
     56	u32 __user *tmp = (u32 __user *) buf;
     57	u32 data[2];
     58	u32 reg = *ppos;
     59	int cpu = iminor(file_inode(file));
     60	int err = 0;
     61	ssize_t bytes = 0;
     62
     63	if (count % 8)
     64		return -EINVAL;	/* Invalid chunk size */
     65
     66	for (; count; count -= 8) {
     67		err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
     68		if (err)
     69			break;
     70		if (copy_to_user(tmp, &data, 8)) {
     71			err = -EFAULT;
     72			break;
     73		}
     74		tmp += 2;
     75		bytes += 8;
     76	}
     77
     78	return bytes ? bytes : err;
     79}
     80
     81static int filter_write(u32 reg)
     82{
     83	/*
     84	 * MSRs writes usually happen all at once, and can easily saturate kmsg.
     85	 * Only allow one message every 30 seconds.
     86	 *
     87	 * It's possible to be smarter here and do it (for example) per-MSR, but
     88	 * it would certainly be more complex, and this is enough at least to
     89	 * avoid saturating the ring buffer.
     90	 */
     91	static DEFINE_RATELIMIT_STATE(fw_rs, 30 * HZ, 1);
     92
     93	switch (allow_writes) {
     94	case MSR_WRITES_ON:  return 0;
     95	case MSR_WRITES_OFF: return -EPERM;
     96	default: break;
     97	}
     98
     99	if (!__ratelimit(&fw_rs))
    100		return 0;
    101
    102	pr_warn("Write to unrecognized MSR 0x%x by %s (pid: %d).\n",
    103	        reg, current->comm, current->pid);
    104	pr_warn("See https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/about for details.\n");
    105
    106	return 0;
    107}
    108
    109static ssize_t msr_write(struct file *file, const char __user *buf,
    110			 size_t count, loff_t *ppos)
    111{
    112	const u32 __user *tmp = (const u32 __user *)buf;
    113	u32 data[2];
    114	u32 reg = *ppos;
    115	int cpu = iminor(file_inode(file));
    116	int err = 0;
    117	ssize_t bytes = 0;
    118
    119	err = security_locked_down(LOCKDOWN_MSR);
    120	if (err)
    121		return err;
    122
    123	err = filter_write(reg);
    124	if (err)
    125		return err;
    126
    127	if (count % 8)
    128		return -EINVAL;	/* Invalid chunk size */
    129
    130	for (; count; count -= 8) {
    131		if (copy_from_user(&data, tmp, 8)) {
    132			err = -EFAULT;
    133			break;
    134		}
    135
    136		add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
    137
    138		err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
    139		if (err)
    140			break;
    141
    142		tmp += 2;
    143		bytes += 8;
    144	}
    145
    146	return bytes ? bytes : err;
    147}
    148
    149static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
    150{
    151	u32 __user *uregs = (u32 __user *)arg;
    152	u32 regs[8];
    153	int cpu = iminor(file_inode(file));
    154	int err;
    155
    156	switch (ioc) {
    157	case X86_IOC_RDMSR_REGS:
    158		if (!(file->f_mode & FMODE_READ)) {
    159			err = -EBADF;
    160			break;
    161		}
    162		if (copy_from_user(&regs, uregs, sizeof(regs))) {
    163			err = -EFAULT;
    164			break;
    165		}
    166		err = rdmsr_safe_regs_on_cpu(cpu, regs);
    167		if (err)
    168			break;
    169		if (copy_to_user(uregs, &regs, sizeof(regs)))
    170			err = -EFAULT;
    171		break;
    172
    173	case X86_IOC_WRMSR_REGS:
    174		if (!(file->f_mode & FMODE_WRITE)) {
    175			err = -EBADF;
    176			break;
    177		}
    178		if (copy_from_user(&regs, uregs, sizeof(regs))) {
    179			err = -EFAULT;
    180			break;
    181		}
    182		err = security_locked_down(LOCKDOWN_MSR);
    183		if (err)
    184			break;
    185
    186		err = filter_write(regs[1]);
    187		if (err)
    188			return err;
    189
    190		add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
    191
    192		err = wrmsr_safe_regs_on_cpu(cpu, regs);
    193		if (err)
    194			break;
    195		if (copy_to_user(uregs, &regs, sizeof(regs)))
    196			err = -EFAULT;
    197		break;
    198
    199	default:
    200		err = -ENOTTY;
    201		break;
    202	}
    203
    204	return err;
    205}
    206
    207static int msr_open(struct inode *inode, struct file *file)
    208{
    209	unsigned int cpu = iminor(file_inode(file));
    210	struct cpuinfo_x86 *c;
    211
    212	if (!capable(CAP_SYS_RAWIO))
    213		return -EPERM;
    214
    215	if (cpu >= nr_cpu_ids || !cpu_online(cpu))
    216		return -ENXIO;	/* No such CPU */
    217
    218	c = &cpu_data(cpu);
    219	if (!cpu_has(c, X86_FEATURE_MSR))
    220		return -EIO;	/* MSR not supported */
    221
    222	return 0;
    223}
    224
    225/*
    226 * File operations we support
    227 */
    228static const struct file_operations msr_fops = {
    229	.owner = THIS_MODULE,
    230	.llseek = no_seek_end_llseek,
    231	.read = msr_read,
    232	.write = msr_write,
    233	.open = msr_open,
    234	.unlocked_ioctl = msr_ioctl,
    235	.compat_ioctl = msr_ioctl,
    236};
    237
    238static int msr_device_create(unsigned int cpu)
    239{
    240	struct device *dev;
    241
    242	dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
    243			    "msr%d", cpu);
    244	return PTR_ERR_OR_ZERO(dev);
    245}
    246
    247static int msr_device_destroy(unsigned int cpu)
    248{
    249	device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
    250	return 0;
    251}
    252
    253static char *msr_devnode(struct device *dev, umode_t *mode)
    254{
    255	return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
    256}
    257
    258static int __init msr_init(void)
    259{
    260	int err;
    261
    262	if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
    263		pr_err("unable to get major %d for msr\n", MSR_MAJOR);
    264		return -EBUSY;
    265	}
    266	msr_class = class_create(THIS_MODULE, "msr");
    267	if (IS_ERR(msr_class)) {
    268		err = PTR_ERR(msr_class);
    269		goto out_chrdev;
    270	}
    271	msr_class->devnode = msr_devnode;
    272
    273	err  = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/msr:online",
    274				 msr_device_create, msr_device_destroy);
    275	if (err < 0)
    276		goto out_class;
    277	cpuhp_msr_state = err;
    278	return 0;
    279
    280out_class:
    281	class_destroy(msr_class);
    282out_chrdev:
    283	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
    284	return err;
    285}
    286module_init(msr_init);
    287
    288static void __exit msr_exit(void)
    289{
    290	cpuhp_remove_state(cpuhp_msr_state);
    291	class_destroy(msr_class);
    292	__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
    293}
    294module_exit(msr_exit)
    295
    296static int set_allow_writes(const char *val, const struct kernel_param *cp)
    297{
    298	/* val is NUL-terminated, see kernfs_fop_write() */
    299	char *s = strstrip((char *)val);
    300
    301	if (!strcmp(s, "on"))
    302		allow_writes = MSR_WRITES_ON;
    303	else if (!strcmp(s, "off"))
    304		allow_writes = MSR_WRITES_OFF;
    305	else
    306		allow_writes = MSR_WRITES_DEFAULT;
    307
    308	return 0;
    309}
    310
    311static int get_allow_writes(char *buf, const struct kernel_param *kp)
    312{
    313	const char *res;
    314
    315	switch (allow_writes) {
    316	case MSR_WRITES_ON:  res = "on"; break;
    317	case MSR_WRITES_OFF: res = "off"; break;
    318	default: res = "default"; break;
    319	}
    320
    321	return sprintf(buf, "%s\n", res);
    322}
    323
    324static const struct kernel_param_ops allow_writes_ops = {
    325	.set = set_allow_writes,
    326	.get = get_allow_writes
    327};
    328
    329module_param_cb(allow_writes, &allow_writes_ops, NULL, 0600);
    330
    331MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
    332MODULE_DESCRIPTION("x86 generic MSR driver");
    333MODULE_LICENSE("GPL");