]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/x86/include/asm/processor.h
x86: print CR2 in case the hypervisor causes a pagefault
[jailhouse.git] / hypervisor / arch / x86 / include / asm / processor.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2013
5  *
6  * Authors:
7  *  Jan Kiszka <jan.kiszka@siemens.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #ifndef _JAILHOUSE_ASM_PROCESSOR_H
14 #define _JAILHOUSE_ASM_PROCESSOR_H
15
16 #include <asm/types.h>
17
18 #define X86_FEATURE_VMX                                 (1 << 5)
19 #define X86_FEATURE_GBPAGES                             (1 << 26)
20 #define X86_FEATURE_RDTSCP                              (1 << 27)
21
22 #define X86_RFLAGS_VM                                   (1 << 17)
23
24 #define X86_CR0_PE                                      0x00000001
25 #define X86_CR0_ET                                      0x00000010
26 #define X86_CR0_NW                                      0x20000000
27 #define X86_CR0_CD                                      0x40000000
28 #define X86_CR0_PG                                      0x80000000
29
30 #define X86_CR4_PAE                                     0x00000020
31 #define X86_CR4_PGE                                     0x00000080
32 #define X86_CR4_VMXE                                    0x00002000
33
34 #define X86_XCR0_FP                                     0x00000001
35
36 #define MSR_IA32_APICBASE                               0x0000001b
37 #define MSR_IA32_FEATURE_CONTROL                        0x0000003a
38 #define MSR_IA32_SYSENTER_CS                            0x00000174
39 #define MSR_IA32_SYSENTER_ESP                           0x00000175
40 #define MSR_IA32_SYSENTER_EIP                           0x00000176
41 #define MSR_IA32_VMX_BASIC                              0x00000480
42 #define MSR_IA32_VMX_PINBASED_CTLS                      0x00000481
43 #define MSR_IA32_VMX_PROCBASED_CTLS                     0x00000482
44 #define MSR_IA32_VMX_EXIT_CTLS                          0x00000483
45 #define MSR_IA32_VMX_ENTRY_CTLS                         0x00000484
46 #define MSR_IA32_VMX_MISC                               0x00000485
47 #define MSR_IA32_VMX_CR0_FIXED0                         0x00000486
48 #define MSR_IA32_VMX_CR0_FIXED1                         0x00000487
49 #define MSR_IA32_VMX_CR4_FIXED0                         0x00000488
50 #define MSR_IA32_VMX_CR4_FIXED1                         0x00000489
51 #define MSR_IA32_VMX_PROCBASED_CTLS2                    0x0000048b
52 #define MSR_IA32_VMX_EPT_VPID_CAP                       0x0000048c
53 #define MSR_IA32_VMX_TRUE_PROCBASED_CTLS                0x0000048e
54 #define MSR_X2APIC_BASE                                 0x00000800
55 #define MSR_X2APIC_ICR                                  0x00000830
56 #define MSR_X2APIC_END                                  0x0000083f
57 #define MSR_EFER                                        0xc0000080
58 #define MSR_FS_BASE                                     0xc0000100
59 #define MSR_GS_BASE                                     0xc0000101
60
61 #define FEATURE_CONTROL_LOCKED                          (1 << 0)
62 #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX       (1 << 2)
63
64 #define EFER_LME                                        0x00000100
65 #define EFER_LMA                                        0x00000400
66
67 #define GDT_DESC_NULL                                   0
68 #define GDT_DESC_CODE                                   1
69 #define GDT_DESC_TSS                                    2
70 #define GDT_DESC_TSS_HI                                 3
71 #define NUM_GDT_DESC                                    4
72
73 #define X86_INST_LEN_CPUID                              2
74 #define X86_INST_LEN_RDMSR                              2
75 #define X86_INST_LEN_WRMSR                              2
76 #define X86_INST_LEN_VMCALL                             3
77 #define X86_INST_LEN_MOV_TO_CR                          3
78 #define X86_INST_LEN_XSETBV                             3
79
80 #define X86_REX_CODE                                    4
81
82 #define X86_OP_MOV_TO_MEM                               0x89
83 #define X86_OP_MOV_FROM_MEM                             0x8b
84
85 #define NMI_VECTOR                                      2
86 #define PF_VECTOR                                       14
87
88 #define DESC_TSS_BUSY                                   (1UL << (9 + 32))
89 #define DESC_PRESENT                                    (1UL << (15 + 32))
90 #define DESC_CODE_DATA                                  (1UL << (12 + 32))
91 #define DESC_PAGE_GRAN                                  (1UL << (23 + 32))
92
93 #ifndef __ASSEMBLY__
94
95 struct registers {
96         unsigned long r15;
97         unsigned long r14;
98         unsigned long r13;
99         unsigned long r12;
100         unsigned long r11;
101         unsigned long r10;
102         unsigned long r9;
103         unsigned long r8;
104         unsigned long rdi;
105         unsigned long rsi;
106         unsigned long rbp;
107         unsigned long unused;
108         unsigned long rbx;
109         unsigned long rdx;
110         unsigned long rcx;
111         unsigned long rax;
112 };
113
114 struct desc_table_reg {
115         u16 limit;
116         u64 base;
117 } __attribute__((packed));
118
119 struct segment {
120         u64 base;
121         u32 limit;
122         u32 access_rights;
123         u16 selector;
124 };
125
126 static unsigned long __force_order;
127
128 static inline void cpu_relax(void)
129 {
130         asm volatile("rep; nop" : : : "memory");
131 }
132
133 static inline void memory_barrier(void)
134 {
135         asm volatile("mfence" : : : "memory");
136 }
137
138 static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
139                            unsigned int *ecx, unsigned int *edx)
140 {
141         /* ecx is often an input as well as an output. */
142         asm volatile("cpuid"
143             : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
144             : "0" (*eax), "2" (*ecx)
145             : "memory");
146 }
147
148 static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
149                          unsigned int *ecx, unsigned int *edx)
150 {
151         *eax = op;
152         *ecx = 0;
153         __cpuid(eax, ebx, ecx, edx);
154 }
155
156 #define CPUID_REG(reg)                                          \
157 static inline unsigned int cpuid_##reg(unsigned int op)         \
158 {                                                               \
159         unsigned int eax, ebx, ecx, edx;                        \
160                                                                 \
161         cpuid(op, &eax, &ebx, &ecx, &edx);                      \
162         return reg;                                             \
163 }
164
165 CPUID_REG(eax)
166 CPUID_REG(ebx)
167 CPUID_REG(ecx)
168 CPUID_REG(edx)
169
170 static inline unsigned long read_cr0(void)
171 {
172         unsigned long cr0;
173
174         asm volatile("mov %%cr0,%0" : "=r" (cr0), "=m" (__force_order));
175         return cr0;
176 }
177
178 static inline void write_cr0(unsigned long val)
179 {
180         asm volatile("mov %0,%%cr0" : : "r" (val), "m" (__force_order));
181 }
182
183 static inline unsigned long read_cr2(void)
184 {
185         unsigned long cr2;
186
187         asm volatile("mov %%cr2,%0" : "=r" (cr2), "=m" (__force_order));
188         return cr2;
189 }
190
191 static inline unsigned long read_cr3(void)
192 {
193         unsigned long cr3;
194
195         asm volatile("mov %%cr3,%0" : "=r" (cr3), "=m" (__force_order));
196         return cr3;
197 }
198
199 static inline void write_cr3(unsigned long val)
200 {
201         asm volatile("mov %0,%%cr3" : : "r" (val), "m" (__force_order));
202 }
203
204 static inline unsigned long read_cr4(void)
205 {
206         unsigned long cr4;
207
208         asm volatile("mov %%cr4,%0" : "=r" (cr4), "=m" (__force_order));
209         return cr4;
210 }
211
212 static inline void write_cr4(unsigned long val)
213 {
214         asm volatile("mov %0,%%cr4" : : "r" (val), "m" (__force_order));
215 }
216
217 static inline unsigned long read_msr(unsigned int msr)
218 {
219         u32 low, high;
220
221         asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
222         return low | ((unsigned long)high << 32);
223 }
224
225 static inline void write_msr(unsigned int msr, unsigned long val)
226 {
227         asm volatile("wrmsr"
228                 : /* no output */
229                 : "c" (msr), "a" (val), "d" (val >> 32)
230                 : "memory");
231 }
232
233 static inline void read_gdtr(struct desc_table_reg *val)
234 {
235         asm volatile("sgdtq %0" : "=m" (*val));
236 }
237
238 static inline void write_gdtr(struct desc_table_reg *val)
239 {
240         asm volatile("lgdtq %0" : : "m" (*val));
241 }
242
243 static inline void read_idtr(struct desc_table_reg *val)
244 {
245         asm volatile("sidtq %0" : "=m" (*val));
246 }
247
248 static inline void write_idtr(struct desc_table_reg *val)
249 {
250         asm volatile("lidtq %0" : : "m" (*val));
251 }
252
253 static inline void enable_irq(void)
254 {
255         asm volatile("sti");
256 }
257
258 static inline void disable_irq(void)
259 {
260         asm volatile("cli");
261 }
262
263 #endif /* !__ASSEMBLY__ */
264
265 #endif /* !_JAILHOUSE_ASM_PROCESSOR_H */