msr.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <linux/module.h>
  2. #include <linux/preempt.h>
  3. #include <asm/msr.h>
  4. #define CREATE_TRACE_POINTS
  5. #include <asm/msr-trace.h>
  6. struct msr *msrs_alloc(void)
  7. {
  8. struct msr *msrs = NULL;
  9. msrs = alloc_percpu(struct msr);
  10. if (!msrs) {
  11. pr_warn("%s: error allocating msrs\n", __func__);
  12. return NULL;
  13. }
  14. return msrs;
  15. }
  16. EXPORT_SYMBOL(msrs_alloc);
  17. void msrs_free(struct msr *msrs)
  18. {
  19. free_percpu(msrs);
  20. }
  21. EXPORT_SYMBOL(msrs_free);
  22. /**
  23. * Read an MSR with error handling
  24. *
  25. * @msr: MSR to read
  26. * @m: value to read into
  27. *
  28. * It returns read data only on success, otherwise it doesn't change the output
  29. * argument @m.
  30. *
  31. */
  32. int msr_read(u32 msr, struct msr *m)
  33. {
  34. int err;
  35. u64 val;
  36. err = rdmsrl_safe(msr, &val);
  37. if (!err)
  38. m->q = val;
  39. return err;
  40. }
  41. /**
  42. * Write an MSR with error handling
  43. *
  44. * @msr: MSR to write
  45. * @m: value to write
  46. */
  47. int msr_write(u32 msr, struct msr *m)
  48. {
  49. return wrmsrl_safe(msr, m->q);
  50. }
  51. static inline int __flip_bit(u32 msr, u8 bit, bool set)
  52. {
  53. struct msr m, m1;
  54. int err = -EINVAL;
  55. if (bit > 63)
  56. return err;
  57. err = msr_read(msr, &m);
  58. if (err)
  59. return err;
  60. m1 = m;
  61. if (set)
  62. m1.q |= BIT_64(bit);
  63. else
  64. m1.q &= ~BIT_64(bit);
  65. if (m1.q == m.q)
  66. return 0;
  67. err = msr_write(msr, &m1);
  68. if (err)
  69. return err;
  70. return 1;
  71. }
  72. /**
  73. * Set @bit in a MSR @msr.
  74. *
  75. * Retval:
  76. * < 0: An error was encountered.
  77. * = 0: Bit was already set.
  78. * > 0: Hardware accepted the MSR write.
  79. */
  80. int msr_set_bit(u32 msr, u8 bit)
  81. {
  82. return __flip_bit(msr, bit, true);
  83. }
  84. /**
  85. * Clear @bit in a MSR @msr.
  86. *
  87. * Retval:
  88. * < 0: An error was encountered.
  89. * = 0: Bit was already cleared.
  90. * > 0: Hardware accepted the MSR write.
  91. */
  92. int msr_clear_bit(u32 msr, u8 bit)
  93. {
  94. return __flip_bit(msr, bit, false);
  95. }
  96. #ifdef CONFIG_TRACEPOINTS
  97. void do_trace_write_msr(unsigned msr, u64 val, int failed)
  98. {
  99. trace_write_msr(msr, val, failed);
  100. }
  101. EXPORT_SYMBOL(do_trace_write_msr);
  102. EXPORT_TRACEPOINT_SYMBOL(write_msr);
  103. void do_trace_read_msr(unsigned msr, u64 val, int failed)
  104. {
  105. trace_read_msr(msr, val, failed);
  106. }
  107. EXPORT_SYMBOL(do_trace_read_msr);
  108. EXPORT_TRACEPOINT_SYMBOL(read_msr);
  109. void do_trace_rdpmc(unsigned counter, u64 val, int failed)
  110. {
  111. trace_rdpmc(counter, val, failed);
  112. }
  113. EXPORT_SYMBOL(do_trace_rdpmc);
  114. EXPORT_TRACEPOINT_SYMBOL(rdpmc);
  115. #endif