ia64/xen-unstable

view xen/include/asm-x86/hvm/svm/vmcb.h @ 19648:f0e2df69a8eb

x86 hvm: Allow cross-vendor migration

Intercept #UD and emulate SYSCALL/SYSENTER/SYSEXIT as necessary.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 26 15:01:36 2009 +0100 (2009-05-26)
parents 6bf61b830153
children 87c411a7c1df
line source
1 /*
2 * vmcb.h: VMCB related definitions
3 * Copyright (c) 2005-2007, Advanced Micro Devices, Inc
4 * Copyright (c) 2004, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
18 *
19 */
20 #ifndef __ASM_X86_HVM_SVM_VMCB_H__
21 #define __ASM_X86_HVM_SVM_VMCB_H__
23 #include <asm/config.h>
24 #include <asm/hvm/hvm.h>
27 /* general 1 intercepts */
28 enum GenericIntercept1bits
29 {
30 GENERAL1_INTERCEPT_INTR = 1 << 0,
31 GENERAL1_INTERCEPT_NMI = 1 << 1,
32 GENERAL1_INTERCEPT_SMI = 1 << 2,
33 GENERAL1_INTERCEPT_INIT = 1 << 3,
34 GENERAL1_INTERCEPT_VINTR = 1 << 4,
35 GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
36 GENERAL1_INTERCEPT_IDTR_READ = 1 << 6,
37 GENERAL1_INTERCEPT_GDTR_READ = 1 << 7,
38 GENERAL1_INTERCEPT_LDTR_READ = 1 << 8,
39 GENERAL1_INTERCEPT_TR_READ = 1 << 9,
40 GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10,
41 GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11,
42 GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12,
43 GENERAL1_INTERCEPT_TR_WRITE = 1 << 13,
44 GENERAL1_INTERCEPT_RDTSC = 1 << 14,
45 GENERAL1_INTERCEPT_RDPMC = 1 << 15,
46 GENERAL1_INTERCEPT_PUSHF = 1 << 16,
47 GENERAL1_INTERCEPT_POPF = 1 << 17,
48 GENERAL1_INTERCEPT_CPUID = 1 << 18,
49 GENERAL1_INTERCEPT_RSM = 1 << 19,
50 GENERAL1_INTERCEPT_IRET = 1 << 20,
51 GENERAL1_INTERCEPT_SWINT = 1 << 21,
52 GENERAL1_INTERCEPT_INVD = 1 << 22,
53 GENERAL1_INTERCEPT_PAUSE = 1 << 23,
54 GENERAL1_INTERCEPT_HLT = 1 << 24,
55 GENERAL1_INTERCEPT_INVLPG = 1 << 25,
56 GENERAL1_INTERCEPT_INVLPGA = 1 << 26,
57 GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27,
58 GENERAL1_INTERCEPT_MSR_PROT = 1 << 28,
59 GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29,
60 GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30,
61 GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1 << 31
62 };
64 /* general 2 intercepts */
65 enum GenericIntercept2bits
66 {
67 GENERAL2_INTERCEPT_VMRUN = 1 << 0,
68 GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
69 GENERAL2_INTERCEPT_VMLOAD = 1 << 2,
70 GENERAL2_INTERCEPT_VMSAVE = 1 << 3,
71 GENERAL2_INTERCEPT_STGI = 1 << 4,
72 GENERAL2_INTERCEPT_CLGI = 1 << 5,
73 GENERAL2_INTERCEPT_SKINIT = 1 << 6,
74 GENERAL2_INTERCEPT_RDTSCP = 1 << 7,
75 GENERAL2_INTERCEPT_ICEBP = 1 << 8,
76 GENERAL2_INTERCEPT_WBINVD = 1 << 9,
77 GENERAL2_INTERCEPT_MONITOR = 1 << 10,
78 GENERAL2_INTERCEPT_MWAIT = 1 << 11,
79 GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12
80 };
83 /* control register intercepts */
84 enum CRInterceptBits
85 {
86 CR_INTERCEPT_CR0_READ = 1 << 0,
87 CR_INTERCEPT_CR1_READ = 1 << 1,
88 CR_INTERCEPT_CR2_READ = 1 << 2,
89 CR_INTERCEPT_CR3_READ = 1 << 3,
90 CR_INTERCEPT_CR4_READ = 1 << 4,
91 CR_INTERCEPT_CR5_READ = 1 << 5,
92 CR_INTERCEPT_CR6_READ = 1 << 6,
93 CR_INTERCEPT_CR7_READ = 1 << 7,
94 CR_INTERCEPT_CR8_READ = 1 << 8,
95 CR_INTERCEPT_CR9_READ = 1 << 9,
96 CR_INTERCEPT_CR10_READ = 1 << 10,
97 CR_INTERCEPT_CR11_READ = 1 << 11,
98 CR_INTERCEPT_CR12_READ = 1 << 12,
99 CR_INTERCEPT_CR13_READ = 1 << 13,
100 CR_INTERCEPT_CR14_READ = 1 << 14,
101 CR_INTERCEPT_CR15_READ = 1 << 15,
102 CR_INTERCEPT_CR0_WRITE = 1 << 16,
103 CR_INTERCEPT_CR1_WRITE = 1 << 17,
104 CR_INTERCEPT_CR2_WRITE = 1 << 18,
105 CR_INTERCEPT_CR3_WRITE = 1 << 19,
106 CR_INTERCEPT_CR4_WRITE = 1 << 20,
107 CR_INTERCEPT_CR5_WRITE = 1 << 21,
108 CR_INTERCEPT_CR6_WRITE = 1 << 22,
109 CR_INTERCEPT_CR7_WRITE = 1 << 23,
110 CR_INTERCEPT_CR8_WRITE = 1 << 24,
111 CR_INTERCEPT_CR9_WRITE = 1 << 25,
112 CR_INTERCEPT_CR10_WRITE = 1 << 26,
113 CR_INTERCEPT_CR11_WRITE = 1 << 27,
114 CR_INTERCEPT_CR12_WRITE = 1 << 28,
115 CR_INTERCEPT_CR13_WRITE = 1 << 29,
116 CR_INTERCEPT_CR14_WRITE = 1 << 30,
117 CR_INTERCEPT_CR15_WRITE = 1 << 31,
118 };
121 /* debug register intercepts */
122 enum DRInterceptBits
123 {
124 DR_INTERCEPT_DR0_READ = 1 << 0,
125 DR_INTERCEPT_DR1_READ = 1 << 1,
126 DR_INTERCEPT_DR2_READ = 1 << 2,
127 DR_INTERCEPT_DR3_READ = 1 << 3,
128 DR_INTERCEPT_DR4_READ = 1 << 4,
129 DR_INTERCEPT_DR5_READ = 1 << 5,
130 DR_INTERCEPT_DR6_READ = 1 << 6,
131 DR_INTERCEPT_DR7_READ = 1 << 7,
132 DR_INTERCEPT_DR8_READ = 1 << 8,
133 DR_INTERCEPT_DR9_READ = 1 << 9,
134 DR_INTERCEPT_DR10_READ = 1 << 10,
135 DR_INTERCEPT_DR11_READ = 1 << 11,
136 DR_INTERCEPT_DR12_READ = 1 << 12,
137 DR_INTERCEPT_DR13_READ = 1 << 13,
138 DR_INTERCEPT_DR14_READ = 1 << 14,
139 DR_INTERCEPT_DR15_READ = 1 << 15,
140 DR_INTERCEPT_DR0_WRITE = 1 << 16,
141 DR_INTERCEPT_DR1_WRITE = 1 << 17,
142 DR_INTERCEPT_DR2_WRITE = 1 << 18,
143 DR_INTERCEPT_DR3_WRITE = 1 << 19,
144 DR_INTERCEPT_DR4_WRITE = 1 << 20,
145 DR_INTERCEPT_DR5_WRITE = 1 << 21,
146 DR_INTERCEPT_DR6_WRITE = 1 << 22,
147 DR_INTERCEPT_DR7_WRITE = 1 << 23,
148 DR_INTERCEPT_DR8_WRITE = 1 << 24,
149 DR_INTERCEPT_DR9_WRITE = 1 << 25,
150 DR_INTERCEPT_DR10_WRITE = 1 << 26,
151 DR_INTERCEPT_DR11_WRITE = 1 << 27,
152 DR_INTERCEPT_DR12_WRITE = 1 << 28,
153 DR_INTERCEPT_DR13_WRITE = 1 << 29,
154 DR_INTERCEPT_DR14_WRITE = 1 << 30,
155 DR_INTERCEPT_DR15_WRITE = 1 << 31,
156 };
158 enum VMEXIT_EXITCODE
159 {
160 /* control register read exitcodes */
161 VMEXIT_CR0_READ = 0,
162 VMEXIT_CR1_READ = 1,
163 VMEXIT_CR2_READ = 2,
164 VMEXIT_CR3_READ = 3,
165 VMEXIT_CR4_READ = 4,
166 VMEXIT_CR5_READ = 5,
167 VMEXIT_CR6_READ = 6,
168 VMEXIT_CR7_READ = 7,
169 VMEXIT_CR8_READ = 8,
170 VMEXIT_CR9_READ = 9,
171 VMEXIT_CR10_READ = 10,
172 VMEXIT_CR11_READ = 11,
173 VMEXIT_CR12_READ = 12,
174 VMEXIT_CR13_READ = 13,
175 VMEXIT_CR14_READ = 14,
176 VMEXIT_CR15_READ = 15,
178 /* control register write exitcodes */
179 VMEXIT_CR0_WRITE = 16,
180 VMEXIT_CR1_WRITE = 17,
181 VMEXIT_CR2_WRITE = 18,
182 VMEXIT_CR3_WRITE = 19,
183 VMEXIT_CR4_WRITE = 20,
184 VMEXIT_CR5_WRITE = 21,
185 VMEXIT_CR6_WRITE = 22,
186 VMEXIT_CR7_WRITE = 23,
187 VMEXIT_CR8_WRITE = 24,
188 VMEXIT_CR9_WRITE = 25,
189 VMEXIT_CR10_WRITE = 26,
190 VMEXIT_CR11_WRITE = 27,
191 VMEXIT_CR12_WRITE = 28,
192 VMEXIT_CR13_WRITE = 29,
193 VMEXIT_CR14_WRITE = 30,
194 VMEXIT_CR15_WRITE = 31,
196 /* debug register read exitcodes */
197 VMEXIT_DR0_READ = 32,
198 VMEXIT_DR1_READ = 33,
199 VMEXIT_DR2_READ = 34,
200 VMEXIT_DR3_READ = 35,
201 VMEXIT_DR4_READ = 36,
202 VMEXIT_DR5_READ = 37,
203 VMEXIT_DR6_READ = 38,
204 VMEXIT_DR7_READ = 39,
205 VMEXIT_DR8_READ = 40,
206 VMEXIT_DR9_READ = 41,
207 VMEXIT_DR10_READ = 42,
208 VMEXIT_DR11_READ = 43,
209 VMEXIT_DR12_READ = 44,
210 VMEXIT_DR13_READ = 45,
211 VMEXIT_DR14_READ = 46,
212 VMEXIT_DR15_READ = 47,
214 /* debug register write exitcodes */
215 VMEXIT_DR0_WRITE = 48,
216 VMEXIT_DR1_WRITE = 49,
217 VMEXIT_DR2_WRITE = 50,
218 VMEXIT_DR3_WRITE = 51,
219 VMEXIT_DR4_WRITE = 52,
220 VMEXIT_DR5_WRITE = 53,
221 VMEXIT_DR6_WRITE = 54,
222 VMEXIT_DR7_WRITE = 55,
223 VMEXIT_DR8_WRITE = 56,
224 VMEXIT_DR9_WRITE = 57,
225 VMEXIT_DR10_WRITE = 58,
226 VMEXIT_DR11_WRITE = 59,
227 VMEXIT_DR12_WRITE = 60,
228 VMEXIT_DR13_WRITE = 61,
229 VMEXIT_DR14_WRITE = 62,
230 VMEXIT_DR15_WRITE = 63,
232 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
233 VMEXIT_EXCEPTION_DE = 64, /* divide-by-zero-error */
234 VMEXIT_EXCEPTION_DB = 65, /* debug */
235 VMEXIT_EXCEPTION_NMI = 66, /* non-maskable-interrupt */
236 VMEXIT_EXCEPTION_BP = 67, /* breakpoint */
237 VMEXIT_EXCEPTION_OF = 68, /* overflow */
238 VMEXIT_EXCEPTION_BR = 69, /* bound-range */
239 VMEXIT_EXCEPTION_UD = 70, /* invalid-opcode*/
240 VMEXIT_EXCEPTION_NM = 71, /* device-not-available */
241 VMEXIT_EXCEPTION_DF = 72, /* double-fault */
242 VMEXIT_EXCEPTION_09 = 73, /* unsupported (reserved) */
243 VMEXIT_EXCEPTION_TS = 74, /* invalid-tss */
244 VMEXIT_EXCEPTION_NP = 75, /* segment-not-present */
245 VMEXIT_EXCEPTION_SS = 76, /* stack */
246 VMEXIT_EXCEPTION_GP = 77, /* general-protection */
247 VMEXIT_EXCEPTION_PF = 78, /* page-fault */
248 VMEXIT_EXCEPTION_15 = 79, /* reserved */
249 VMEXIT_EXCEPTION_MF = 80, /* x87 floating-point exception-pending */
250 VMEXIT_EXCEPTION_AC = 81, /* alignment-check */
251 VMEXIT_EXCEPTION_MC = 82, /* machine-check */
252 VMEXIT_EXCEPTION_XF = 83, /* simd floating-point */
254 /* exceptions 20-31 (exitcodes 84-95) are reserved */
256 /* ...and the rest of the #VMEXITs */
257 VMEXIT_INTR = 96,
258 VMEXIT_NMI = 97,
259 VMEXIT_SMI = 98,
260 VMEXIT_INIT = 99,
261 VMEXIT_VINTR = 100,
262 VMEXIT_CR0_SEL_WRITE = 101,
263 VMEXIT_IDTR_READ = 102,
264 VMEXIT_GDTR_READ = 103,
265 VMEXIT_LDTR_READ = 104,
266 VMEXIT_TR_READ = 105,
267 VMEXIT_IDTR_WRITE = 106,
268 VMEXIT_GDTR_WRITE = 107,
269 VMEXIT_LDTR_WRITE = 108,
270 VMEXIT_TR_WRITE = 109,
271 VMEXIT_RDTSC = 110,
272 VMEXIT_RDPMC = 111,
273 VMEXIT_PUSHF = 112,
274 VMEXIT_POPF = 113,
275 VMEXIT_CPUID = 114,
276 VMEXIT_RSM = 115,
277 VMEXIT_IRET = 116,
278 VMEXIT_SWINT = 117,
279 VMEXIT_INVD = 118,
280 VMEXIT_PAUSE = 119,
281 VMEXIT_HLT = 120,
282 VMEXIT_INVLPG = 121,
283 VMEXIT_INVLPGA = 122,
284 VMEXIT_IOIO = 123,
285 VMEXIT_MSR = 124,
286 VMEXIT_TASK_SWITCH = 125,
287 VMEXIT_FERR_FREEZE = 126,
288 VMEXIT_SHUTDOWN = 127,
289 VMEXIT_VMRUN = 128,
290 VMEXIT_VMMCALL = 129,
291 VMEXIT_VMLOAD = 130,
292 VMEXIT_VMSAVE = 131,
293 VMEXIT_STGI = 132,
294 VMEXIT_CLGI = 133,
295 VMEXIT_SKINIT = 134,
296 VMEXIT_RDTSCP = 135,
297 VMEXIT_ICEBP = 136,
298 VMEXIT_WBINVD = 137,
299 VMEXIT_MONITOR = 138,
300 VMEXIT_MWAIT = 139,
301 VMEXIT_MWAIT_CONDITIONAL= 140,
302 VMEXIT_NPF = 1024, /* nested paging fault */
303 VMEXIT_INVALID = -1
304 };
306 /* Definition of segment state is borrowed by the generic HVM code. */
307 typedef struct segment_register svm_segment_register_t;
309 typedef union
310 {
311 u64 bytes;
312 struct
313 {
314 u64 vector: 8;
315 u64 type: 3;
316 u64 ev: 1;
317 u64 resvd1: 19;
318 u64 v: 1;
319 u64 errorcode:32;
320 } fields;
321 } __attribute__ ((packed)) eventinj_t;
323 typedef union
324 {
325 u64 bytes;
326 struct
327 {
328 u64 tpr: 8;
329 u64 irq: 1;
330 u64 rsvd0: 7;
331 u64 prio: 4;
332 u64 ign_tpr: 1;
333 u64 rsvd1: 3;
334 u64 intr_masking: 1;
335 u64 rsvd2: 7;
336 u64 vector: 8;
337 u64 rsvd3: 24;
338 } fields;
339 } __attribute__ ((packed)) vintr_t;
341 typedef union
342 {
343 u64 bytes;
344 struct
345 {
346 u64 type: 1;
347 u64 rsv0: 1;
348 u64 str: 1;
349 u64 rep: 1;
350 u64 sz8: 1;
351 u64 sz16: 1;
352 u64 sz32: 1;
353 u64 rsv1: 9;
354 u64 port: 16;
355 } fields;
356 } __attribute__ ((packed)) ioio_info_t;
358 typedef union
359 {
360 u64 bytes;
361 struct
362 {
363 u64 enable:1;
364 } fields;
365 } __attribute__ ((packed)) lbrctrl_t;
367 struct vmcb_struct {
368 u32 cr_intercepts; /* offset 0x00 */
369 u32 dr_intercepts; /* offset 0x04 */
370 u32 exception_intercepts; /* offset 0x08 */
371 u32 general1_intercepts; /* offset 0x0C */
372 u32 general2_intercepts; /* offset 0x10 */
373 u32 res01; /* offset 0x14 */
374 u64 res02; /* offset 0x18 */
375 u64 res03; /* offset 0x20 */
376 u64 res04; /* offset 0x28 */
377 u64 res05; /* offset 0x30 */
378 u64 res06; /* offset 0x38 */
379 u64 iopm_base_pa; /* offset 0x40 */
380 u64 msrpm_base_pa; /* offset 0x48 */
381 u64 tsc_offset; /* offset 0x50 */
382 u32 guest_asid; /* offset 0x58 */
383 u8 tlb_control; /* offset 0x5C */
384 u8 res07[3];
385 vintr_t vintr; /* offset 0x60 */
386 u64 interrupt_shadow; /* offset 0x68 */
387 u64 exitcode; /* offset 0x70 */
388 u64 exitinfo1; /* offset 0x78 */
389 u64 exitinfo2; /* offset 0x80 */
390 eventinj_t exitintinfo; /* offset 0x88 */
391 u64 np_enable; /* offset 0x90 */
392 u64 res08[2];
393 eventinj_t eventinj; /* offset 0xA8 */
394 u64 h_cr3; /* offset 0xB0 */
395 lbrctrl_t lbr_control; /* offset 0xB8 */
396 u64 res09; /* offset 0xC0 */
397 u64 nextrip; /* offset 0xC8 */
398 u64 res10a[102]; /* offset 0xD0 pad to save area */
400 svm_segment_register_t es; /* offset 1024 */
401 svm_segment_register_t cs;
402 svm_segment_register_t ss;
403 svm_segment_register_t ds;
404 svm_segment_register_t fs;
405 svm_segment_register_t gs;
406 svm_segment_register_t gdtr;
407 svm_segment_register_t ldtr;
408 svm_segment_register_t idtr;
409 svm_segment_register_t tr;
410 u64 res10[5];
411 u8 res11[3];
412 u8 cpl;
413 u32 res12;
414 u64 efer; /* offset 1024 + 0xD0 */
415 u64 res13[14];
416 u64 cr4; /* loffset 1024 + 0x148 */
417 u64 cr3;
418 u64 cr0;
419 u64 dr7;
420 u64 dr6;
421 u64 rflags;
422 u64 rip;
423 u64 res14[11];
424 u64 rsp;
425 u64 res15[3];
426 u64 rax;
427 u64 star;
428 u64 lstar;
429 u64 cstar;
430 u64 sfmask;
431 u64 kerngsbase;
432 u64 sysenter_cs;
433 u64 sysenter_esp;
434 u64 sysenter_eip;
435 u64 cr2;
436 u64 pdpe0;
437 u64 pdpe1;
438 u64 pdpe2;
439 u64 pdpe3;
440 u64 g_pat;
441 u64 debugctlmsr;
442 u64 lastbranchfromip;
443 u64 lastbranchtoip;
444 u64 lastintfromip;
445 u64 lastinttoip;
446 u64 res16[301];
447 } __attribute__ ((packed));
449 struct svm_domain {
450 #if CONFIG_PAGING_LEVELS == 3
451 bool_t npt_4gb_warning;
452 #endif
453 };
455 struct arch_svm_struct {
456 struct vmcb_struct *vmcb;
457 u64 vmcb_pa;
458 u64 asid_generation; /* ASID tracking, moved here for cache locality. */
459 unsigned long *msrpm;
460 int launch_core;
461 bool_t vmcb_in_sync; /* VMCB sync'ed with VMSAVE? */
463 /* Upper four bytes are undefined in the VMCB, therefore we can't
464 * use the fields in the VMCB. Write a 64bit value and then read a 64bit
465 * value is fine unless there's a VMRUN/VMEXIT in between which clears
466 * the upper four bytes.
467 */
468 uint64_t guest_sysenter_cs;
469 uint64_t guest_sysenter_esp;
470 uint64_t guest_sysenter_eip;
471 };
473 struct vmcb_struct *alloc_vmcb(void);
474 struct host_save_area *alloc_host_save_area(void);
475 void free_vmcb(struct vmcb_struct *vmcb);
477 int svm_create_vmcb(struct vcpu *v);
478 void svm_destroy_vmcb(struct vcpu *v);
480 void setup_vmcb_dump(void);
482 void svm_disable_intercept_for_msr(struct vcpu *v, u32 msr);
484 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
486 /*
487 * Local variables:
488 * mode: C
489 * c-set-style: "BSD"
490 * c-basic-offset: 4
491 * tab-width: 4
492 * indent-tabs-mode: nil
493 * End:
494 */