ia64/xen-unstable

view xen/include/asm-x86/hvm/svm/vmcb.h @ 15675:66147ca8f9c4

hvm: Define common (across VMX and SVM) set of event types.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Jul 31 10:11:47 2007 +0100 (2007-07-31)
parents 3cf5052ba5e5
children 0f541efbb6d6
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 };
79 /* control register intercepts */
80 enum CRInterceptBits
81 {
82 CR_INTERCEPT_CR0_READ = 1 << 0,
83 CR_INTERCEPT_CR1_READ = 1 << 1,
84 CR_INTERCEPT_CR2_READ = 1 << 2,
85 CR_INTERCEPT_CR3_READ = 1 << 3,
86 CR_INTERCEPT_CR4_READ = 1 << 4,
87 CR_INTERCEPT_CR5_READ = 1 << 5,
88 CR_INTERCEPT_CR6_READ = 1 << 6,
89 CR_INTERCEPT_CR7_READ = 1 << 7,
90 CR_INTERCEPT_CR8_READ = 1 << 8,
91 CR_INTERCEPT_CR9_READ = 1 << 9,
92 CR_INTERCEPT_CR10_READ = 1 << 10,
93 CR_INTERCEPT_CR11_READ = 1 << 11,
94 CR_INTERCEPT_CR12_READ = 1 << 12,
95 CR_INTERCEPT_CR13_READ = 1 << 13,
96 CR_INTERCEPT_CR14_READ = 1 << 14,
97 CR_INTERCEPT_CR15_READ = 1 << 15,
98 CR_INTERCEPT_CR0_WRITE = 1 << 16,
99 CR_INTERCEPT_CR1_WRITE = 1 << 17,
100 CR_INTERCEPT_CR2_WRITE = 1 << 18,
101 CR_INTERCEPT_CR3_WRITE = 1 << 19,
102 CR_INTERCEPT_CR4_WRITE = 1 << 20,
103 CR_INTERCEPT_CR5_WRITE = 1 << 21,
104 CR_INTERCEPT_CR6_WRITE = 1 << 22,
105 CR_INTERCEPT_CR7_WRITE = 1 << 23,
106 CR_INTERCEPT_CR8_WRITE = 1 << 24,
107 CR_INTERCEPT_CR9_WRITE = 1 << 25,
108 CR_INTERCEPT_CR10_WRITE = 1 << 26,
109 CR_INTERCEPT_CR11_WRITE = 1 << 27,
110 CR_INTERCEPT_CR12_WRITE = 1 << 28,
111 CR_INTERCEPT_CR13_WRITE = 1 << 29,
112 CR_INTERCEPT_CR14_WRITE = 1 << 30,
113 CR_INTERCEPT_CR15_WRITE = 1 << 31,
114 };
117 /* debug register intercepts */
118 enum DRInterceptBits
119 {
120 DR_INTERCEPT_DR0_READ = 1 << 0,
121 DR_INTERCEPT_DR1_READ = 1 << 1,
122 DR_INTERCEPT_DR2_READ = 1 << 2,
123 DR_INTERCEPT_DR3_READ = 1 << 3,
124 DR_INTERCEPT_DR4_READ = 1 << 4,
125 DR_INTERCEPT_DR5_READ = 1 << 5,
126 DR_INTERCEPT_DR6_READ = 1 << 6,
127 DR_INTERCEPT_DR7_READ = 1 << 7,
128 DR_INTERCEPT_DR8_READ = 1 << 8,
129 DR_INTERCEPT_DR9_READ = 1 << 9,
130 DR_INTERCEPT_DR10_READ = 1 << 10,
131 DR_INTERCEPT_DR11_READ = 1 << 11,
132 DR_INTERCEPT_DR12_READ = 1 << 12,
133 DR_INTERCEPT_DR13_READ = 1 << 13,
134 DR_INTERCEPT_DR14_READ = 1 << 14,
135 DR_INTERCEPT_DR15_READ = 1 << 15,
136 DR_INTERCEPT_DR0_WRITE = 1 << 16,
137 DR_INTERCEPT_DR1_WRITE = 1 << 17,
138 DR_INTERCEPT_DR2_WRITE = 1 << 18,
139 DR_INTERCEPT_DR3_WRITE = 1 << 19,
140 DR_INTERCEPT_DR4_WRITE = 1 << 20,
141 DR_INTERCEPT_DR5_WRITE = 1 << 21,
142 DR_INTERCEPT_DR6_WRITE = 1 << 22,
143 DR_INTERCEPT_DR7_WRITE = 1 << 23,
144 DR_INTERCEPT_DR8_WRITE = 1 << 24,
145 DR_INTERCEPT_DR9_WRITE = 1 << 25,
146 DR_INTERCEPT_DR10_WRITE = 1 << 26,
147 DR_INTERCEPT_DR11_WRITE = 1 << 27,
148 DR_INTERCEPT_DR12_WRITE = 1 << 28,
149 DR_INTERCEPT_DR13_WRITE = 1 << 29,
150 DR_INTERCEPT_DR14_WRITE = 1 << 30,
151 DR_INTERCEPT_DR15_WRITE = 1 << 31,
152 };
154 /* for lazy save/restore we'd like to intercept all DR writes */
155 #define DR_INTERCEPT_ALL_WRITES \
156 (DR_INTERCEPT_DR0_WRITE|DR_INTERCEPT_DR1_WRITE|DR_INTERCEPT_DR2_WRITE \
157 |DR_INTERCEPT_DR3_WRITE|DR_INTERCEPT_DR4_WRITE|DR_INTERCEPT_DR5_WRITE \
158 |DR_INTERCEPT_DR6_WRITE|DR_INTERCEPT_DR7_WRITE)
161 enum VMEXIT_EXITCODE
162 {
163 /* control register read exitcodes */
164 VMEXIT_CR0_READ = 0,
165 VMEXIT_CR1_READ = 1,
166 VMEXIT_CR2_READ = 2,
167 VMEXIT_CR3_READ = 3,
168 VMEXIT_CR4_READ = 4,
169 VMEXIT_CR5_READ = 5,
170 VMEXIT_CR6_READ = 6,
171 VMEXIT_CR7_READ = 7,
172 VMEXIT_CR8_READ = 8,
173 VMEXIT_CR9_READ = 9,
174 VMEXIT_CR10_READ = 10,
175 VMEXIT_CR11_READ = 11,
176 VMEXIT_CR12_READ = 12,
177 VMEXIT_CR13_READ = 13,
178 VMEXIT_CR14_READ = 14,
179 VMEXIT_CR15_READ = 15,
181 /* control register write exitcodes */
182 VMEXIT_CR0_WRITE = 16,
183 VMEXIT_CR1_WRITE = 17,
184 VMEXIT_CR2_WRITE = 18,
185 VMEXIT_CR3_WRITE = 19,
186 VMEXIT_CR4_WRITE = 20,
187 VMEXIT_CR5_WRITE = 21,
188 VMEXIT_CR6_WRITE = 22,
189 VMEXIT_CR7_WRITE = 23,
190 VMEXIT_CR8_WRITE = 24,
191 VMEXIT_CR9_WRITE = 25,
192 VMEXIT_CR10_WRITE = 26,
193 VMEXIT_CR11_WRITE = 27,
194 VMEXIT_CR12_WRITE = 28,
195 VMEXIT_CR13_WRITE = 29,
196 VMEXIT_CR14_WRITE = 30,
197 VMEXIT_CR15_WRITE = 31,
199 /* debug register read exitcodes */
200 VMEXIT_DR0_READ = 32,
201 VMEXIT_DR1_READ = 33,
202 VMEXIT_DR2_READ = 34,
203 VMEXIT_DR3_READ = 35,
204 VMEXIT_DR4_READ = 36,
205 VMEXIT_DR5_READ = 37,
206 VMEXIT_DR6_READ = 38,
207 VMEXIT_DR7_READ = 39,
208 VMEXIT_DR8_READ = 40,
209 VMEXIT_DR9_READ = 41,
210 VMEXIT_DR10_READ = 42,
211 VMEXIT_DR11_READ = 43,
212 VMEXIT_DR12_READ = 44,
213 VMEXIT_DR13_READ = 45,
214 VMEXIT_DR14_READ = 46,
215 VMEXIT_DR15_READ = 47,
217 /* debug register write exitcodes */
218 VMEXIT_DR0_WRITE = 48,
219 VMEXIT_DR1_WRITE = 49,
220 VMEXIT_DR2_WRITE = 50,
221 VMEXIT_DR3_WRITE = 51,
222 VMEXIT_DR4_WRITE = 52,
223 VMEXIT_DR5_WRITE = 53,
224 VMEXIT_DR6_WRITE = 54,
225 VMEXIT_DR7_WRITE = 55,
226 VMEXIT_DR8_WRITE = 56,
227 VMEXIT_DR9_WRITE = 57,
228 VMEXIT_DR10_WRITE = 58,
229 VMEXIT_DR11_WRITE = 59,
230 VMEXIT_DR12_WRITE = 60,
231 VMEXIT_DR13_WRITE = 61,
232 VMEXIT_DR14_WRITE = 62,
233 VMEXIT_DR15_WRITE = 63,
235 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
236 VMEXIT_EXCEPTION_DE = 64, /* divide-by-zero-error */
237 VMEXIT_EXCEPTION_DB = 65, /* debug */
238 VMEXIT_EXCEPTION_NMI = 66, /* non-maskable-interrupt */
239 VMEXIT_EXCEPTION_BP = 67, /* breakpoint */
240 VMEXIT_EXCEPTION_OF = 68, /* overflow */
241 VMEXIT_EXCEPTION_BR = 69, /* bound-range */
242 VMEXIT_EXCEPTION_UD = 70, /* invalid-opcode*/
243 VMEXIT_EXCEPTION_NM = 71, /* device-not-available */
244 VMEXIT_EXCEPTION_DF = 72, /* double-fault */
245 VMEXIT_EXCEPTION_09 = 73, /* unsupported (reserved) */
246 VMEXIT_EXCEPTION_TS = 74, /* invalid-tss */
247 VMEXIT_EXCEPTION_NP = 75, /* segment-not-present */
248 VMEXIT_EXCEPTION_SS = 76, /* stack */
249 VMEXIT_EXCEPTION_GP = 77, /* general-protection */
250 VMEXIT_EXCEPTION_PF = 78, /* page-fault */
251 VMEXIT_EXCEPTION_15 = 79, /* reserved */
252 VMEXIT_EXCEPTION_MF = 80, /* x87 floating-point exception-pending */
253 VMEXIT_EXCEPTION_AC = 81, /* alignment-check */
254 VMEXIT_EXCEPTION_MC = 82, /* machine-check */
255 VMEXIT_EXCEPTION_XF = 83, /* simd floating-point */
257 /* exceptions 20-31 (exitcodes 84-95) are reserved */
259 /* ...and the rest of the #VMEXITs */
260 VMEXIT_INTR = 96,
261 VMEXIT_NMI = 97,
262 VMEXIT_SMI = 98,
263 VMEXIT_INIT = 99,
264 VMEXIT_VINTR = 100,
265 VMEXIT_CR0_SEL_WRITE = 101,
266 VMEXIT_IDTR_READ = 102,
267 VMEXIT_GDTR_READ = 103,
268 VMEXIT_LDTR_READ = 104,
269 VMEXIT_TR_READ = 105,
270 VMEXIT_IDTR_WRITE = 106,
271 VMEXIT_GDTR_WRITE = 107,
272 VMEXIT_LDTR_WRITE = 108,
273 VMEXIT_TR_WRITE = 109,
274 VMEXIT_RDTSC = 110,
275 VMEXIT_RDPMC = 111,
276 VMEXIT_PUSHF = 112,
277 VMEXIT_POPF = 113,
278 VMEXIT_CPUID = 114,
279 VMEXIT_RSM = 115,
280 VMEXIT_IRET = 116,
281 VMEXIT_SWINT = 117,
282 VMEXIT_INVD = 118,
283 VMEXIT_PAUSE = 119,
284 VMEXIT_HLT = 120,
285 VMEXIT_INVLPG = 121,
286 VMEXIT_INVLPGA = 122,
287 VMEXIT_IOIO = 123,
288 VMEXIT_MSR = 124,
289 VMEXIT_TASK_SWITCH = 125,
290 VMEXIT_FERR_FREEZE = 126,
291 VMEXIT_SHUTDOWN = 127,
292 VMEXIT_VMRUN = 128,
293 VMEXIT_VMMCALL = 129,
294 VMEXIT_VMLOAD = 130,
295 VMEXIT_VMSAVE = 131,
296 VMEXIT_STGI = 132,
297 VMEXIT_CLGI = 133,
298 VMEXIT_SKINIT = 134,
299 VMEXIT_RDTSCP = 135,
300 VMEXIT_ICEBP = 136,
301 VMEXIT_NPF = 1024, /* nested paging fault */
302 VMEXIT_INVALID = -1
303 };
305 /* Definitions of segment state are borrowed by the generic HVM code. */
306 typedef segment_attributes_t svm_segment_attributes_t;
307 typedef segment_register_t 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 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 svm_segment_register_t es; /* offset 1024 */
389 svm_segment_register_t cs;
390 svm_segment_register_t ss;
391 svm_segment_register_t ds;
392 svm_segment_register_t fs;
393 svm_segment_register_t gs;
394 svm_segment_register_t gdtr;
395 svm_segment_register_t ldtr;
396 svm_segment_register_t idtr;
397 svm_segment_register_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 u64 vmcb_pa;
438 u64 asid_generation; /* ASID tracking, moved here to
439 prevent cacheline misses. */
440 u32 *msrpm;
441 int launch_core;
442 bool_t vmcb_in_sync; /* VMCB sync'ed with VMSAVE? */
443 unsigned long cpu_shadow_cr0; /* Guest value for CR0 */
444 unsigned long cpu_shadow_cr4; /* Guest value for CR4 */
445 unsigned long cpu_shadow_efer; /* Guest value for EFER */
446 unsigned long cpu_cr2;
447 unsigned long cpu_cr3;
448 };
450 struct vmcb_struct *alloc_vmcb(void);
451 struct host_save_area *alloc_host_save_area(void);
452 void free_vmcb(struct vmcb_struct *vmcb);
454 int svm_create_vmcb(struct vcpu *v);
455 void svm_destroy_vmcb(struct vcpu *v);
457 void setup_vmcb_dump(void);
459 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
461 /*
462 * Local variables:
463 * mode: C
464 * c-set-style: "BSD"
465 * c-basic-offset: 4
466 * tab-width: 4
467 * indent-tabs-mode: nil
468 * End:
469 */