msr-on-cpu.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 __rdmsr_safe_on_cpu(void *info)
  16. {
  17. struct msr_info *rv = info;
  18. rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
  19. }
  20. static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe)
  21. {
  22. int err = 0;
  23. struct msr_info rv;
  24. rv.msr_no = msr_no;
  25. if (safe) {
  26. err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu,
  27. &rv, 1);
  28. err = err ? err : rv.err;
  29. } else {
  30. err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
  31. }
  32. *l = rv.l;
  33. *h = rv.h;
  34. return err;
  35. }
  36. static void __wrmsr_on_cpu(void *info)
  37. {
  38. struct msr_info *rv = info;
  39. wrmsr(rv->msr_no, rv->l, rv->h);
  40. }
  41. static void __wrmsr_safe_on_cpu(void *info)
  42. {
  43. struct msr_info *rv = info;
  44. rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
  45. }
  46. static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe)
  47. {
  48. int err = 0;
  49. struct msr_info rv;
  50. rv.msr_no = msr_no;
  51. rv.l = l;
  52. rv.h = h;
  53. if (safe) {
  54. err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu,
  55. &rv, 1);
  56. err = err ? err : rv.err;
  57. } else {
  58. err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
  59. }
  60. return err;
  61. }
  62. int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
  63. {
  64. return _wrmsr_on_cpu(cpu, msr_no, l, h, 0);
  65. }
  66. int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
  67. {
  68. return _rdmsr_on_cpu(cpu, msr_no, l, h, 0);
  69. }
  70. /* These "safe" variants are slower and should be used when the target MSR
  71. may not actually exist. */
  72. int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
  73. {
  74. return _wrmsr_on_cpu(cpu, msr_no, l, h, 1);
  75. }
  76. int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
  77. {
  78. return _rdmsr_on_cpu(cpu, msr_no, l, h, 1);
  79. }
  80. EXPORT_SYMBOL(rdmsr_on_cpu);
  81. EXPORT_SYMBOL(wrmsr_on_cpu);
  82. EXPORT_SYMBOL(rdmsr_safe_on_cpu);
  83. EXPORT_SYMBOL(wrmsr_safe_on_cpu);