Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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