2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) 2005-2007, Advanced Micro Devices, Inc
5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) Valentine Sinitsyn, 2014
9 * Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
11 * Definitions in this file were adapted from Xvisor source code.
12 * See http://xhypervisor.org for details.
14 * This work is licensed under the terms of the GNU GPL, version 2. See
15 * the COPYING file in the top-level directory.
18 #ifndef _JAILHOUSE_ASM_SVM_H
19 #define _JAILHOUSE_ASM_SVM_H
21 #include <jailhouse/types.h>
23 #define EFER_SVME (1UL << 12)
24 #define VM_CR_SVMDIS (1UL << 4)
26 #define MSR_VM_CR 0xc0010114
27 #define MSR_VM_HSAVE_PA 0xc0010117
29 #define SVM_MSRPM_0000 0
30 #define SVM_MSRPM_C000 1
31 #define SVM_MSRPM_C001 2
32 #define SVM_MSRPM_RESV 3
34 #define SVM_TLB_FLUSH_ALL 0x01
35 #define SVM_TLB_FLUSH_GUEST 0x03
37 #define NPT_PAGE_DIR_LEVELS 4
44 } __attribute__((packed));
46 /* general 1 intercepts */
47 enum generic_interrupt_1_bits {
48 GENERAL1_INTERCEPT_INTR = 1 << 0,
49 GENERAL1_INTERCEPT_NMI = 1 << 1,
50 GENERAL1_INTERCEPT_SMI = 1 << 2,
51 GENERAL1_INTERCEPT_INIT = 1 << 3,
52 GENERAL1_INTERCEPT_VINTR = 1 << 4,
53 GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
54 GENERAL1_INTERCEPT_IDTR_READ = 1 << 6,
55 GENERAL1_INTERCEPT_GDTR_READ = 1 << 7,
56 GENERAL1_INTERCEPT_LDTR_READ = 1 << 8,
57 GENERAL1_INTERCEPT_TR_READ = 1 << 9,
58 GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10,
59 GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11,
60 GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12,
61 GENERAL1_INTERCEPT_TR_WRITE = 1 << 13,
62 GENERAL1_INTERCEPT_RDTSC = 1 << 14,
63 GENERAL1_INTERCEPT_RDPMC = 1 << 15,
64 GENERAL1_INTERCEPT_PUSHF = 1 << 16,
65 GENERAL1_INTERCEPT_POPF = 1 << 17,
66 GENERAL1_INTERCEPT_CPUID = 1 << 18,
67 GENERAL1_INTERCEPT_RSM = 1 << 19,
68 GENERAL1_INTERCEPT_IRET = 1 << 20,
69 GENERAL1_INTERCEPT_SWINT = 1 << 21,
70 GENERAL1_INTERCEPT_INVD = 1 << 22,
71 GENERAL1_INTERCEPT_PAUSE = 1 << 23,
72 GENERAL1_INTERCEPT_HLT = 1 << 24,
73 GENERAL1_INTERCEPT_INVLPG = 1 << 25,
74 GENERAL1_INTERCEPT_INVLPGA = 1 << 26,
75 GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27,
76 GENERAL1_INTERCEPT_MSR_PROT = 1 << 28,
77 GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29,
78 GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30,
79 GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1 << 31
82 /* general 2 intercepts */
83 enum generic_interrupts_2_bits {
84 GENERAL2_INTERCEPT_VMRUN = 1 << 0,
85 GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
86 GENERAL2_INTERCEPT_VMLOAD = 1 << 2,
87 GENERAL2_INTERCEPT_VMSAVE = 1 << 3,
88 GENERAL2_INTERCEPT_STGI = 1 << 4,
89 GENERAL2_INTERCEPT_CLGI = 1 << 5,
90 GENERAL2_INTERCEPT_SKINIT = 1 << 6,
91 GENERAL2_INTERCEPT_RDTSCP = 1 << 7,
92 GENERAL2_INTERCEPT_ICEBP = 1 << 8,
93 GENERAL2_INTERCEPT_WBINVD = 1 << 9,
94 GENERAL2_INTERCEPT_MONITOR = 1 << 10,
95 GENERAL2_INTERCEPT_MWAIT = 1 << 11,
96 GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12
100 /* control register read exitcodes */
111 VMEXIT_CR10_READ = 10,
112 VMEXIT_CR11_READ = 11,
113 VMEXIT_CR12_READ = 12,
114 VMEXIT_CR13_READ = 13,
115 VMEXIT_CR14_READ = 14,
116 VMEXIT_CR15_READ = 15,
118 /* control register write exitcodes */
119 VMEXIT_CR0_WRITE = 16,
120 VMEXIT_CR1_WRITE = 17,
121 VMEXIT_CR2_WRITE = 18,
122 VMEXIT_CR3_WRITE = 19,
123 VMEXIT_CR4_WRITE = 20,
124 VMEXIT_CR5_WRITE = 21,
125 VMEXIT_CR6_WRITE = 22,
126 VMEXIT_CR7_WRITE = 23,
127 VMEXIT_CR8_WRITE = 24,
128 VMEXIT_CR9_WRITE = 25,
129 VMEXIT_CR10_WRITE = 26,
130 VMEXIT_CR11_WRITE = 27,
131 VMEXIT_CR12_WRITE = 28,
132 VMEXIT_CR13_WRITE = 29,
133 VMEXIT_CR14_WRITE = 30,
134 VMEXIT_CR15_WRITE = 31,
136 /* debug register read exitcodes */
137 VMEXIT_DR0_READ = 32,
138 VMEXIT_DR1_READ = 33,
139 VMEXIT_DR2_READ = 34,
140 VMEXIT_DR3_READ = 35,
141 VMEXIT_DR4_READ = 36,
142 VMEXIT_DR5_READ = 37,
143 VMEXIT_DR6_READ = 38,
144 VMEXIT_DR7_READ = 39,
145 VMEXIT_DR8_READ = 40,
146 VMEXIT_DR9_READ = 41,
147 VMEXIT_DR10_READ = 42,
148 VMEXIT_DR11_READ = 43,
149 VMEXIT_DR12_READ = 44,
150 VMEXIT_DR13_READ = 45,
151 VMEXIT_DR14_READ = 46,
152 VMEXIT_DR15_READ = 47,
154 /* debug register write exitcodes */
155 VMEXIT_DR0_WRITE = 48,
156 VMEXIT_DR1_WRITE = 49,
157 VMEXIT_DR2_WRITE = 50,
158 VMEXIT_DR3_WRITE = 51,
159 VMEXIT_DR4_WRITE = 52,
160 VMEXIT_DR5_WRITE = 53,
161 VMEXIT_DR6_WRITE = 54,
162 VMEXIT_DR7_WRITE = 55,
163 VMEXIT_DR8_WRITE = 56,
164 VMEXIT_DR9_WRITE = 57,
165 VMEXIT_DR10_WRITE = 58,
166 VMEXIT_DR11_WRITE = 59,
167 VMEXIT_DR12_WRITE = 60,
168 VMEXIT_DR13_WRITE = 61,
169 VMEXIT_DR14_WRITE = 62,
170 VMEXIT_DR15_WRITE = 63,
172 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
173 VMEXIT_EXCEPTION_DE = 64, /* divide-by-zero-error */
174 VMEXIT_EXCEPTION_DB = 65, /* debug */
175 VMEXIT_EXCEPTION_NMI = 66, /* non-maskable-interrupt */
176 VMEXIT_EXCEPTION_BP = 67, /* breakpoint */
177 VMEXIT_EXCEPTION_OF = 68, /* overflow */
178 VMEXIT_EXCEPTION_BR = 69, /* bound-range */
179 VMEXIT_EXCEPTION_UD = 70, /* invalid-opcode*/
180 VMEXIT_EXCEPTION_NM = 71, /* device-not-available */
181 VMEXIT_EXCEPTION_DF = 72, /* double-fault */
182 VMEXIT_EXCEPTION_09 = 73, /* unsupported (reserved) */
183 VMEXIT_EXCEPTION_TS = 74, /* invalid-tss */
184 VMEXIT_EXCEPTION_NP = 75, /* segment-not-present */
185 VMEXIT_EXCEPTION_SS = 76, /* stack */
186 VMEXIT_EXCEPTION_GP = 77, /* general-protection */
187 VMEXIT_EXCEPTION_PF = 78, /* page-fault */
188 VMEXIT_EXCEPTION_15 = 79, /* reserved */
189 VMEXIT_EXCEPTION_MF = 80, /* x87 floating-point exception-pending */
190 VMEXIT_EXCEPTION_AC = 81, /* alignment-check */
191 VMEXIT_EXCEPTION_MC = 82, /* machine-check */
192 VMEXIT_EXCEPTION_XF = 83, /* simd floating-point */
194 /* exceptions 20-31 (exitcodes 84-95) are reserved */
196 /* ...and the rest of the #VMEXITs */
202 VMEXIT_CR0_SEL_WRITE = 101,
203 VMEXIT_IDTR_READ = 102,
204 VMEXIT_GDTR_READ = 103,
205 VMEXIT_LDTR_READ = 104,
206 VMEXIT_TR_READ = 105,
207 VMEXIT_IDTR_WRITE = 106,
208 VMEXIT_GDTR_WRITE = 107,
209 VMEXIT_LDTR_WRITE = 108,
210 VMEXIT_TR_WRITE = 109,
223 VMEXIT_INVLPGA = 122,
226 VMEXIT_TASK_SWITCH = 125,
227 VMEXIT_FERR_FREEZE = 126,
228 VMEXIT_SHUTDOWN = 127,
230 VMEXIT_VMMCALL = 129,
239 VMEXIT_MONITOR = 138,
241 VMEXIT_MWAIT_CONDITIONAL = 140,
243 VMEXIT_NPF = 1024, /* nested paging fault */
248 CLEAN_BITS_I = 1 << 0,
249 CLEAN_BITS_IOPM = 1 << 1,
250 CLEAN_BITS_ASID = 1 << 2,
251 CLEAN_BITS_TPR = 1 << 3,
252 CLEAN_BITS_NP = 1 << 4,
253 CLEAN_BITS_CRX = 1 << 5,
254 CLEAN_BITS_DRX = 1 << 6,
255 CLEAN_BITS_DT = 1 << 7,
256 CLEAN_BITS_SEG = 1 << 8,
257 CLEAN_BITS_CR2 = 1 << 9,
258 CLEAN_BITS_LBR = 1 << 10,
259 CLEAN_BITS_AVIC = 1 << 11
263 typedef u64 eventinj_t;
264 typedef u64 lbrctrl_t;
267 u32 cr_intercepts; /* offset 0x00 */
268 u32 dr_intercepts; /* offset 0x04 */
269 u32 exception_intercepts; /* offset 0x08 */
270 u32 general1_intercepts; /* offset 0x0C */
271 u32 general2_intercepts; /* offset 0x10 */
272 u32 res01; /* offset 0x14 */
273 u64 res02; /* offset 0x18 */
274 u64 res03; /* offset 0x20 */
275 u64 res04; /* offset 0x28 */
276 u64 res05; /* offset 0x30 */
277 u32 res06; /* offset 0x38 */
278 u16 res06a; /* offset 0x3C */
279 u16 pause_filter_count; /* offset 0x3E */
280 u64 iopm_base_pa; /* offset 0x40 */
281 u64 msrpm_base_pa; /* offset 0x48 */
282 u64 tsc_offset; /* offset 0x50 */
283 u32 guest_asid; /* offset 0x58 */
284 u8 tlb_control; /* offset 0x5C */
286 vintr_t vintr; /* offset 0x60 */
287 u64 interrupt_shadow; /* offset 0x68 */
288 u64 exitcode; /* offset 0x70 */
289 u64 exitinfo1; /* offset 0x78 */
290 u64 exitinfo2; /* offset 0x80 */
291 eventinj_t exitintinfo; /* offset 0x88 */
292 u64 np_enable; /* offset 0x90 */
294 eventinj_t eventinj; /* offset 0xA8 */
295 u64 n_cr3; /* offset 0xB0 */
296 lbrctrl_t lbr_control; /* offset 0xB8 */
297 u64 clean_bits; /* offset 0xC0 */
298 u64 nextrip; /* offset 0xC8 */
299 u8 bytes_fetched; /* offset 0xD0 */
301 u64 res10a[100]; /* offset 0xE0 pad to save area */
303 struct svm_segment es; /* offset 1024 */
304 struct svm_segment cs;
305 struct svm_segment ss;
306 struct svm_segment ds;
307 struct svm_segment fs;
308 struct svm_segment gs;
309 struct svm_segment gdtr;
310 struct svm_segment ldtr;
311 struct svm_segment idtr;
312 struct svm_segment tr;
318 u64 efer; /* offset 1024 + 0xD0 */
320 u64 cr4; /* loffset 1024 + 0x148 */
346 u64 lastbranchfromip;
351 } __attribute__((packed));