x86, msr: Export the register-setting MSR functions via /dev/*/msr
Make it possible to access the all-register-setting/getting MSR functions via the MSR driver. This is implemented as an ioctl() on the standard MSR device node. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Cc: Borislav Petkov <petkovbb@gmail.com>
This commit is contained in:
parent
8b956bf1f0
commit
ff55df53df
|
@ -121,6 +121,7 @@ Code Seq# Include File Comments
|
||||||
'c' 00-7F linux/comstats.h conflict!
|
'c' 00-7F linux/comstats.h conflict!
|
||||||
'c' 00-7F linux/coda.h conflict!
|
'c' 00-7F linux/coda.h conflict!
|
||||||
'c' 80-9F arch/s390/include/asm/chsc.h
|
'c' 80-9F arch/s390/include/asm/chsc.h
|
||||||
|
'c' A0-AF arch/x86/include/asm/msr.h
|
||||||
'd' 00-FF linux/char/drm/drm/h conflict!
|
'd' 00-FF linux/char/drm/drm/h conflict!
|
||||||
'd' F0-FF linux/digi1.h
|
'd' F0-FF linux/digi1.h
|
||||||
'e' all linux/digi1.h conflict!
|
'e' all linux/digi1.h conflict!
|
||||||
|
|
|
@ -3,10 +3,16 @@
|
||||||
|
|
||||||
#include <asm/msr-index.h>
|
#include <asm/msr-index.h>
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/ioctl.h>
|
||||||
|
|
||||||
|
#define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8])
|
||||||
|
#define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8])
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
#include <asm/cpumask.h>
|
#include <asm/cpumask.h>
|
||||||
|
@ -286,6 +292,6 @@ static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
|
||||||
return wrmsr_safe_regs(regs);
|
return wrmsr_safe_regs(regs);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* _ASM_X86_MSR_H */
|
#endif /* _ASM_X86_MSR_H */
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* ----------------------------------------------------------------------- *
|
/* ----------------------------------------------------------------------- *
|
||||||
*
|
*
|
||||||
* Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
|
* 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
|
* 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
|
* 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;
|
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)
|
static int msr_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
|
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
|
||||||
|
@ -151,6 +200,8 @@ static const struct file_operations msr_fops = {
|
||||||
.read = msr_read,
|
.read = msr_read,
|
||||||
.write = msr_write,
|
.write = msr_write,
|
||||||
.open = msr_open,
|
.open = msr_open,
|
||||||
|
.unlocked_ioctl = msr_ioctl,
|
||||||
|
.compat_ioctl = msr_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __cpuinit msr_device_create(int cpu)
|
static int __cpuinit msr_device_create(int cpu)
|
||||||
|
|
Loading…
Reference in a new issue