Commit ff55df53dfdd338906c8ba9d1f4a759b86b869d5
1 parent
8b956bf1f0
Exists in
master
and in
7 other branches
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(®s, 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, ®s, 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(®s, 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, ®s, 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) |