msr-on-cpu.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <linux/module.h>
  2. #include <linux/preempt.h>
  3. #include <linux/smp.h>
  4. #include <asm/msr.h>
  5. struct msr_info {
  6. u32 msr_no;
  7. u32 l, h;
  8. int err;
  9. };
  10. static void __rdmsr_on_cpu(void *info)
  11. {
  12. struct msr_info *rv = info;
  13. rdmsr(rv->msr_no, rv->l, rv->h);
  14. }
  15. static void __wrmsr_on_cpu(void *info)
  16. {
  17. struct msr_info *rv = info;
  18. wrmsr(rv->msr_no, rv->l, rv->h);
  19. }
  20. int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
  21. {
  22. int err;
  23. struct msr_info rv;
  24. rv.msr_no = msr_no;
  25. err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
  26. *l = rv.l;
  27. *h = rv.h;
  28. return err;
  29. }
  30. int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
  31. {
  32. int err;
  33. struct msr_info rv;
  34. rv.msr_no = msr_no;
  35. rv.l = l;
  36. rv.h = h;
  37. err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
  38. return err;
  39. }
  40. /* These "safe" variants are slower and should be used when the target MSR
  41. may not actually exist. */
  42. static void __rdmsr_safe_on_cpu(void *info)
  43. {
  44. struct msr_info *rv = info;
  45. rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
  46. }
  47. static void __wrmsr_safe_on_cpu(void *info)
  48. {
  49. struct msr_info *rv = info;
  50. rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
  51. }
  52. int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
  53. {
  54. int err;
  55. struct msr_info rv;
  56. rv.msr_no = msr_no;
  57. err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
  58. *l = rv.l;
  59. *h = rv.h;
  60. return err ? err : rv.err;
  61. }
  62. int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
  63. {
  64. int err;
  65. struct msr_info rv;
  66. rv.msr_no = msr_no;
  67. rv.l = l;
  68. rv.h = h;
  69. err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
  70. return err ? err : rv.err;
  71. }
  72. EXPORT_SYMBOL(rdmsr_on_cpu);
  73. EXPORT_SYMBOL(wrmsr_on_cpu);
  74. EXPORT_SYMBOL(rdmsr_safe_on_cpu);
  75. EXPORT_SYMBOL(wrmsr_safe_on_cpu);