ia64/xen-unstable

view xen/include/asm-x86/hvm/svm/vmcb.h @ 9793:d580da01ded7

SVM patch to ensure that PAE bit is set for 32bit guests on 32bit PAE,
by using paging levels>=3 rather than ifdef i386. This patch fixes
the "black screen" hang issue when building w/XEN_TARGET_X86_PAE=y on
32bit.

Tested linux debian and win2003EE guests with pae=1. The linux
guest boots without error, while the windows guest sometimes hits a
bug() in shadow.c. Both VT and SVM encounter the same bug.

Signed-off-by: Tom Woller <thomas.woller@amd.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 20 17:02:42 2006 +0100 (2006-04-20)
parents a376bab39768
children b4361ae1aabc
line source
1 /*
2 * vmcb.h: VMCB related definitions
3 * Copyright (c) 2005, AMD Corporation.
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>
26 extern int start_svm(void);
28 /* general 1 intercepts */
29 enum GenericIntercept1bits
30 {
31 GENERAL1_INTERCEPT_INTR = 1 << 0,
32 GENERAL1_INTERCEPT_NMI = 1 << 1,
33 GENERAL1_INTERCEPT_SMI = 1 << 2,
34 GENERAL1_INTERCEPT_INIT = 1 << 3,
35 GENERAL1_INTERCEPT_VINTR = 1 << 4,
36 GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
37 GENERAL1_INTERCEPT_IDTR_READ = 1 << 6,
38 GENERAL1_INTERCEPT_GDTR_READ = 1 << 7,
39 GENERAL1_INTERCEPT_LDTR_READ = 1 << 8,
40 GENERAL1_INTERCEPT_TR_READ = 1 << 9,
41 GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10,
42 GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11,
43 GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12,
44 GENERAL1_INTERCEPT_TR_WRITE = 1 << 13,
45 GENERAL1_INTERCEPT_RDTSC = 1 << 14,
46 GENERAL1_INTERCEPT_RDPMC = 1 << 15,
47 GENERAL1_INTERCEPT_PUSHF = 1 << 16,
48 GENERAL1_INTERCEPT_POPF = 1 << 17,
49 GENERAL1_INTERCEPT_CPUID = 1 << 18,
50 GENERAL1_INTERCEPT_RSM = 1 << 19,
51 GENERAL1_INTERCEPT_IRET = 1 << 20,
52 GENERAL1_INTERCEPT_SWINT = 1 << 21,
53 GENERAL1_INTERCEPT_INVD = 1 << 22,
54 GENERAL1_INTERCEPT_PAUSE = 1 << 23,
55 GENERAL1_INTERCEPT_HLT = 1 << 24,
56 GENERAL1_INTERCEPT_INVLPG = 1 << 25,
57 GENERAL1_INTERCEPT_INVLPGA = 1 << 26,
58 GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27,
59 GENERAL1_INTERCEPT_MSR_PROT = 1 << 28,
60 GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29,
61 GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30,
62 GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1 << 31
63 };
65 /* general 2 intercepts */
66 enum GenericIntercept2bits
67 {
68 GENERAL2_INTERCEPT_VMRUN = 1 << 0,
69 GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
70 GENERAL2_INTERCEPT_VMLOAD = 1 << 2,
71 GENERAL2_INTERCEPT_VMSAVE = 1 << 3,
72 GENERAL2_INTERCEPT_STGI = 1 << 4,
73 GENERAL2_INTERCEPT_CLGI = 1 << 5,
74 GENERAL2_INTERCEPT_SKINIT = 1 << 6,
75 GENERAL2_INTERCEPT_RDTSCP = 1 << 7,
76 GENERAL2_INTERCEPT_ICEBP = 1 << 8
77 };
80 /* control register intercepts */
81 enum CRInterceptBits
82 {
83 CR_INTERCEPT_CR0_READ = 1 << 0,
84 CR_INTERCEPT_CR1_READ = 1 << 1,
85 CR_INTERCEPT_CR2_READ = 1 << 2,
86 CR_INTERCEPT_CR3_READ = 1 << 3,
87 CR_INTERCEPT_CR4_READ = 1 << 4,
88 CR_INTERCEPT_CR5_READ = 1 << 5,
89 CR_INTERCEPT_CR6_READ = 1 << 6,
90 CR_INTERCEPT_CR7_READ = 1 << 7,
91 CR_INTERCEPT_CR8_READ = 1 << 8,
92 CR_INTERCEPT_CR9_READ = 1 << 9,
93 CR_INTERCEPT_CR10_READ = 1 << 10,
94 CR_INTERCEPT_CR11_READ = 1 << 11,
95 CR_INTERCEPT_CR12_READ = 1 << 12,
96 CR_INTERCEPT_CR13_READ = 1 << 13,
97 CR_INTERCEPT_CR14_READ = 1 << 14,
98 CR_INTERCEPT_CR15_READ = 1 << 15,
99 CR_INTERCEPT_CR0_WRITE = 1 << 16,
100 CR_INTERCEPT_CR1_WRITE = 1 << 17,
101 CR_INTERCEPT_CR2_WRITE = 1 << 18,
102 CR_INTERCEPT_CR3_WRITE = 1 << 19,
103 CR_INTERCEPT_CR4_WRITE = 1 << 20,
104 CR_INTERCEPT_CR5_WRITE = 1 << 21,
105 CR_INTERCEPT_CR6_WRITE = 1 << 22,
106 CR_INTERCEPT_CR7_WRITE = 1 << 23,
107 CR_INTERCEPT_CR8_WRITE = 1 << 24,
108 CR_INTERCEPT_CR9_WRITE = 1 << 25,
109 CR_INTERCEPT_CR10_WRITE = 1 << 26,
110 CR_INTERCEPT_CR11_WRITE = 1 << 27,
111 CR_INTERCEPT_CR12_WRITE = 1 << 28,
112 CR_INTERCEPT_CR13_WRITE = 1 << 29,
113 CR_INTERCEPT_CR14_WRITE = 1 << 30,
114 CR_INTERCEPT_CR15_WRITE = 1 << 31,
115 };
117 enum VMEXIT_EXITCODE
118 {
119 /* control register read exitcodes */
120 VMEXIT_CR0_READ = 0,
121 VMEXIT_CR1_READ = 1,
122 VMEXIT_CR2_READ = 2,
123 VMEXIT_CR3_READ = 3,
124 VMEXIT_CR4_READ = 4,
125 VMEXIT_CR5_READ = 5,
126 VMEXIT_CR6_READ = 6,
127 VMEXIT_CR7_READ = 7,
128 VMEXIT_CR8_READ = 8,
129 VMEXIT_CR9_READ = 9,
130 VMEXIT_CR10_READ = 10,
131 VMEXIT_CR11_READ = 11,
132 VMEXIT_CR12_READ = 12,
133 VMEXIT_CR13_READ = 13,
134 VMEXIT_CR14_READ = 14,
135 VMEXIT_CR15_READ = 15,
137 /* control register write exitcodes */
138 VMEXIT_CR0_WRITE = 16,
139 VMEXIT_CR1_WRITE = 17,
140 VMEXIT_CR2_WRITE = 18,
141 VMEXIT_CR3_WRITE = 19,
142 VMEXIT_CR4_WRITE = 20,
143 VMEXIT_CR5_WRITE = 21,
144 VMEXIT_CR6_WRITE = 22,
145 VMEXIT_CR7_WRITE = 23,
146 VMEXIT_CR8_WRITE = 24,
147 VMEXIT_CR9_WRITE = 25,
148 VMEXIT_CR10_WRITE = 26,
149 VMEXIT_CR11_WRITE = 27,
150 VMEXIT_CR12_WRITE = 28,
151 VMEXIT_CR13_WRITE = 29,
152 VMEXIT_CR14_WRITE = 30,
153 VMEXIT_CR15_WRITE = 31,
155 /* debug register read exitcodes */
156 VMEXIT_DR0_READ = 32,
157 VMEXIT_DR1_READ = 33,
158 VMEXIT_DR2_READ = 34,
159 VMEXIT_DR3_READ = 35,
160 VMEXIT_DR4_READ = 36,
161 VMEXIT_DR5_READ = 37,
162 VMEXIT_DR6_READ = 38,
163 VMEXIT_DR7_READ = 39,
164 VMEXIT_DR8_READ = 40,
165 VMEXIT_DR9_READ = 41,
166 VMEXIT_DR10_READ = 42,
167 VMEXIT_DR11_READ = 43,
168 VMEXIT_DR12_READ = 44,
169 VMEXIT_DR13_READ = 45,
170 VMEXIT_DR14_READ = 46,
171 VMEXIT_DR15_READ = 47,
173 /* debug register write exitcodes */
174 VMEXIT_DR0_WRITE = 48,
175 VMEXIT_DR1_WRITE = 49,
176 VMEXIT_DR2_WRITE = 50,
177 VMEXIT_DR3_WRITE = 51,
178 VMEXIT_DR4_WRITE = 52,
179 VMEXIT_DR5_WRITE = 53,
180 VMEXIT_DR6_WRITE = 54,
181 VMEXIT_DR7_WRITE = 55,
182 VMEXIT_DR8_WRITE = 56,
183 VMEXIT_DR9_WRITE = 57,
184 VMEXIT_DR10_WRITE = 58,
185 VMEXIT_DR11_WRITE = 59,
186 VMEXIT_DR12_WRITE = 60,
187 VMEXIT_DR13_WRITE = 61,
188 VMEXIT_DR14_WRITE = 62,
189 VMEXIT_DR15_WRITE = 63,
191 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
192 VMEXIT_EXCEPTION_DE = 64, /* divide-by-zero-error */
193 VMEXIT_EXCEPTION_DB = 65, /* debug */
194 VMEXIT_EXCEPTION_NMI = 66, /* non-maskable-interrupt */
195 VMEXIT_EXCEPTION_BP = 67, /* breakpoint */
196 VMEXIT_EXCEPTION_OF = 68, /* overflow */
197 VMEXIT_EXCEPTION_BR = 69, /* bound-range */
198 VMEXIT_EXCEPTION_UD = 70, /* invalid-opcode*/
199 VMEXIT_EXCEPTION_NM = 71, /* device-not-available */
200 VMEXIT_EXCEPTION_DF = 72, /* double-fault */
201 VMEXIT_EXCEPTION_09 = 73, /* unsupported (reserved) */
202 VMEXIT_EXCEPTION_TS = 74, /* invalid-tss */
203 VMEXIT_EXCEPTION_NP = 75, /* segment-not-present */
204 VMEXIT_EXCEPTION_SS = 76, /* stack */
205 VMEXIT_EXCEPTION_GP = 77, /* general-protection */
206 VMEXIT_EXCEPTION_PF = 78, /* page-fault */
207 VMEXIT_EXCEPTION_15 = 79, /* reserved */
208 VMEXIT_EXCEPTION_MF = 80, /* x87 floating-point exception-pending */
209 VMEXIT_EXCEPTION_AC = 81, /* alignment-check */
210 VMEXIT_EXCEPTION_MC = 82, /* machine-check */
211 VMEXIT_EXCEPTION_XF = 83, /* simd floating-point */
213 /* exceptions 20-31 (exitcodes 84-95) are reserved */
215 /* ...and the rest of the #VMEXITs */
216 VMEXIT_INTR = 96,
217 VMEXIT_NMI = 97,
218 VMEXIT_SMI = 98,
219 VMEXIT_INIT = 99,
220 VMEXIT_VINTR = 100,
221 VMEXIT_CR0_SEL_WRITE = 101,
222 VMEXIT_IDTR_READ = 102,
223 VMEXIT_GDTR_READ = 103,
224 VMEXIT_LDTR_READ = 104,
225 VMEXIT_TR_READ = 105,
226 VMEXIT_IDTR_WRITE = 106,
227 VMEXIT_GDTR_WRITE = 107,
228 VMEXIT_LDTR_WRITE = 108,
229 VMEXIT_TR_WRITE = 109,
230 VMEXIT_RDTSC = 110,
231 VMEXIT_RDPMC = 111,
232 VMEXIT_PUSHF = 112,
233 VMEXIT_POPF = 113,
234 VMEXIT_CPUID = 114,
235 VMEXIT_RSM = 115,
236 VMEXIT_IRET = 116,
237 VMEXIT_SWINT = 117,
238 VMEXIT_INVD = 118,
239 VMEXIT_PAUSE = 119,
240 VMEXIT_HLT = 120,
241 VMEXIT_INVLPG = 121,
242 VMEXIT_INVLPGA = 122,
243 VMEXIT_IOIO = 123,
244 VMEXIT_MSR = 124,
245 VMEXIT_TASK_SWITCH = 125,
246 VMEXIT_FERR_FREEZE = 126,
247 VMEXIT_SHUTDOWN = 127,
248 VMEXIT_VMRUN = 128,
249 VMEXIT_VMMCALL = 129,
250 VMEXIT_VMLOAD = 130,
251 VMEXIT_VMSAVE = 131,
252 VMEXIT_STGI = 132,
253 VMEXIT_CLGI = 133,
254 VMEXIT_SKINIT = 134,
255 VMEXIT_RDTSCP = 135,
256 VMEXIT_ICEBP = 136,
257 VMEXIT_NPF = 1024, /* nested paging fault */
258 VMEXIT_INVALID = -1
259 };
261 enum {
262 SVM_CPU_STATE_PG_ENABLED=0,
263 SVM_CPU_STATE_PAE_ENABLED,
264 SVM_CPU_STATE_LME_ENABLED,
265 SVM_CPU_STATE_LMA_ENABLED,
266 SVM_CPU_STATE_ASSIST_ENABLED,
267 };
269 #define SVM_LONG_GUEST(ed) \
270 (test_bit(SVM_CPU_STATE_LMA_ENABLED, &ed->arch.hvm_svm.cpu_state))
273 /*
274 * Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the
275 * segment descriptor.
276 */
277 typedef union
278 {
279 u16 bytes;
280 struct
281 {
282 u16 type:4; /* 0; Bit 40-43 */
283 u16 s: 1; /* 4; Bit 44 */
284 u16 dpl: 2; /* 5; Bit 45-46 */
285 u16 p: 1; /* 7; Bit 47 */
286 u16 avl: 1; /* 8; Bit 52 */
287 u16 l: 1; /* 9; Bit 53 */
288 u16 db: 1; /* 10; Bit 54 */
289 u16 g: 1; /* 11; Bit 55 */
290 } fields;
291 } __attribute__ ((packed)) segment_attributes_t;
293 typedef struct
294 {
295 u16 sel;
296 segment_attributes_t attributes;
297 u32 limit;
298 u64 base;
299 } __attribute__ ((packed)) segment_selector_t;
301 typedef union
302 {
303 u64 bytes;
304 struct
305 {
306 u64 vector: 8;
307 u64 type: 3;
308 u64 ev: 1;
309 u64 resvd1: 19;
310 u64 v: 1;
311 u64 errorcode:32;
312 } fields;
313 } __attribute__ ((packed)) eventinj_t;
315 enum EVENTTYPES
316 {
317 EVENTTYPE_INTR = 0,
318 EVENTTYPE_NMI = 2,
319 EVENTTYPE_EXCEPTION = 3,
320 EVENTTYPE_SWINT = 4,
321 };
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 struct vmcb_struct {
359 u32 cr_intercepts; /* offset 0x00 */
360 u32 dr_intercepts; /* offset 0x04 */
361 u32 exception_intercepts; /* offset 0x08 */
362 u32 general1_intercepts; /* offset 0x0C */
363 u32 general2_intercepts; /* offset 0x10 */
364 u32 res01; /* offset 0x14 */
365 u64 res02; /* offset 0x18 */
366 u64 res03; /* offset 0x20 */
367 u64 res04; /* offset 0x28 */
368 u64 res05; /* offset 0x30 */
369 u64 res06; /* offset 0x38 */
370 u64 iopm_base_pa; /* offset 0x40 */
371 u64 msrpm_base_pa; /* offset 0x48 */
372 u64 tsc_offset; /* offset 0x50 */
373 u32 guest_asid; /* offset 0x58 */
374 u8 tlb_control; /* offset 0x5C */
375 u8 res07[3];
376 vintr_t vintr; /* offset 0x60 */
377 u64 interrupt_shadow; /* offset 0x68 */
378 u64 exitcode; /* offset 0x70 */
379 u64 exitinfo1; /* offset 0x78 */
380 u64 exitinfo2; /* offset 0x80 */
381 eventinj_t exitintinfo; /* offset 0x88 */
382 u64 np_enable; /* offset 0x90 */
383 u64 res08[2];
384 eventinj_t eventinj; /* offset 0xA8 */
385 u64 h_cr3; /* offset 0xB0 */
386 u64 res09[105]; /* offset 0xB8 pad to save area */
388 segment_selector_t es; /* offset 1024 */
389 segment_selector_t cs;
390 segment_selector_t ss;
391 segment_selector_t ds;
392 segment_selector_t fs;
393 segment_selector_t gs;
394 segment_selector_t gdtr;
395 segment_selector_t ldtr;
396 segment_selector_t idtr;
397 segment_selector_t tr;
398 u64 res10[5];
399 u8 res11[3];
400 u8 cpl;
401 u32 res12;
402 u64 efer; /* offset 1024 + 0xD0 */
403 u64 res13[14];
404 u64 cr4; /* loffset 1024 + 0x148 */
405 u64 cr3;
406 u64 cr0;
407 u64 dr7;
408 u64 dr6;
409 u64 rflags;
410 u64 rip;
411 u64 res14[11];
412 u64 rsp;
413 u64 res15[3];
414 u64 rax;
415 u64 star;
416 u64 lstar;
417 u64 cstar;
418 u64 sfmask;
419 u64 kerngsbase;
420 u64 sysenter_cs;
421 u64 sysenter_esp;
422 u64 sysenter_eip;
423 u64 cr2;
424 u64 pdpe0;
425 u64 pdpe1;
426 u64 pdpe2;
427 u64 pdpe3;
428 u64 g_pat;
429 u64 res16[50];
430 u64 res17[128];
431 u64 res18[128];
432 } __attribute__ ((packed));
435 struct arch_svm_struct {
436 struct vmcb_struct *vmcb;
437 void *host_save_area;
438 u64 host_save_pa;
439 u64 vmcb_pa;
440 u32 *iopm;
441 u32 *msrpm;
442 u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
443 int injecting_event;
444 int saved_irq_vector;
445 u32 launch_core;
446 u32 asid_core;
448 unsigned long flags; /* VMCB flags */
449 unsigned long cpu_shadow_cr0; /* Guest value for CR0 */
450 unsigned long cpu_shadow_cr4; /* Guest value for CR4 */
451 unsigned long cpu_cr2;
452 unsigned long cpu_cr3;
453 unsigned long cpu_state;
454 struct timer hlt_timer; /* hlt ins emulation wakeup timer */
455 };
457 struct vmcb_struct *alloc_vmcb(void);
458 struct host_save_area *alloc_host_save_area(void);
459 void free_vmcb(struct vmcb_struct *vmcb);
460 void free_host_save_area(struct host_save_area *hsa);
461 void dump_vmcb(void);
462 int construct_vmcb(struct arch_svm_struct *, struct cpu_user_regs *);
464 #define VMCB_USE_HOST_ENV 1
465 #define VMCB_USE_SEPARATE_ENV 0
467 enum {
468 ARCH_SVM_VMCB_LOADED = 0,
469 ARCH_SVM_VMCB_ASSIGN_ASID
470 };
472 #define VMCB_EFLAGS_RESERVED_0 0xffc08028 /* bitmap for 0 */
473 #define VMCB_EFLAGS_RESERVED_1 0x00000002 /* bitmap for 1 */
475 /* These bits in the CR4 are owned by the host */
476 #if CONFIG_PAGING_LEVELS >= 3
477 #define SVM_CR4_HOST_MASK (X86_CR4_PAE)
478 #else
479 #define SVM_CR4_HOST_MASK 0
480 #endif
483 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
485 /*
486 * Local variables:
487 * mode: C
488 * c-set-style: "BSD"
489 * c-basic-offset: 4
490 * tab-width: 4
491 * indent-tabs-mode: nil
492 * End:
493 */