debuggers.hg

view xen/include/asm-x86/hvm/svm/vmcb.h @ 13651:fde9e1d474b7

hvm: Define a global I/O access bitmap, allowing direct access to port 0x80.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Jan 25 18:20:58 2007 +0000 (2007-01-25)
parents baa9b76ea3e1
children 437774e49735
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 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 };
118 /* debug register intercepts */
119 enum DRInterceptBits
120 {
121 DR_INTERCEPT_DR0_READ = 1 << 0,
122 DR_INTERCEPT_DR1_READ = 1 << 1,
123 DR_INTERCEPT_DR2_READ = 1 << 2,
124 DR_INTERCEPT_DR3_READ = 1 << 3,
125 DR_INTERCEPT_DR4_READ = 1 << 4,
126 DR_INTERCEPT_DR5_READ = 1 << 5,
127 DR_INTERCEPT_DR6_READ = 1 << 6,
128 DR_INTERCEPT_DR7_READ = 1 << 7,
129 DR_INTERCEPT_DR8_READ = 1 << 8,
130 DR_INTERCEPT_DR9_READ = 1 << 9,
131 DR_INTERCEPT_DR10_READ = 1 << 10,
132 DR_INTERCEPT_DR11_READ = 1 << 11,
133 DR_INTERCEPT_DR12_READ = 1 << 12,
134 DR_INTERCEPT_DR13_READ = 1 << 13,
135 DR_INTERCEPT_DR14_READ = 1 << 14,
136 DR_INTERCEPT_DR15_READ = 1 << 15,
137 DR_INTERCEPT_DR0_WRITE = 1 << 16,
138 DR_INTERCEPT_DR1_WRITE = 1 << 17,
139 DR_INTERCEPT_DR2_WRITE = 1 << 18,
140 DR_INTERCEPT_DR3_WRITE = 1 << 19,
141 DR_INTERCEPT_DR4_WRITE = 1 << 20,
142 DR_INTERCEPT_DR5_WRITE = 1 << 21,
143 DR_INTERCEPT_DR6_WRITE = 1 << 22,
144 DR_INTERCEPT_DR7_WRITE = 1 << 23,
145 DR_INTERCEPT_DR8_WRITE = 1 << 24,
146 DR_INTERCEPT_DR9_WRITE = 1 << 25,
147 DR_INTERCEPT_DR10_WRITE = 1 << 26,
148 DR_INTERCEPT_DR11_WRITE = 1 << 27,
149 DR_INTERCEPT_DR12_WRITE = 1 << 28,
150 DR_INTERCEPT_DR13_WRITE = 1 << 29,
151 DR_INTERCEPT_DR14_WRITE = 1 << 30,
152 DR_INTERCEPT_DR15_WRITE = 1 << 31,
153 };
155 /* for lazy save/restore we'd like to intercept all DR writes */
156 #define DR_INTERCEPT_ALL_WRITES \
157 (DR_INTERCEPT_DR0_WRITE|DR_INTERCEPT_DR1_WRITE|DR_INTERCEPT_DR2_WRITE \
158 |DR_INTERCEPT_DR3_WRITE|DR_INTERCEPT_DR4_WRITE|DR_INTERCEPT_DR5_WRITE \
159 |DR_INTERCEPT_DR6_WRITE|DR_INTERCEPT_DR7_WRITE)
162 enum VMEXIT_EXITCODE
163 {
164 /* control register read exitcodes */
165 VMEXIT_CR0_READ = 0,
166 VMEXIT_CR1_READ = 1,
167 VMEXIT_CR2_READ = 2,
168 VMEXIT_CR3_READ = 3,
169 VMEXIT_CR4_READ = 4,
170 VMEXIT_CR5_READ = 5,
171 VMEXIT_CR6_READ = 6,
172 VMEXIT_CR7_READ = 7,
173 VMEXIT_CR8_READ = 8,
174 VMEXIT_CR9_READ = 9,
175 VMEXIT_CR10_READ = 10,
176 VMEXIT_CR11_READ = 11,
177 VMEXIT_CR12_READ = 12,
178 VMEXIT_CR13_READ = 13,
179 VMEXIT_CR14_READ = 14,
180 VMEXIT_CR15_READ = 15,
182 /* control register write exitcodes */
183 VMEXIT_CR0_WRITE = 16,
184 VMEXIT_CR1_WRITE = 17,
185 VMEXIT_CR2_WRITE = 18,
186 VMEXIT_CR3_WRITE = 19,
187 VMEXIT_CR4_WRITE = 20,
188 VMEXIT_CR5_WRITE = 21,
189 VMEXIT_CR6_WRITE = 22,
190 VMEXIT_CR7_WRITE = 23,
191 VMEXIT_CR8_WRITE = 24,
192 VMEXIT_CR9_WRITE = 25,
193 VMEXIT_CR10_WRITE = 26,
194 VMEXIT_CR11_WRITE = 27,
195 VMEXIT_CR12_WRITE = 28,
196 VMEXIT_CR13_WRITE = 29,
197 VMEXIT_CR14_WRITE = 30,
198 VMEXIT_CR15_WRITE = 31,
200 /* debug register read exitcodes */
201 VMEXIT_DR0_READ = 32,
202 VMEXIT_DR1_READ = 33,
203 VMEXIT_DR2_READ = 34,
204 VMEXIT_DR3_READ = 35,
205 VMEXIT_DR4_READ = 36,
206 VMEXIT_DR5_READ = 37,
207 VMEXIT_DR6_READ = 38,
208 VMEXIT_DR7_READ = 39,
209 VMEXIT_DR8_READ = 40,
210 VMEXIT_DR9_READ = 41,
211 VMEXIT_DR10_READ = 42,
212 VMEXIT_DR11_READ = 43,
213 VMEXIT_DR12_READ = 44,
214 VMEXIT_DR13_READ = 45,
215 VMEXIT_DR14_READ = 46,
216 VMEXIT_DR15_READ = 47,
218 /* debug register write exitcodes */
219 VMEXIT_DR0_WRITE = 48,
220 VMEXIT_DR1_WRITE = 49,
221 VMEXIT_DR2_WRITE = 50,
222 VMEXIT_DR3_WRITE = 51,
223 VMEXIT_DR4_WRITE = 52,
224 VMEXIT_DR5_WRITE = 53,
225 VMEXIT_DR6_WRITE = 54,
226 VMEXIT_DR7_WRITE = 55,
227 VMEXIT_DR8_WRITE = 56,
228 VMEXIT_DR9_WRITE = 57,
229 VMEXIT_DR10_WRITE = 58,
230 VMEXIT_DR11_WRITE = 59,
231 VMEXIT_DR12_WRITE = 60,
232 VMEXIT_DR13_WRITE = 61,
233 VMEXIT_DR14_WRITE = 62,
234 VMEXIT_DR15_WRITE = 63,
236 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
237 VMEXIT_EXCEPTION_DE = 64, /* divide-by-zero-error */
238 VMEXIT_EXCEPTION_DB = 65, /* debug */
239 VMEXIT_EXCEPTION_NMI = 66, /* non-maskable-interrupt */
240 VMEXIT_EXCEPTION_BP = 67, /* breakpoint */
241 VMEXIT_EXCEPTION_OF = 68, /* overflow */
242 VMEXIT_EXCEPTION_BR = 69, /* bound-range */
243 VMEXIT_EXCEPTION_UD = 70, /* invalid-opcode*/
244 VMEXIT_EXCEPTION_NM = 71, /* device-not-available */
245 VMEXIT_EXCEPTION_DF = 72, /* double-fault */
246 VMEXIT_EXCEPTION_09 = 73, /* unsupported (reserved) */
247 VMEXIT_EXCEPTION_TS = 74, /* invalid-tss */
248 VMEXIT_EXCEPTION_NP = 75, /* segment-not-present */
249 VMEXIT_EXCEPTION_SS = 76, /* stack */
250 VMEXIT_EXCEPTION_GP = 77, /* general-protection */
251 VMEXIT_EXCEPTION_PF = 78, /* page-fault */
252 VMEXIT_EXCEPTION_15 = 79, /* reserved */
253 VMEXIT_EXCEPTION_MF = 80, /* x87 floating-point exception-pending */
254 VMEXIT_EXCEPTION_AC = 81, /* alignment-check */
255 VMEXIT_EXCEPTION_MC = 82, /* machine-check */
256 VMEXIT_EXCEPTION_XF = 83, /* simd floating-point */
258 /* exceptions 20-31 (exitcodes 84-95) are reserved */
260 /* ...and the rest of the #VMEXITs */
261 VMEXIT_INTR = 96,
262 VMEXIT_NMI = 97,
263 VMEXIT_SMI = 98,
264 VMEXIT_INIT = 99,
265 VMEXIT_VINTR = 100,
266 VMEXIT_CR0_SEL_WRITE = 101,
267 VMEXIT_IDTR_READ = 102,
268 VMEXIT_GDTR_READ = 103,
269 VMEXIT_LDTR_READ = 104,
270 VMEXIT_TR_READ = 105,
271 VMEXIT_IDTR_WRITE = 106,
272 VMEXIT_GDTR_WRITE = 107,
273 VMEXIT_LDTR_WRITE = 108,
274 VMEXIT_TR_WRITE = 109,
275 VMEXIT_RDTSC = 110,
276 VMEXIT_RDPMC = 111,
277 VMEXIT_PUSHF = 112,
278 VMEXIT_POPF = 113,
279 VMEXIT_CPUID = 114,
280 VMEXIT_RSM = 115,
281 VMEXIT_IRET = 116,
282 VMEXIT_SWINT = 117,
283 VMEXIT_INVD = 118,
284 VMEXIT_PAUSE = 119,
285 VMEXIT_HLT = 120,
286 VMEXIT_INVLPG = 121,
287 VMEXIT_INVLPGA = 122,
288 VMEXIT_IOIO = 123,
289 VMEXIT_MSR = 124,
290 VMEXIT_TASK_SWITCH = 125,
291 VMEXIT_FERR_FREEZE = 126,
292 VMEXIT_SHUTDOWN = 127,
293 VMEXIT_VMRUN = 128,
294 VMEXIT_VMMCALL = 129,
295 VMEXIT_VMLOAD = 130,
296 VMEXIT_VMSAVE = 131,
297 VMEXIT_STGI = 132,
298 VMEXIT_CLGI = 133,
299 VMEXIT_SKINIT = 134,
300 VMEXIT_RDTSCP = 135,
301 VMEXIT_ICEBP = 136,
302 VMEXIT_NPF = 1024, /* nested paging fault */
303 VMEXIT_INVALID = -1
304 };
306 enum {
307 SVM_CPU_STATE_PG_ENABLED=0,
308 SVM_CPU_STATE_PAE_ENABLED,
309 SVM_CPU_STATE_LME_ENABLED,
310 SVM_CPU_STATE_LMA_ENABLED,
311 SVM_CPU_STATE_ASSIST_ENABLED,
312 };
314 /* Definitions of segment state are borrowed by the generic HVM code. */
315 typedef segment_attributes_t svm_segment_attributes_t;
316 typedef segment_register_t svm_segment_register_t;
318 typedef union
319 {
320 u64 bytes;
321 struct
322 {
323 u64 vector: 8;
324 u64 type: 3;
325 u64 ev: 1;
326 u64 resvd1: 19;
327 u64 v: 1;
328 u64 errorcode:32;
329 } fields;
330 } __attribute__ ((packed)) eventinj_t;
332 enum EVENTTYPES
333 {
334 EVENTTYPE_INTR = 0,
335 EVENTTYPE_NMI = 2,
336 EVENTTYPE_EXCEPTION = 3,
337 EVENTTYPE_SWINT = 4,
338 };
340 typedef union
341 {
342 u64 bytes;
343 struct
344 {
345 u64 tpr: 8;
346 u64 irq: 1;
347 u64 rsvd0: 7;
348 u64 prio: 4;
349 u64 ign_tpr: 1;
350 u64 rsvd1: 3;
351 u64 intr_masking: 1;
352 u64 rsvd2: 7;
353 u64 vector: 8;
354 u64 rsvd3: 24;
355 } fields;
356 } __attribute__ ((packed)) vintr_t;
358 typedef union
359 {
360 u64 bytes;
361 struct
362 {
363 u64 type: 1;
364 u64 rsv0: 1;
365 u64 str: 1;
366 u64 rep: 1;
367 u64 sz8: 1;
368 u64 sz16: 1;
369 u64 sz32: 1;
370 u64 rsv1: 9;
371 u64 port: 16;
372 } fields;
373 } __attribute__ ((packed)) ioio_info_t;
375 struct vmcb_struct {
376 u32 cr_intercepts; /* offset 0x00 */
377 u32 dr_intercepts; /* offset 0x04 */
378 u32 exception_intercepts; /* offset 0x08 */
379 u32 general1_intercepts; /* offset 0x0C */
380 u32 general2_intercepts; /* offset 0x10 */
381 u32 res01; /* offset 0x14 */
382 u64 res02; /* offset 0x18 */
383 u64 res03; /* offset 0x20 */
384 u64 res04; /* offset 0x28 */
385 u64 res05; /* offset 0x30 */
386 u64 res06; /* offset 0x38 */
387 u64 iopm_base_pa; /* offset 0x40 */
388 u64 msrpm_base_pa; /* offset 0x48 */
389 u64 tsc_offset; /* offset 0x50 */
390 u32 guest_asid; /* offset 0x58 */
391 u8 tlb_control; /* offset 0x5C */
392 u8 res07[3];
393 vintr_t vintr; /* offset 0x60 */
394 u64 interrupt_shadow; /* offset 0x68 */
395 u64 exitcode; /* offset 0x70 */
396 u64 exitinfo1; /* offset 0x78 */
397 u64 exitinfo2; /* offset 0x80 */
398 eventinj_t exitintinfo; /* offset 0x88 */
399 u64 np_enable; /* offset 0x90 */
400 u64 res08[2];
401 eventinj_t eventinj; /* offset 0xA8 */
402 u64 h_cr3; /* offset 0xB0 */
403 u64 res09[105]; /* offset 0xB8 pad to save area */
405 svm_segment_register_t es; /* offset 1024 */
406 svm_segment_register_t cs;
407 svm_segment_register_t ss;
408 svm_segment_register_t ds;
409 svm_segment_register_t fs;
410 svm_segment_register_t gs;
411 svm_segment_register_t gdtr;
412 svm_segment_register_t ldtr;
413 svm_segment_register_t idtr;
414 svm_segment_register_t tr;
415 u64 res10[5];
416 u8 res11[3];
417 u8 cpl;
418 u32 res12;
419 u64 efer; /* offset 1024 + 0xD0 */
420 u64 res13[14];
421 u64 cr4; /* loffset 1024 + 0x148 */
422 u64 cr3;
423 u64 cr0;
424 u64 dr7;
425 u64 dr6;
426 u64 rflags;
427 u64 rip;
428 u64 res14[11];
429 u64 rsp;
430 u64 res15[3];
431 u64 rax;
432 u64 star;
433 u64 lstar;
434 u64 cstar;
435 u64 sfmask;
436 u64 kerngsbase;
437 u64 sysenter_cs;
438 u64 sysenter_esp;
439 u64 sysenter_eip;
440 u64 cr2;
441 u64 pdpe0;
442 u64 pdpe1;
443 u64 pdpe2;
444 u64 pdpe3;
445 u64 g_pat;
446 u64 res16[50];
447 u64 res17[128];
448 u64 res18[128];
449 } __attribute__ ((packed));
452 struct arch_svm_struct {
453 struct vmcb_struct *vmcb;
454 u64 vmcb_pa;
455 u32 *msrpm;
456 u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
457 int saved_irq_vector;
458 u32 launch_core;
460 unsigned long flags; /* VMCB flags */
461 unsigned long cpu_shadow_cr0; /* Guest value for CR0 */
462 unsigned long cpu_shadow_cr4; /* Guest value for CR4 */
463 unsigned long cpu_cr2;
464 unsigned long cpu_cr3;
465 unsigned long cpu_state;
466 };
468 struct vmcb_struct *alloc_vmcb(void);
469 struct host_save_area *alloc_host_save_area(void);
470 void free_vmcb(struct vmcb_struct *vmcb);
471 void free_host_save_area(struct host_save_area *hsa);
473 int svm_create_vmcb(struct vcpu *v);
474 void svm_destroy_vmcb(struct vcpu *v);
476 void setup_vmcb_dump(void);
478 /* These bits in the CR4 are owned by the host */
479 #if CONFIG_PAGING_LEVELS >= 3
480 #define SVM_CR4_HOST_MASK (X86_CR4_PAE)
481 #else
482 #define SVM_CR4_HOST_MASK 0
483 #endif
486 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
488 /*
489 * Local variables:
490 * mode: C
491 * c-set-style: "BSD"
492 * c-basic-offset: 4
493 * tab-width: 4
494 * indent-tabs-mode: nil
495 * End:
496 */