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