xref: /illumos-kvm/kvm_msr.h (revision 2a9ff8dc)
1 /*
2  * GPL HEADER START
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * GPL HEADER END
18  *
19  * Derived from Linux Kernel ./arch/x86/include/asm/msr.h
20  *
21  * Copyright 2011 various Linux Kernel contributors.
22  * Copyright 2011 Joyent, Inc. All Rights Reserved.
23  */
24 
25 #ifndef _KVM_MSR_H
26 #define	_KVM_MSR_H
27 
28 #include "msr-index.h"
29 
30 #include <sys/ontrap.h>
31 #include <sys/errno.h>
32 
33 typedef struct msr {
34 	union {
35 		struct {
36 			uint32_t l;
37 			uint32_t h;
38 		};
39 		uint64_t q;
40 	}b;
41 } msr_t;
42 
43 typedef struct msr_info {
44 	uint32_t msr_no;
45 	struct msr reg;
46 	struct msr *msrs;
47 	int err;
48 } msr_info_t;
49 
50 typedef struct msr_regs_info {
51 	uint32_t *regs;
52 	int err;
53 } msr_regs_info_t;
54 
55 /*
56  * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
57  * constraint has different meanings. For i386, "A" means exactly
58  * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
59  * it means rax *or* rdx.
60  */
61 #define	DECLARE_ARGS(val, low, high)	unsigned low, high
62 #define	EAX_EDX_VAL(val, low, high)	((low) | ((uint64_t)(high) << 32))
63 #define	EAX_EDX_ARGS(val, low, high)	"a" (low), "d" (high)
64 #define	EAX_EDX_RET(val, low, high)	"=a" (low), "=d" (high)
65 
66 extern unsigned long long native_read_msr(unsigned int);
67 extern uint64_t native_read_msr_safe(unsigned int, int *);
68 extern int native_write_msr_safe(unsigned int, unsigned, unsigned);
69 extern void native_write_msr(unsigned int, unsigned, unsigned);
70 
71 extern unsigned long long native_read_tsc(void);
72 extern unsigned long long __native_read_tsc(void);
73 
74 /*
75  * Access to machine-specific registers (available on 586 and better only)
76  * Note: the rd* operations modify the parameters directly (without using
77  * pointer indirection), this allows gcc to optimize better
78  */
79 
80 #define	rdmsr(msr, val1, val2)						\
81 do {									\
82 	uint64_t __val = native_read_msr((msr));			\
83 	(val1) = (uint32_t)__val;					\
84 	(val2) = (uint32_t)(__val >> 32);				\
85 } while (0)
86 
87 #define	rdmsrl(msr, val)						\
88 	((val) = native_read_msr((msr)))
89 
90 #define	wrmsrl(msr, val)						\
91 	native_write_msr((msr), (uint32_t)((uint64_t)(val)),		\
92 	    (uint32_t)((uint64_t)(val) >> 32))
93 
94 /* see comment above for wrmsr() */
95 /* wrmsr with exception handling */
96 extern int wrmsr_safe(unsigned msr, unsigned low, unsigned high);
97 
98 /* rdmsr with exception handling */
99 /* BEGIN CSTYLED */
100 #define	rdmsr_safe(msr, p1, p2)					\
101 ({								\
102 	int __err;						\
103 	uint64_t __val = native_read_msr_safe((msr), &__err);	\
104 	(*p1) = (uint32_t)__val;				\
105 	(*p2) = (uint32_t)(__val >> 32);			\
106 	__err;							\
107 })
108 /* END CSTYLED */
109 
110 extern int rdmsrl_safe(unsigned, unsigned long long *);
111 extern int rdmsrl_amd_safe(unsigned, unsigned long long *);
112 extern int wrmsrl_amd_safe(unsigned, unsigned long long);
113 
114 #define	rdtscl(low)						\
115 	((low) = (uint32_t)__native_read_tsc())
116 
117 #define	rdtscll(val)						\
118 	((val) = __native_read_tsc())
119 
120 #endif /* _KVM_MSR_H */
121