msr.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
  4. * Copyright 2009 Intel Corporation; author: H. Peter Anvin
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
  9. * USA; either version 2 of the License, or (at your option) any later
  10. * version; incorporated herein by reference.
  11. *
  12. * ----------------------------------------------------------------------- */
  13. /*
  14. * x86 MSR access device
  15. *
  16. * This device is accessed by lseek() to the appropriate register number
  17. * and then read/write in chunks of 8 bytes. A larger size means multiple
  18. * reads or writes of the same register.
  19. *
  20. * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
  21. * an SMP box will direct the access to CPU %d.
  22. */
  23. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  24. #include <linux/module.h>
  25. #include <linux/types.h>
  26. #include <linux/errno.h>
  27. #include <linux/fcntl.h>
  28. #include <linux/init.h>
  29. #include <linux/poll.h>
  30. #include <linux/smp.h>
  31. #include <linux/major.h>
  32. #include <linux/fs.h>
  33. #include <linux/device.h>
  34. #include <linux/cpu.h>
  35. #include <linux/notifier.h>
  36. #include <linux/uaccess.h>
  37. #include <linux/gfp.h>
  38. #include <asm/cpufeature.h>
  39. #include <asm/msr.h>
  40. static struct class *msr_class;
  41. static ssize_t msr_read(struct file *file, char __user *buf,
  42. size_t count, loff_t *ppos)
  43. {
  44. u32 __user *tmp = (u32 __user *) buf;
  45. u32 data[2];
  46. u32 reg = *ppos;
  47. int cpu = iminor(file_inode(file));
  48. int err = 0;
  49. ssize_t bytes = 0;
  50. if (count % 8)
  51. return -EINVAL; /* Invalid chunk size */
  52. for (; count; count -= 8) {
  53. err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
  54. if (err)
  55. break;
  56. if (copy_to_user(tmp, &data, 8)) {
  57. err = -EFAULT;
  58. break;
  59. }
  60. tmp += 2;
  61. bytes += 8;
  62. }
  63. return bytes ? bytes : err;
  64. }
  65. static ssize_t msr_write(struct file *file, const char __user *buf,
  66. size_t count, loff_t *ppos)
  67. {
  68. const u32 __user *tmp = (const u32 __user *)buf;
  69. u32 data[2];
  70. u32 reg = *ppos;
  71. int cpu = iminor(file_inode(file));
  72. int err = 0;
  73. ssize_t bytes = 0;
  74. if (count % 8)
  75. return -EINVAL; /* Invalid chunk size */
  76. for (; count; count -= 8) {
  77. if (copy_from_user(&data, tmp, 8)) {
  78. err = -EFAULT;
  79. break;
  80. }
  81. err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
  82. if (err)
  83. break;
  84. tmp += 2;
  85. bytes += 8;
  86. }
  87. return bytes ? bytes : err;
  88. }
  89. static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
  90. {
  91. u32 __user *uregs = (u32 __user *)arg;
  92. u32 regs[8];
  93. int cpu = iminor(file_inode(file));
  94. int err;
  95. switch (ioc) {
  96. case X86_IOC_RDMSR_REGS:
  97. if (!(file->f_mode & FMODE_READ)) {
  98. err = -EBADF;
  99. break;
  100. }
  101. if (copy_from_user(&regs, uregs, sizeof regs)) {
  102. err = -EFAULT;
  103. break;
  104. }
  105. err = rdmsr_safe_regs_on_cpu(cpu, regs);
  106. if (err)
  107. break;
  108. if (copy_to_user(uregs, &regs, sizeof regs))
  109. err = -EFAULT;
  110. break;
  111. case X86_IOC_WRMSR_REGS:
  112. if (!(file->f_mode & FMODE_WRITE)) {
  113. err = -EBADF;
  114. break;
  115. }
  116. if (copy_from_user(&regs, uregs, sizeof regs)) {
  117. err = -EFAULT;
  118. break;
  119. }
  120. err = wrmsr_safe_regs_on_cpu(cpu, regs);
  121. if (err)
  122. break;
  123. if (copy_to_user(uregs, &regs, sizeof regs))
  124. err = -EFAULT;
  125. break;
  126. default:
  127. err = -ENOTTY;
  128. break;
  129. }
  130. return err;
  131. }
  132. static int msr_open(struct inode *inode, struct file *file)
  133. {
  134. unsigned int cpu = iminor(file_inode(file));
  135. struct cpuinfo_x86 *c;
  136. if (!capable(CAP_SYS_RAWIO))
  137. return -EPERM;
  138. if (cpu >= nr_cpu_ids || !cpu_online(cpu))
  139. return -ENXIO; /* No such CPU */
  140. c = &cpu_data(cpu);
  141. if (!cpu_has(c, X86_FEATURE_MSR))
  142. return -EIO; /* MSR not supported */
  143. return 0;
  144. }
  145. /*
  146. * File operations we support
  147. */
  148. static const struct file_operations msr_fops = {
  149. .owner = THIS_MODULE,
  150. .llseek = no_seek_end_llseek,
  151. .read = msr_read,
  152. .write = msr_write,
  153. .open = msr_open,
  154. .unlocked_ioctl = msr_ioctl,
  155. .compat_ioctl = msr_ioctl,
  156. };
  157. static int msr_device_create(int cpu)
  158. {
  159. struct device *dev;
  160. dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
  161. "msr%d", cpu);
  162. return PTR_ERR_OR_ZERO(dev);
  163. }
  164. static void msr_device_destroy(int cpu)
  165. {
  166. device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
  167. }
  168. static int msr_class_cpu_callback(struct notifier_block *nfb,
  169. unsigned long action, void *hcpu)
  170. {
  171. unsigned int cpu = (unsigned long)hcpu;
  172. int err = 0;
  173. switch (action) {
  174. case CPU_UP_PREPARE:
  175. err = msr_device_create(cpu);
  176. break;
  177. case CPU_UP_CANCELED:
  178. case CPU_UP_CANCELED_FROZEN:
  179. case CPU_DEAD:
  180. msr_device_destroy(cpu);
  181. break;
  182. }
  183. return notifier_from_errno(err);
  184. }
  185. static struct notifier_block __refdata msr_class_cpu_notifier = {
  186. .notifier_call = msr_class_cpu_callback,
  187. };
  188. static char *msr_devnode(struct device *dev, umode_t *mode)
  189. {
  190. return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
  191. }
  192. static int __init msr_init(void)
  193. {
  194. int i, err = 0;
  195. i = 0;
  196. if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
  197. pr_err("unable to get major %d for msr\n", MSR_MAJOR);
  198. err = -EBUSY;
  199. goto out;
  200. }
  201. msr_class = class_create(THIS_MODULE, "msr");
  202. if (IS_ERR(msr_class)) {
  203. err = PTR_ERR(msr_class);
  204. goto out_chrdev;
  205. }
  206. msr_class->devnode = msr_devnode;
  207. cpu_notifier_register_begin();
  208. for_each_online_cpu(i) {
  209. err = msr_device_create(i);
  210. if (err != 0)
  211. goto out_class;
  212. }
  213. __register_hotcpu_notifier(&msr_class_cpu_notifier);
  214. cpu_notifier_register_done();
  215. err = 0;
  216. goto out;
  217. out_class:
  218. i = 0;
  219. for_each_online_cpu(i)
  220. msr_device_destroy(i);
  221. cpu_notifier_register_done();
  222. class_destroy(msr_class);
  223. out_chrdev:
  224. __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
  225. out:
  226. return err;
  227. }
  228. static void __exit msr_exit(void)
  229. {
  230. int cpu = 0;
  231. cpu_notifier_register_begin();
  232. for_each_online_cpu(cpu)
  233. msr_device_destroy(cpu);
  234. class_destroy(msr_class);
  235. __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
  236. __unregister_hotcpu_notifier(&msr_class_cpu_notifier);
  237. cpu_notifier_register_done();
  238. }
  239. module_init(msr_init);
  240. module_exit(msr_exit)
  241. MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
  242. MODULE_DESCRIPTION("x86 generic MSR driver");
  243. MODULE_LICENSE("GPL");