Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef _ASM_X86_MSR_H
3 : : #define _ASM_X86_MSR_H
4 : :
5 : : #include "msr-index.h"
6 : :
7 : : #ifndef __ASSEMBLY__
8 : :
9 : : #include <asm/asm.h>
10 : : #include <asm/errno.h>
11 : : #include <asm/cpumask.h>
12 : : #include <uapi/asm/msr.h>
13 : :
14 : : struct msr {
15 : : union {
16 : : struct {
17 : : u32 l;
18 : : u32 h;
19 : : };
20 : : u64 q;
21 : : };
22 : : };
23 : :
24 : : struct msr_info {
25 : : u32 msr_no;
26 : : struct msr reg;
27 : : struct msr *msrs;
28 : : int err;
29 : : };
30 : :
31 : : struct msr_regs_info {
32 : : u32 *regs;
33 : : int err;
34 : : };
35 : :
36 : : struct saved_msr {
37 : : bool valid;
38 : : struct msr_info info;
39 : : };
40 : :
41 : : struct saved_msrs {
42 : : unsigned int num;
43 : : struct saved_msr *array;
44 : : };
45 : :
46 : : /*
47 : : * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
48 : : * constraint has different meanings. For i386, "A" means exactly
49 : : * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
50 : : * it means rax *or* rdx.
51 : : */
52 : : #ifdef CONFIG_X86_64
53 : : /* Using 64-bit values saves one instruction clearing the high half of low */
54 : : #define DECLARE_ARGS(val, low, high) unsigned long low, high
55 : : #define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32)
56 : : #define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
57 : : #else
58 : : #define DECLARE_ARGS(val, low, high) unsigned long long val
59 : : #define EAX_EDX_VAL(val, low, high) (val)
60 : : #define EAX_EDX_RET(val, low, high) "=A" (val)
61 : : #endif
62 : :
63 : : #ifdef CONFIG_TRACEPOINTS
64 : : /*
65 : : * Be very careful with includes. This header is prone to include loops.
66 : : */
67 : : #include <asm/atomic.h>
68 : : #include <linux/tracepoint-defs.h>
69 : :
70 : : extern struct tracepoint __tracepoint_read_msr;
71 : : extern struct tracepoint __tracepoint_write_msr;
72 : : extern struct tracepoint __tracepoint_rdpmc;
73 : : #define msr_tracepoint_active(t) static_key_false(&(t).key)
74 : : extern void do_trace_write_msr(unsigned int msr, u64 val, int failed);
75 : : extern void do_trace_read_msr(unsigned int msr, u64 val, int failed);
76 : : extern void do_trace_rdpmc(unsigned int msr, u64 val, int failed);
77 : : #else
78 : : #define msr_tracepoint_active(t) false
79 : : static inline void do_trace_write_msr(unsigned int msr, u64 val, int failed) {}
80 : : static inline void do_trace_read_msr(unsigned int msr, u64 val, int failed) {}
81 : : static inline void do_trace_rdpmc(unsigned int msr, u64 val, int failed) {}
82 : : #endif
83 : :
84 : : /*
85 : : * __rdmsr() and __wrmsr() are the two primitives which are the bare minimum MSR
86 : : * accessors and should not have any tracing or other functionality piggybacking
87 : : * on them - those are *purely* for accessing MSRs and nothing more. So don't even
88 : : * think of extending them - you will be slapped with a stinking trout or a frozen
89 : : * shark will reach you, wherever you are! You've been warned.
90 : : */
91 : 231 : static inline unsigned long long notrace __rdmsr(unsigned int msr)
92 : : {
93 : 231 : DECLARE_ARGS(val, low, high);
94 : :
95 : 231 : asm volatile("1: rdmsr\n"
96 : : "2:\n"
97 : : _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe)
98 : : : EAX_EDX_RET(val, low, high) : "c" (msr));
99 : :
100 [ # # # # : 231 : return EAX_EDX_VAL(val, low, high);
# # ]
101 : : }
102 : :
103 : 61046 : static inline void notrace __wrmsr(unsigned int msr, u32 low, u32 high)
104 : : {
105 : 61046 : asm volatile("1: wrmsr\n"
106 : : "2:\n"
107 : : _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe)
108 : : : : "c" (msr), "a"(low), "d" (high) : "memory");
109 : : }
110 : :
111 : : #define native_rdmsr(msr, val1, val2) \
112 : : do { \
113 : : u64 __val = __rdmsr((msr)); \
114 : : (void)((val1) = (u32)__val); \
115 : : (void)((val2) = (u32)(__val >> 32)); \
116 : : } while (0)
117 : :
118 : : #define native_wrmsr(msr, low, high) \
119 : : __wrmsr(msr, low, high)
120 : :
121 : : #define native_wrmsrl(msr, val) \
122 : : __wrmsr((msr), (u32)((u64)(val)), \
123 : : (u32)((u64)(val) >> 32))
124 : :
125 : 231 : static inline unsigned long long native_read_msr(unsigned int msr)
126 : : {
127 : 231 : unsigned long long val;
128 : :
129 : 231 : val = __rdmsr(msr);
130 : :
131 [ - + ]: 231 : if (msr_tracepoint_active(__tracepoint_read_msr))
132 : 0 : do_trace_read_msr(msr, val, 0);
133 : :
134 : 231 : return val;
135 : : }
136 : :
137 : 90 : static inline unsigned long long native_read_msr_safe(unsigned int msr,
138 : : int *err)
139 : : {
140 : 90 : DECLARE_ARGS(val, low, high);
141 : :
142 : 90 : asm volatile("2: rdmsr ; xor %[err],%[err]\n"
143 : : "1:\n\t"
144 : : ".section .fixup,\"ax\"\n\t"
145 : : "3: mov %[fault],%[err]\n\t"
146 : : "xorl %%eax, %%eax\n\t"
147 : : "xorl %%edx, %%edx\n\t"
148 : : "jmp 1b\n\t"
149 : : ".previous\n\t"
150 : : _ASM_EXTABLE(2b, 3b)
151 : : : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
152 : : : "c" (msr), [fault] "i" (-EIO));
153 [ - + ]: 90 : if (msr_tracepoint_active(__tracepoint_read_msr))
154 : 0 : do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
155 : 90 : return EAX_EDX_VAL(val, low, high);
156 : : }
157 : :
158 : : /* Can be uninlined because referenced by paravirt */
159 : : static inline void notrace
160 : 61046 : native_write_msr(unsigned int msr, u32 low, u32 high)
161 : : {
162 : 61046 : __wrmsr(msr, low, high);
163 : :
164 [ - + ]: 61046 : if (msr_tracepoint_active(__tracepoint_write_msr))
165 : 0 : do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
166 : 61046 : }
167 : :
168 : : /* Can be uninlined because referenced by paravirt */
169 : : static inline int notrace
170 : 27 : native_write_msr_safe(unsigned int msr, u32 low, u32 high)
171 : : {
172 : 27 : int err;
173 : :
174 : 27 : asm volatile("2: wrmsr ; xor %[err],%[err]\n"
175 : : "1:\n\t"
176 : : ".section .fixup,\"ax\"\n\t"
177 : : "3: mov %[fault],%[err] ; jmp 1b\n\t"
178 : : ".previous\n\t"
179 : : _ASM_EXTABLE(2b, 3b)
180 : : : [err] "=a" (err)
181 : : : "c" (msr), "0" (low), "d" (high),
182 : : [fault] "i" (-EIO)
183 : : : "memory");
184 [ - + ]: 27 : if (msr_tracepoint_active(__tracepoint_write_msr))
185 : 0 : do_trace_write_msr(msr, ((u64)high << 32 | low), err);
186 : 27 : return err;
187 : : }
188 : :
189 : : extern int rdmsr_safe_regs(u32 regs[8]);
190 : : extern int wrmsr_safe_regs(u32 regs[8]);
191 : :
192 : : /**
193 : : * rdtsc() - returns the current TSC without ordering constraints
194 : : *
195 : : * rdtsc() returns the result of RDTSC as a 64-bit integer. The
196 : : * only ordering constraint it supplies is the ordering implied by
197 : : * "asm volatile": it will put the RDTSC in the place you expect. The
198 : : * CPU can and will speculatively execute that RDTSC, though, so the
199 : : * results can be non-monotonic if compared on different CPUs.
200 : : */
201 : 9577191 : static __always_inline unsigned long long rdtsc(void)
202 : : {
203 : 9577191 : DECLARE_ARGS(val, low, high);
204 : :
205 : 9577191 : asm volatile("rdtsc" : EAX_EDX_RET(val, low, high));
206 : :
207 [ + + - + : 9577191 : return EAX_EDX_VAL(val, low, high);
+ + - - -
- # # #
# ]
208 : : }
209 : :
210 : : /**
211 : : * rdtsc_ordered() - read the current TSC in program order
212 : : *
213 : : * rdtsc_ordered() returns the result of RDTSC as a 64-bit integer.
214 : : * It is ordered like a load to a global in-memory counter. It should
215 : : * be impossible to observe non-monotonic rdtsc_unordered() behavior
216 : : * across multiple CPUs as long as the TSC is synced.
217 : : */
218 : 3139887 : static __always_inline unsigned long long rdtsc_ordered(void)
219 : : {
220 : 3139887 : DECLARE_ARGS(val, low, high);
221 : :
222 : : /*
223 : : * The RDTSC instruction is not ordered relative to memory
224 : : * access. The Intel SDM and the AMD APM are both vague on this
225 : : * point, but empirically an RDTSC instruction can be
226 : : * speculatively executed before prior loads. An RDTSC
227 : : * immediately after an appropriate barrier appears to be
228 : : * ordered as a normal load, that is, it provides the same
229 : : * ordering guarantees as reading from a global memory location
230 : : * that some other imaginary CPU is updating continuously with a
231 : : * time stamp.
232 : : *
233 : : * Thus, use the preferred barrier on the respective CPU, aiming for
234 : : * RDTSCP as the default.
235 : : */
236 : 3139887 : asm volatile(ALTERNATIVE_2("rdtsc",
237 : : "lfence; rdtsc", X86_FEATURE_LFENCE_RDTSC,
238 : : "rdtscp", X86_FEATURE_RDTSCP)
239 : : : EAX_EDX_RET(val, low, high)
240 : : /* RDTSCP clobbers ECX with MSR_TSC_AUX. */
241 : : :: "ecx");
242 : :
243 [ + - + + ]: 3139887 : return EAX_EDX_VAL(val, low, high);
244 : : }
245 : :
246 : 0 : static inline unsigned long long native_read_pmc(int counter)
247 : : {
248 : 0 : DECLARE_ARGS(val, low, high);
249 : :
250 : 0 : asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
251 [ # # ]: 0 : if (msr_tracepoint_active(__tracepoint_rdpmc))
252 : 0 : do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
253 : 0 : return EAX_EDX_VAL(val, low, high);
254 : : }
255 : :
256 : : #ifdef CONFIG_PARAVIRT_XXL
257 : : #include <asm/paravirt.h>
258 : : #else
259 : : #include <linux/errno.h>
260 : : /*
261 : : * Access to machine-specific registers (available on 586 and better only)
262 : : * Note: the rd* operations modify the parameters directly (without using
263 : : * pointer indirection), this allows gcc to optimize better
264 : : */
265 : :
266 : : #define rdmsr(msr, low, high) \
267 : : do { \
268 : : u64 __val = native_read_msr((msr)); \
269 : : (void)((low) = (u32)__val); \
270 : : (void)((high) = (u32)(__val >> 32)); \
271 : : } while (0)
272 : :
273 : 6 : static inline void wrmsr(unsigned int msr, u32 low, u32 high)
274 : : {
275 : 6 : native_write_msr(msr, low, high);
276 : 3 : }
277 : :
278 : : #define rdmsrl(msr, val) \
279 : : ((val) = native_read_msr((msr)))
280 : :
281 : 61039 : static inline void wrmsrl(unsigned int msr, u64 val)
282 : : {
283 : 61033 : native_write_msr(msr, (u32)(val & 0xffffffffULL), (u32)(val >> 32));
284 : 46084 : }
285 : :
286 : : /* wrmsr with exception handling */
287 : 27 : static inline int wrmsr_safe(unsigned int msr, u32 low, u32 high)
288 : : {
289 : 27 : return native_write_msr_safe(msr, low, high);
290 : : }
291 : :
292 : : /* rdmsr with exception handling */
293 : : #define rdmsr_safe(msr, low, high) \
294 : : ({ \
295 : : int __err; \
296 : : u64 __val = native_read_msr_safe((msr), &__err); \
297 : : (*low) = (u32)__val; \
298 : : (*high) = (u32)(__val >> 32); \
299 : : __err; \
300 : : })
301 : :
302 : 54 : static inline int rdmsrl_safe(unsigned int msr, unsigned long long *p)
303 : : {
304 : 54 : int err;
305 : :
306 : 54 : *p = native_read_msr_safe(msr, &err);
307 [ + + - - : 54 : return err;
- + + - ]
308 : : }
309 : :
310 : : #define rdpmc(counter, low, high) \
311 : : do { \
312 : : u64 _l = native_read_pmc((counter)); \
313 : : (low) = (u32)_l; \
314 : : (high) = (u32)(_l >> 32); \
315 : : } while (0)
316 : :
317 : : #define rdpmcl(counter, val) ((val) = native_read_pmc(counter))
318 : :
319 : : #endif /* !CONFIG_PARAVIRT_XXL */
320 : :
321 : : /*
322 : : * 64-bit version of wrmsr_safe():
323 : : */
324 : 15 : static inline int wrmsrl_safe(u32 msr, u64 val)
325 : : {
326 : 12 : return wrmsr_safe(msr, (u32)val, (u32)(val >> 32));
327 : : }
328 : :
329 : : #define write_tsc(low, high) wrmsr(MSR_IA32_TSC, (low), (high))
330 : :
331 : : #define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
332 : :
333 : : struct msr *msrs_alloc(void);
334 : : void msrs_free(struct msr *msrs);
335 : : int msr_set_bit(u32 msr, u8 bit);
336 : : int msr_clear_bit(u32 msr, u8 bit);
337 : :
338 : : #ifdef CONFIG_SMP
339 : : int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
340 : : int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
341 : : int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
342 : : int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
343 : : void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
344 : : void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
345 : : int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
346 : : int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
347 : : int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
348 : : int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
349 : : int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
350 : : int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
351 : : #else /* CONFIG_SMP */
352 : : static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
353 : : {
354 : : rdmsr(msr_no, *l, *h);
355 : : return 0;
356 : : }
357 : : static inline int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
358 : : {
359 : : wrmsr(msr_no, l, h);
360 : : return 0;
361 : : }
362 : : static inline int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
363 : : {
364 : : rdmsrl(msr_no, *q);
365 : : return 0;
366 : : }
367 : : static inline int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
368 : : {
369 : : wrmsrl(msr_no, q);
370 : : return 0;
371 : : }
372 : : static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
373 : : struct msr *msrs)
374 : : {
375 : : rdmsr_on_cpu(0, msr_no, &(msrs[0].l), &(msrs[0].h));
376 : : }
377 : : static inline void wrmsr_on_cpus(const struct cpumask *m, u32 msr_no,
378 : : struct msr *msrs)
379 : : {
380 : : wrmsr_on_cpu(0, msr_no, msrs[0].l, msrs[0].h);
381 : : }
382 : : static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no,
383 : : u32 *l, u32 *h)
384 : : {
385 : : return rdmsr_safe(msr_no, l, h);
386 : : }
387 : : static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
388 : : {
389 : : return wrmsr_safe(msr_no, l, h);
390 : : }
391 : : static inline int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q)
392 : : {
393 : : return rdmsrl_safe(msr_no, q);
394 : : }
395 : : static inline int wrmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
396 : : {
397 : : return wrmsrl_safe(msr_no, q);
398 : : }
399 : : static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
400 : : {
401 : : return rdmsr_safe_regs(regs);
402 : : }
403 : : static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
404 : : {
405 : : return wrmsr_safe_regs(regs);
406 : : }
407 : : #endif /* CONFIG_SMP */
408 : : #endif /* __ASSEMBLY__ */
409 : : #endif /* _ASM_X86_MSR_H */
|