Commit ff55df53dfdd338906c8ba9d1f4a759b86b869d5

Authored by H. Peter Anvin
1 parent 8b956bf1f0

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>

Showing 3 changed files with 60 additions and 2 deletions Side-by-side Diff

Documentation/ioctl/ioctl-number.txt
... ... @@ -121,6 +121,7 @@
121 121 'c' 00-7F linux/comstats.h conflict!
122 122 'c' 00-7F linux/coda.h conflict!
123 123 'c' 80-9F arch/s390/include/asm/chsc.h
  124 +'c' A0-AF arch/x86/include/asm/msr.h
124 125 'd' 00-FF linux/char/drm/drm/h conflict!
125 126 'd' F0-FF linux/digi1.h
126 127 'e' all linux/digi1.h conflict!
arch/x86/include/asm/msr.h
... ... @@ -3,10 +3,16 @@
3 3  
4 4 #include <asm/msr-index.h>
5 5  
6   -#ifdef __KERNEL__
7 6 #ifndef __ASSEMBLY__
8 7  
9 8 #include <linux/types.h>
  9 +#include <linux/ioctl.h>
  10 +
  11 +#define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8])
  12 +#define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8])
  13 +
  14 +#ifdef __KERNEL__
  15 +
10 16 #include <asm/asm.h>
11 17 #include <asm/errno.h>
12 18 #include <asm/cpumask.h>
13 19  
... ... @@ -286,7 +292,7 @@
286 292 return wrmsr_safe_regs(regs);
287 293 }
288 294 #endif /* CONFIG_SMP */
289   -#endif /* __ASSEMBLY__ */
290 295 #endif /* __KERNEL__ */
  296 +#endif /* __ASSEMBLY__ */
291 297 #endif /* _ASM_X86_MSR_H */
arch/x86/kernel/msr.c
1 1 /* ----------------------------------------------------------------------- *
2 2 *
3 3 * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
  4 + * Copyright 2009 Intel Corporation; author: H. Peter Anvin
4 5 *
5 6 * This program is free software; you can redistribute it and/or modify
6 7 * it under the terms of the GNU General Public License as published by
... ... @@ -121,6 +122,54 @@
121 122 return bytes ? bytes : err;
122 123 }
123 124  
  125 +static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
  126 +{
  127 + u32 __user *uregs = (u32 __user *)arg;
  128 + u32 regs[8];
  129 + int cpu = iminor(file->f_path.dentry->d_inode);
  130 + int err;
  131 +
  132 + switch (ioc) {
  133 + case X86_IOC_RDMSR_REGS:
  134 + if (!(file->f_mode & FMODE_READ)) {
  135 + err = -EBADF;
  136 + break;
  137 + }
  138 + if (copy_from_user(&regs, uregs, sizeof regs)) {
  139 + err = -EFAULT;
  140 + break;
  141 + }
  142 + err = rdmsr_safe_regs_on_cpu(cpu, regs);
  143 + if (err)
  144 + break;
  145 + if (copy_to_user(uregs, &regs, sizeof regs))
  146 + err = -EFAULT;
  147 + break;
  148 +
  149 + case X86_IOC_WRMSR_REGS:
  150 + if (!(file->f_mode & FMODE_WRITE)) {
  151 + err = -EBADF;
  152 + break;
  153 + }
  154 + if (copy_from_user(&regs, uregs, sizeof regs)) {
  155 + err = -EFAULT;
  156 + break;
  157 + }
  158 + err = wrmsr_safe_regs_on_cpu(cpu, regs);
  159 + if (err)
  160 + break;
  161 + if (copy_to_user(uregs, &regs, sizeof regs))
  162 + err = -EFAULT;
  163 + break;
  164 +
  165 + default:
  166 + err = -ENOTTY;
  167 + break;
  168 + }
  169 +
  170 + return err;
  171 +}
  172 +
124 173 static int msr_open(struct inode *inode, struct file *file)
125 174 {
126 175 unsigned int cpu = iminor(file->f_path.dentry->d_inode);
... ... @@ -151,6 +200,8 @@
151 200 .read = msr_read,
152 201 .write = msr_write,
153 202 .open = msr_open,
  203 + .unlocked_ioctl = msr_ioctl,
  204 + .compat_ioctl = msr_ioctl,
154 205 };
155 206  
156 207 static int __cpuinit msr_device_create(int cpu)