|
@@ -1,6 +1,7 @@
|
|
|
/* ----------------------------------------------------------------------- *
|
|
|
*
|
|
|
* Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
|
|
|
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
|
|
|
*
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -121,6 +122,54 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
|
|
|
return bytes ? bytes : err;
|
|
|
}
|
|
|
|
|
|
+static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
|
|
|
+{
|
|
|
+ u32 __user *uregs = (u32 __user *)arg;
|
|
|
+ u32 regs[8];
|
|
|
+ int cpu = iminor(file->f_path.dentry->d_inode);
|
|
|
+ int err;
|
|
|
+
|
|
|
+ switch (ioc) {
|
|
|
+ case X86_IOC_RDMSR_REGS:
|
|
|
+ if (!(file->f_mode & FMODE_READ)) {
|
|
|
+ err = -EBADF;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (copy_from_user(®s, uregs, sizeof regs)) {
|
|
|
+ err = -EFAULT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ err = rdmsr_safe_regs_on_cpu(cpu, regs);
|
|
|
+ if (err)
|
|
|
+ break;
|
|
|
+ if (copy_to_user(uregs, ®s, sizeof regs))
|
|
|
+ err = -EFAULT;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case X86_IOC_WRMSR_REGS:
|
|
|
+ if (!(file->f_mode & FMODE_WRITE)) {
|
|
|
+ err = -EBADF;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (copy_from_user(®s, uregs, sizeof regs)) {
|
|
|
+ err = -EFAULT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ err = wrmsr_safe_regs_on_cpu(cpu, regs);
|
|
|
+ if (err)
|
|
|
+ break;
|
|
|
+ if (copy_to_user(uregs, ®s, sizeof regs))
|
|
|
+ err = -EFAULT;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ err = -ENOTTY;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static int msr_open(struct inode *inode, struct file *file)
|
|
|
{
|
|
|
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
|
|
@@ -151,6 +200,8 @@ static const struct file_operations msr_fops = {
|
|
|
.read = msr_read,
|
|
|
.write = msr_write,
|
|
|
.open = msr_open,
|
|
|
+ .unlocked_ioctl = msr_ioctl,
|
|
|
+ .compat_ioctl = msr_ioctl,
|
|
|
};
|
|
|
|
|
|
static int __cpuinit msr_device_create(int cpu)
|