msr.c 1.6 KB

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