Home | History | Annotate | Download | only in asm
      1 /* SPDX-License-Identifier: GPL-2.0+ */
      2 /*
      3  * Taken from the linux kernel file of the same name
      4  *
      5  * (C) Copyright 2012
      6  * Graeme Russ, <graeme.russ (at) gmail.com>
      7  */
      8 
      9 #ifndef _ASM_X86_MSR_H
     10 #define _ASM_X86_MSR_H
     11 
     12 #include <asm/msr-index.h>
     13 
     14 #ifndef __ASSEMBLY__
     15 
     16 #include <linux/types.h>
     17 #include <linux/ioctl.h>
     18 
     19 #define X86_IOC_RDMSR_REGS	_IOWR('c', 0xA0, __u32[8])
     20 #define X86_IOC_WRMSR_REGS	_IOWR('c', 0xA1, __u32[8])
     21 
     22 #ifdef __KERNEL__
     23 
     24 #include <linux/errno.h>
     25 
     26 struct msr {
     27 	union {
     28 		struct {
     29 			u32 l;
     30 			u32 h;
     31 		};
     32 		u64 q;
     33 	};
     34 };
     35 
     36 struct msr_info {
     37 	u32 msr_no;
     38 	struct msr reg;
     39 	struct msr *msrs;
     40 	int err;
     41 };
     42 
     43 struct msr_regs_info {
     44 	u32 *regs;
     45 	int err;
     46 };
     47 
     48 static inline unsigned long long native_read_tscp(unsigned int *aux)
     49 {
     50 	unsigned long low, high;
     51 	asm volatile(".byte 0x0f,0x01,0xf9"
     52 		     : "=a" (low), "=d" (high), "=c" (*aux));
     53 	return low | ((u64)high << 32);
     54 }
     55 
     56 /*
     57  * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
     58  * constraint has different meanings. For i386, "A" means exactly
     59  * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
     60  * it means rax *or* rdx.
     61  */
     62 #ifdef CONFIG_X86_64
     63 #define DECLARE_ARGS(val, low, high)	unsigned low, high
     64 #define EAX_EDX_VAL(val, low, high)	((low) | ((u64)(high) << 32))
     65 #define EAX_EDX_ARGS(val, low, high)	"a" (low), "d" (high)
     66 #define EAX_EDX_RET(val, low, high)	"=a" (low), "=d" (high)
     67 #else
     68 #define DECLARE_ARGS(val, low, high)	unsigned long long val
     69 #define EAX_EDX_VAL(val, low, high)	(val)
     70 #define EAX_EDX_ARGS(val, low, high)	"A" (val)
     71 #define EAX_EDX_RET(val, low, high)	"=A" (val)
     72 #endif
     73 
     74 static inline __attribute__((no_instrument_function))
     75 	unsigned long long native_read_msr(unsigned int msr)
     76 {
     77 	DECLARE_ARGS(val, low, high);
     78 
     79 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
     80 	return EAX_EDX_VAL(val, low, high);
     81 }
     82 
     83 static inline void native_write_msr(unsigned int msr,
     84 				    unsigned low, unsigned high)
     85 {
     86 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
     87 }
     88 
     89 extern unsigned long long native_read_tsc(void);
     90 
     91 extern int native_rdmsr_safe_regs(u32 regs[8]);
     92 extern int native_wrmsr_safe_regs(u32 regs[8]);
     93 
     94 static inline unsigned long long native_read_pmc(int counter)
     95 {
     96 	DECLARE_ARGS(val, low, high);
     97 
     98 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
     99 	return EAX_EDX_VAL(val, low, high);
    100 }
    101 
    102 #ifdef CONFIG_PARAVIRT
    103 #include <asm/paravirt.h>
    104 #else
    105 #include <errno.h>
    106 /*
    107  * Access to machine-specific registers (available on 586 and better only)
    108  * Note: the rd* operations modify the parameters directly (without using
    109  * pointer indirection), this allows gcc to optimize better
    110  */
    111 
    112 #define rdmsr(msr, val1, val2)					\
    113 do {								\
    114 	u64 __val = native_read_msr((msr));			\
    115 	(void)((val1) = (u32)__val);				\
    116 	(void)((val2) = (u32)(__val >> 32));			\
    117 } while (0)
    118 
    119 static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
    120 {
    121 	native_write_msr(msr, low, high);
    122 }
    123 
    124 #define rdmsrl(msr, val)			\
    125 	((val) = native_read_msr((msr)))
    126 
    127 #define wrmsrl(msr, val)						\
    128 	native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32))
    129 
    130 static inline void msr_clrsetbits_64(unsigned msr, u64 clear, u64 set)
    131 {
    132 	u64 val;
    133 
    134 	val = native_read_msr(msr);
    135 	val &= ~clear;
    136 	val |= set;
    137 	wrmsrl(msr, val);
    138 }
    139 
    140 static inline void msr_setbits_64(unsigned msr, u64 set)
    141 {
    142 	u64 val;
    143 
    144 	val = native_read_msr(msr);
    145 	val |= set;
    146 	wrmsrl(msr, val);
    147 }
    148 
    149 static inline void msr_clrbits_64(unsigned msr, u64 clear)
    150 {
    151 	u64 val;
    152 
    153 	val = native_read_msr(msr);
    154 	val &= ~clear;
    155 	wrmsrl(msr, val);
    156 }
    157 
    158 /* rdmsr with exception handling */
    159 #define rdmsr_safe(msr, p1, p2)					\
    160 ({								\
    161 	int __err;						\
    162 	u64 __val = native_read_msr_safe((msr), &__err);	\
    163 	(*p1) = (u32)__val;					\
    164 	(*p2) = (u32)(__val >> 32);				\
    165 	__err;							\
    166 })
    167 
    168 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
    169 {
    170 	u32 gprs[8] = { 0 };
    171 	int err;
    172 
    173 	gprs[1] = msr;
    174 	gprs[7] = 0x9c5a203a;
    175 
    176 	err = native_rdmsr_safe_regs(gprs);
    177 
    178 	*p = gprs[0] | ((u64)gprs[2] << 32);
    179 
    180 	return err;
    181 }
    182 
    183 static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
    184 {
    185 	u32 gprs[8] = { 0 };
    186 
    187 	gprs[0] = (u32)val;
    188 	gprs[1] = msr;
    189 	gprs[2] = val >> 32;
    190 	gprs[7] = 0x9c5a203a;
    191 
    192 	return native_wrmsr_safe_regs(gprs);
    193 }
    194 
    195 static inline int rdmsr_safe_regs(u32 regs[8])
    196 {
    197 	return native_rdmsr_safe_regs(regs);
    198 }
    199 
    200 static inline int wrmsr_safe_regs(u32 regs[8])
    201 {
    202 	return native_wrmsr_safe_regs(regs);
    203 }
    204 
    205 typedef struct msr_t {
    206 	uint32_t lo;
    207 	uint32_t hi;
    208 } msr_t;
    209 
    210 static inline struct msr_t msr_read(unsigned msr_num)
    211 {
    212 	struct msr_t msr;
    213 
    214 	rdmsr(msr_num, msr.lo, msr.hi);
    215 
    216 	return msr;
    217 }
    218 
    219 static inline void msr_write(unsigned msr_num, msr_t msr)
    220 {
    221 	wrmsr(msr_num, msr.lo, msr.hi);
    222 }
    223 
    224 #define rdtscl(low)						\
    225 	((low) = (u32)__native_read_tsc())
    226 
    227 #define rdtscll(val)						\
    228 	((val) = __native_read_tsc())
    229 
    230 #define rdpmc(counter, low, high)			\
    231 do {							\
    232 	u64 _l = native_read_pmc((counter));		\
    233 	(low)  = (u32)_l;				\
    234 	(high) = (u32)(_l >> 32);			\
    235 } while (0)
    236 
    237 #define rdtscp(low, high, aux)					\
    238 do {                                                            \
    239 	unsigned long long _val = native_read_tscp(&(aux));     \
    240 	(low) = (u32)_val;                                      \
    241 	(high) = (u32)(_val >> 32);                             \
    242 } while (0)
    243 
    244 #define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
    245 
    246 #endif	/* !CONFIG_PARAVIRT */
    247 
    248 
    249 #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),		\
    250 					     (u32)((val) >> 32))
    251 
    252 #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
    253 
    254 #define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
    255 
    256 struct msr *msrs_alloc(void);
    257 void msrs_free(struct msr *msrs);
    258 
    259 #endif /* __KERNEL__ */
    260 #endif /* __ASSEMBLY__ */
    261 #endif /* _ASM_X86_MSR_H */
    262