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