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, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 #ifndef __ASM_X86_HVM_SVM_VMCB_H__
20 #define __ASM_X86_HVM_SVM_VMCB_H__
21 
22 #include <xen/types.h>
23 
24 /* general 1 intercepts */
25 enum GenericIntercept1bits
26 {
27     GENERAL1_INTERCEPT_INTR          = 1 << 0,
28     GENERAL1_INTERCEPT_NMI           = 1 << 1,
29     GENERAL1_INTERCEPT_SMI           = 1 << 2,
30     GENERAL1_INTERCEPT_INIT          = 1 << 3,
31     GENERAL1_INTERCEPT_VINTR         = 1 << 4,
32     GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
33     GENERAL1_INTERCEPT_IDTR_READ     = 1 << 6,
34     GENERAL1_INTERCEPT_GDTR_READ     = 1 << 7,
35     GENERAL1_INTERCEPT_LDTR_READ     = 1 << 8,
36     GENERAL1_INTERCEPT_TR_READ       = 1 << 9,
37     GENERAL1_INTERCEPT_IDTR_WRITE    = 1 << 10,
38     GENERAL1_INTERCEPT_GDTR_WRITE    = 1 << 11,
39     GENERAL1_INTERCEPT_LDTR_WRITE    = 1 << 12,
40     GENERAL1_INTERCEPT_TR_WRITE      = 1 << 13,
41     GENERAL1_INTERCEPT_RDTSC         = 1 << 14,
42     GENERAL1_INTERCEPT_RDPMC         = 1 << 15,
43     GENERAL1_INTERCEPT_PUSHF         = 1 << 16,
44     GENERAL1_INTERCEPT_POPF          = 1 << 17,
45     GENERAL1_INTERCEPT_CPUID         = 1 << 18,
46     GENERAL1_INTERCEPT_RSM           = 1 << 19,
47     GENERAL1_INTERCEPT_IRET          = 1 << 20,
48     GENERAL1_INTERCEPT_SWINT         = 1 << 21,
49     GENERAL1_INTERCEPT_INVD          = 1 << 22,
50     GENERAL1_INTERCEPT_PAUSE         = 1 << 23,
51     GENERAL1_INTERCEPT_HLT           = 1 << 24,
52     GENERAL1_INTERCEPT_INVLPG        = 1 << 25,
53     GENERAL1_INTERCEPT_INVLPGA       = 1 << 26,
54     GENERAL1_INTERCEPT_IOIO_PROT     = 1 << 27,
55     GENERAL1_INTERCEPT_MSR_PROT      = 1 << 28,
56     GENERAL1_INTERCEPT_TASK_SWITCH   = 1 << 29,
57     GENERAL1_INTERCEPT_FERR_FREEZE   = 1 << 30,
58     GENERAL1_INTERCEPT_SHUTDOWN_EVT  = 1 << 31
59 };
60 
61 /* general 2 intercepts */
62 enum GenericIntercept2bits
63 {
64     GENERAL2_INTERCEPT_VMRUN   = 1 << 0,
65     GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
66     GENERAL2_INTERCEPT_VMLOAD  = 1 << 2,
67     GENERAL2_INTERCEPT_VMSAVE  = 1 << 3,
68     GENERAL2_INTERCEPT_STGI    = 1 << 4,
69     GENERAL2_INTERCEPT_CLGI    = 1 << 5,
70     GENERAL2_INTERCEPT_SKINIT  = 1 << 6,
71     GENERAL2_INTERCEPT_RDTSCP  = 1 << 7,
72     GENERAL2_INTERCEPT_ICEBP   = 1 << 8,
73     GENERAL2_INTERCEPT_WBINVD  = 1 << 9,
74     GENERAL2_INTERCEPT_MONITOR = 1 << 10,
75     GENERAL2_INTERCEPT_MWAIT   = 1 << 11,
76     GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12,
77     GENERAL2_INTERCEPT_XSETBV  = 1 << 13
78 };
79 
80 
81 /* control register intercepts */
82 enum CRInterceptBits
83 {
84     CR_INTERCEPT_CR0_READ   = 1 << 0,
85     CR_INTERCEPT_CR1_READ   = 1 << 1,
86     CR_INTERCEPT_CR2_READ   = 1 << 2,
87     CR_INTERCEPT_CR3_READ   = 1 << 3,
88     CR_INTERCEPT_CR4_READ   = 1 << 4,
89     CR_INTERCEPT_CR5_READ   = 1 << 5,
90     CR_INTERCEPT_CR6_READ   = 1 << 6,
91     CR_INTERCEPT_CR7_READ   = 1 << 7,
92     CR_INTERCEPT_CR8_READ   = 1 << 8,
93     CR_INTERCEPT_CR9_READ   = 1 << 9,
94     CR_INTERCEPT_CR10_READ  = 1 << 10,
95     CR_INTERCEPT_CR11_READ  = 1 << 11,
96     CR_INTERCEPT_CR12_READ  = 1 << 12,
97     CR_INTERCEPT_CR13_READ  = 1 << 13,
98     CR_INTERCEPT_CR14_READ  = 1 << 14,
99     CR_INTERCEPT_CR15_READ  = 1 << 15,
100     CR_INTERCEPT_CR0_WRITE  = 1 << 16,
101     CR_INTERCEPT_CR1_WRITE  = 1 << 17,
102     CR_INTERCEPT_CR2_WRITE  = 1 << 18,
103     CR_INTERCEPT_CR3_WRITE  = 1 << 19,
104     CR_INTERCEPT_CR4_WRITE  = 1 << 20,
105     CR_INTERCEPT_CR5_WRITE  = 1 << 21,
106     CR_INTERCEPT_CR6_WRITE  = 1 << 22,
107     CR_INTERCEPT_CR7_WRITE  = 1 << 23,
108     CR_INTERCEPT_CR8_WRITE  = 1 << 24,
109     CR_INTERCEPT_CR9_WRITE  = 1 << 25,
110     CR_INTERCEPT_CR10_WRITE = 1 << 26,
111     CR_INTERCEPT_CR11_WRITE = 1 << 27,
112     CR_INTERCEPT_CR12_WRITE = 1 << 28,
113     CR_INTERCEPT_CR13_WRITE = 1 << 29,
114     CR_INTERCEPT_CR14_WRITE = 1 << 30,
115     CR_INTERCEPT_CR15_WRITE = 1 << 31,
116 };
117 
118 
119 /* debug register intercepts */
120 enum DRInterceptBits
121 {
122     DR_INTERCEPT_DR0_READ   = 1 << 0,
123     DR_INTERCEPT_DR1_READ   = 1 << 1,
124     DR_INTERCEPT_DR2_READ   = 1 << 2,
125     DR_INTERCEPT_DR3_READ   = 1 << 3,
126     DR_INTERCEPT_DR4_READ   = 1 << 4,
127     DR_INTERCEPT_DR5_READ   = 1 << 5,
128     DR_INTERCEPT_DR6_READ   = 1 << 6,
129     DR_INTERCEPT_DR7_READ   = 1 << 7,
130     DR_INTERCEPT_DR8_READ   = 1 << 8,
131     DR_INTERCEPT_DR9_READ   = 1 << 9,
132     DR_INTERCEPT_DR10_READ  = 1 << 10,
133     DR_INTERCEPT_DR11_READ  = 1 << 11,
134     DR_INTERCEPT_DR12_READ  = 1 << 12,
135     DR_INTERCEPT_DR13_READ  = 1 << 13,
136     DR_INTERCEPT_DR14_READ  = 1 << 14,
137     DR_INTERCEPT_DR15_READ  = 1 << 15,
138     DR_INTERCEPT_DR0_WRITE  = 1 << 16,
139     DR_INTERCEPT_DR1_WRITE  = 1 << 17,
140     DR_INTERCEPT_DR2_WRITE  = 1 << 18,
141     DR_INTERCEPT_DR3_WRITE  = 1 << 19,
142     DR_INTERCEPT_DR4_WRITE  = 1 << 20,
143     DR_INTERCEPT_DR5_WRITE  = 1 << 21,
144     DR_INTERCEPT_DR6_WRITE  = 1 << 22,
145     DR_INTERCEPT_DR7_WRITE  = 1 << 23,
146     DR_INTERCEPT_DR8_WRITE  = 1 << 24,
147     DR_INTERCEPT_DR9_WRITE  = 1 << 25,
148     DR_INTERCEPT_DR10_WRITE = 1 << 26,
149     DR_INTERCEPT_DR11_WRITE = 1 << 27,
150     DR_INTERCEPT_DR12_WRITE = 1 << 28,
151     DR_INTERCEPT_DR13_WRITE = 1 << 29,
152     DR_INTERCEPT_DR14_WRITE = 1 << 30,
153     DR_INTERCEPT_DR15_WRITE = 1 << 31,
154 };
155 
156 enum VMEXIT_EXITCODE
157 {
158     /* control register read exitcodes */
159     VMEXIT_CR0_READ    =   0, /* 0x0 */
160     VMEXIT_CR1_READ    =   1, /* 0x1 */
161     VMEXIT_CR2_READ    =   2, /* 0x2 */
162     VMEXIT_CR3_READ    =   3, /* 0x3 */
163     VMEXIT_CR4_READ    =   4, /* 0x4 */
164     VMEXIT_CR5_READ    =   5, /* 0x5 */
165     VMEXIT_CR6_READ    =   6, /* 0x6 */
166     VMEXIT_CR7_READ    =   7, /* 0x7 */
167     VMEXIT_CR8_READ    =   8, /* 0x8 */
168     VMEXIT_CR9_READ    =   9, /* 0x9 */
169     VMEXIT_CR10_READ   =  10, /* 0xa */
170     VMEXIT_CR11_READ   =  11, /* 0xb */
171     VMEXIT_CR12_READ   =  12, /* 0xc */
172     VMEXIT_CR13_READ   =  13, /* 0xd */
173     VMEXIT_CR14_READ   =  14, /* 0xe */
174     VMEXIT_CR15_READ   =  15, /* 0xf */
175 
176     /* control register write exitcodes */
177     VMEXIT_CR0_WRITE   =  16, /* 0x10 */
178     VMEXIT_CR1_WRITE   =  17, /* 0x11 */
179     VMEXIT_CR2_WRITE   =  18, /* 0x12 */
180     VMEXIT_CR3_WRITE   =  19, /* 0x13 */
181     VMEXIT_CR4_WRITE   =  20, /* 0x14 */
182     VMEXIT_CR5_WRITE   =  21, /* 0x15 */
183     VMEXIT_CR6_WRITE   =  22, /* 0x16 */
184     VMEXIT_CR7_WRITE   =  23, /* 0x17 */
185     VMEXIT_CR8_WRITE   =  24, /* 0x18 */
186     VMEXIT_CR9_WRITE   =  25, /* 0x19 */
187     VMEXIT_CR10_WRITE  =  26, /* 0x1a */
188     VMEXIT_CR11_WRITE  =  27, /* 0x1b */
189     VMEXIT_CR12_WRITE  =  28, /* 0x1c */
190     VMEXIT_CR13_WRITE  =  29, /* 0x1d */
191     VMEXIT_CR14_WRITE  =  30, /* 0x1e */
192     VMEXIT_CR15_WRITE  =  31, /* 0x1f */
193 
194     /* debug register read exitcodes */
195     VMEXIT_DR0_READ    =  32, /* 0x20 */
196     VMEXIT_DR1_READ    =  33, /* 0x21 */
197     VMEXIT_DR2_READ    =  34, /* 0x22 */
198     VMEXIT_DR3_READ    =  35, /* 0x23 */
199     VMEXIT_DR4_READ    =  36, /* 0x24 */
200     VMEXIT_DR5_READ    =  37, /* 0x25 */
201     VMEXIT_DR6_READ    =  38, /* 0x26 */
202     VMEXIT_DR7_READ    =  39, /* 0x27 */
203     VMEXIT_DR8_READ    =  40, /* 0x28 */
204     VMEXIT_DR9_READ    =  41, /* 0x29 */
205     VMEXIT_DR10_READ   =  42, /* 0x2a */
206     VMEXIT_DR11_READ   =  43, /* 0x2b */
207     VMEXIT_DR12_READ   =  44, /* 0x2c */
208     VMEXIT_DR13_READ   =  45, /* 0x2d */
209     VMEXIT_DR14_READ   =  46, /* 0x2e */
210     VMEXIT_DR15_READ   =  47, /* 0x2f */
211 
212     /* debug register write exitcodes */
213     VMEXIT_DR0_WRITE   =  48, /* 0x30 */
214     VMEXIT_DR1_WRITE   =  49, /* 0x31 */
215     VMEXIT_DR2_WRITE   =  50, /* 0x32 */
216     VMEXIT_DR3_WRITE   =  51, /* 0x33 */
217     VMEXIT_DR4_WRITE   =  52, /* 0x34 */
218     VMEXIT_DR5_WRITE   =  53, /* 0x35 */
219     VMEXIT_DR6_WRITE   =  54, /* 0x36 */
220     VMEXIT_DR7_WRITE   =  55, /* 0x37 */
221     VMEXIT_DR8_WRITE   =  56, /* 0x38 */
222     VMEXIT_DR9_WRITE   =  57, /* 0x39 */
223     VMEXIT_DR10_WRITE  =  58, /* 0x3a */
224     VMEXIT_DR11_WRITE  =  59, /* 0x3b */
225     VMEXIT_DR12_WRITE  =  60, /* 0x3c */
226     VMEXIT_DR13_WRITE  =  61, /* 0x3d */
227     VMEXIT_DR14_WRITE  =  62, /* 0x3e */
228     VMEXIT_DR15_WRITE  =  63, /* 0x3f */
229 
230     /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
231     VMEXIT_EXCEPTION_DE  =  64, /* 0x40, divide-by-zero-error */
232     VMEXIT_EXCEPTION_DB  =  65, /* 0x41, debug */
233     VMEXIT_EXCEPTION_NMI =  66, /* 0x42, non-maskable-interrupt */
234     VMEXIT_EXCEPTION_BP  =  67, /* 0x43, breakpoint */
235     VMEXIT_EXCEPTION_OF  =  68, /* 0x44, overflow */
236     VMEXIT_EXCEPTION_BR  =  69, /* 0x45, bound-range */
237     VMEXIT_EXCEPTION_UD  =  70, /* 0x46, invalid-opcode*/
238     VMEXIT_EXCEPTION_NM  =  71, /* 0x47, device-not-available */
239     VMEXIT_EXCEPTION_DF  =  72, /* 0x48, double-fault */
240     VMEXIT_EXCEPTION_09  =  73, /* 0x49, unsupported (reserved) */
241     VMEXIT_EXCEPTION_TS  =  74, /* 0x4a, invalid-tss */
242     VMEXIT_EXCEPTION_NP  =  75, /* 0x4b, segment-not-present */
243     VMEXIT_EXCEPTION_SS  =  76, /* 0x4c, stack */
244     VMEXIT_EXCEPTION_GP  =  77, /* 0x4d, general-protection */
245     VMEXIT_EXCEPTION_PF  =  78, /* 0x4e, page-fault */
246     VMEXIT_EXCEPTION_15  =  79, /* 0x4f, reserved */
247     VMEXIT_EXCEPTION_MF  =  80, /* 0x50, x87 floating-point exception-pending */
248     VMEXIT_EXCEPTION_AC  =  81, /* 0x51, alignment-check */
249     VMEXIT_EXCEPTION_MC  =  82, /* 0x52, machine-check */
250     VMEXIT_EXCEPTION_XF  =  83, /* 0x53, simd floating-point */
251 
252     /* exceptions 20-31 (exitcodes 84-95) are reserved */
253 
254     /* ...and the rest of the #VMEXITs */
255     VMEXIT_INTR             =  96, /* 0x60 */
256     VMEXIT_NMI              =  97, /* 0x61 */
257     VMEXIT_SMI              =  98, /* 0x62 */
258     VMEXIT_INIT             =  99, /* 0x63 */
259     VMEXIT_VINTR            = 100, /* 0x64 */
260     VMEXIT_CR0_SEL_WRITE    = 101, /* 0x65 */
261     VMEXIT_IDTR_READ        = 102, /* 0x66 */
262     VMEXIT_GDTR_READ        = 103, /* 0x67 */
263     VMEXIT_LDTR_READ        = 104, /* 0x68 */
264     VMEXIT_TR_READ          = 105, /* 0x69 */
265     VMEXIT_IDTR_WRITE       = 106, /* 0x6a */
266     VMEXIT_GDTR_WRITE       = 107, /* 0x6b */
267     VMEXIT_LDTR_WRITE       = 108, /* 0x6c */
268     VMEXIT_TR_WRITE         = 109, /* 0x6d */
269     VMEXIT_RDTSC            = 110, /* 0x6e */
270     VMEXIT_RDPMC            = 111, /* 0x6f */
271     VMEXIT_PUSHF            = 112, /* 0x70 */
272     VMEXIT_POPF             = 113, /* 0x71 */
273     VMEXIT_CPUID            = 114, /* 0x72 */
274     VMEXIT_RSM              = 115, /* 0x73 */
275     VMEXIT_IRET             = 116, /* 0x74 */
276     VMEXIT_SWINT            = 117, /* 0x75 */
277     VMEXIT_INVD             = 118, /* 0x76 */
278     VMEXIT_PAUSE            = 119, /* 0x77 */
279     VMEXIT_HLT              = 120, /* 0x78 */
280     VMEXIT_INVLPG           = 121, /* 0x79 */
281     VMEXIT_INVLPGA          = 122, /* 0x7a */
282     VMEXIT_IOIO             = 123, /* 0x7b */
283     VMEXIT_MSR              = 124, /* 0x7c */
284     VMEXIT_TASK_SWITCH      = 125, /* 0x7d */
285     VMEXIT_FERR_FREEZE      = 126, /* 0x7e */
286     VMEXIT_SHUTDOWN         = 127, /* 0x7f */
287     VMEXIT_VMRUN            = 128, /* 0x80 */
288     VMEXIT_VMMCALL          = 129, /* 0x81 */
289     VMEXIT_VMLOAD           = 130, /* 0x82 */
290     VMEXIT_VMSAVE           = 131, /* 0x83 */
291     VMEXIT_STGI             = 132, /* 0x84 */
292     VMEXIT_CLGI             = 133, /* 0x85 */
293     VMEXIT_SKINIT           = 134, /* 0x86 */
294     VMEXIT_RDTSCP           = 135, /* 0x87 */
295     VMEXIT_ICEBP            = 136, /* 0x88 */
296     VMEXIT_WBINVD           = 137, /* 0x89 */
297     VMEXIT_MONITOR          = 138, /* 0x8a */
298     VMEXIT_MWAIT            = 139, /* 0x8b */
299     VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */
300     VMEXIT_XSETBV           = 141, /* 0x8d */
301     VMEXIT_NPF              = 1024, /* 0x400, nested paging fault */
302     VMEXIT_INVALID          =  -1
303 };
304 
305 enum
306 {
307     /* Available on all SVM-capable hardware. */
308     TLB_CTRL_NO_FLUSH             = 0,
309     TLB_CTRL_FLUSH_ALL            = 1,
310 
311     /* Available with the FlushByASID feature. */
312     TLB_CTRL_FLUSH_ASID           = 3,
313     TLB_CTRL_FLUSH_ASID_NONGLOBAL = 7,
314 };
315 
316 typedef union
317 {
318     struct
319     {
320         uint8_t  vector;
321         uint8_t  type:3;
322         bool     ev:1;
323         uint32_t resvd1:19;
324         bool     v:1;
325         uint32_t ec;
326     };
327     uint64_t raw;
328 } intinfo_t;
329 
330 typedef union {
331     struct {
332         bool intr_shadow:    1;
333         bool guest_intr_mask:1;
334     };
335     uint64_t raw;
336 } intstat_t;
337 
338 typedef union
339 {
340     u64 bytes;
341     struct
342     {
343         u64 tpr:          8;
344         u64 irq:          1;
345         u64 vgif:         1;
346         u64 rsvd0:        6;
347         u64 prio:         4;
348         u64 ign_tpr:      1;
349         u64 rsvd1:        3;
350         u64 intr_masking: 1;
351         u64 vgif_enable:  1;
352         u64 rsvd2:        6;
353         u64 vector:       8;
354         u64 rsvd3:       24;
355     } fields;
356 } vintr_t;
357 
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 } ioio_info_t;
374 
375 typedef union
376 {
377     u64 bytes;
378     struct
379     {
380         u64 lbr_enable:1;
381         u64 vloadsave_enable:1;
382     } fields;
383 } virt_ext_t;
384 
385 typedef union
386 {
387     struct {
388         bool intercepts:1; /* 0:  cr/dr/exception/general intercepts,
389                             *     pause_filter_count, tsc_offset */
390         bool iopm:1;       /* 1:  iopm_base_pa, msrpm_base_pa */
391         bool asid:1;       /* 2:  guest_asid */
392         bool tpr:1;        /* 3:  vintr */
393         bool np:1;         /* 4:  np_enable, h_cr3, g_pat */
394         bool cr:1;         /* 5:  cr0, cr3, cr4, efer */
395         bool dr:1;         /* 6:  dr6, dr7 */
396         bool dt:1;         /* 7:  gdtr, idtr */
397         bool seg:1;        /* 8:  cs, ds, es, ss, cpl */
398         bool cr2:1;        /* 9:  cr2 */
399         bool lbr:1;        /* 10: debugctlmsr, last{branch,int}{to,from}ip */
400     };
401     uint32_t raw;
402 } vmcbcleanbits_t;
403 
404 #define IOPM_SIZE   (12 * 1024)
405 #define MSRPM_SIZE  (8  * 1024)
406 
407 struct vmcb_struct {
408     u32 _cr_intercepts;         /* offset 0x00 - cleanbit 0 */
409     u32 _dr_intercepts;         /* offset 0x04 - cleanbit 0 */
410     u32 _exception_intercepts;  /* offset 0x08 - cleanbit 0 */
411     u32 _general1_intercepts;   /* offset 0x0C - cleanbit 0 */
412     u32 _general2_intercepts;   /* offset 0x10 - cleanbit 0 */
413     u32 res01[10];
414     u16 _pause_filter_thresh;   /* offset 0x3C - cleanbit 0 */
415     u16 _pause_filter_count;    /* offset 0x3E - cleanbit 0 */
416     u64 _iopm_base_pa;          /* offset 0x40 - cleanbit 1 */
417     u64 _msrpm_base_pa;         /* offset 0x48 - cleanbit 1 */
418     u64 _tsc_offset;            /* offset 0x50 - cleanbit 0 */
419     u32 _guest_asid;            /* offset 0x58 - cleanbit 2 */
420     u8  tlb_control;            /* offset 0x5C - TLB_CTRL_* */
421     u8  res07[3];
422     vintr_t _vintr;             /* offset 0x60 - cleanbit 3 */
423     intstat_t int_stat;         /* offset 0x68 */
424     u64 exitcode;               /* offset 0x70 */
425     union {
426         struct {
427             uint64_t exitinfo1; /* offset 0x78 */
428             uint64_t exitinfo2; /* offset 0x80 */
429         };
430         union {
431             struct {
432                 uint16_t sel;
433                 uint64_t :48;
434 
435                 uint32_t ec;
436                 uint32_t :4;
437                 bool     iret:1;
438                 uint32_t :1;
439                 bool     jmp:1;
440                 uint32_t :5;
441                 bool     ev:1;
442                 uint32_t :3;
443                 bool     rf:1;
444             } task_switch;
445         } ei;
446     };
447     intinfo_t exit_int_info;    /* offset 0x88 */
448     union {                     /* offset 0x90 - cleanbit 4 */
449         struct {
450             bool _np_enable     :1;
451             bool _sev_enable    :1;
452             bool _sev_es_enable :1;
453             bool _gmet          :1;
454             bool                :1;
455             bool _vte           :1;
456         };
457         uint64_t _np_ctrl;
458     };
459     u64 res08[2];
460     intinfo_t event_inj;        /* offset 0xA8 */
461     u64 _h_cr3;                 /* offset 0xB0 - cleanbit 4 */
462     virt_ext_t virt_ext;        /* offset 0xB8 */
463     vmcbcleanbits_t cleanbits;  /* offset 0xC0 */
464     u32 res09;                  /* offset 0xC4 */
465     u64 nextrip;                /* offset 0xC8 */
466     u8  guest_ins_len;          /* offset 0xD0 */
467     u8  guest_ins[15];          /* offset 0xD1 */
468     u64 res10a[100];            /* offset 0xE0 pad to save area */
469 
470     union {
471         struct segment_register sreg[6];
472         struct {
473             struct segment_register es;  /* offset 0x400 - cleanbit 8 */
474             struct segment_register cs;  /* cleanbit 8 */
475             struct segment_register ss;  /* cleanbit 8 */
476             struct segment_register ds;  /* cleanbit 8 */
477             struct segment_register fs;
478             struct segment_register gs;
479         };
480     };
481     struct segment_register gdtr; /* cleanbit 7 */
482     struct segment_register ldtr;
483     struct segment_register idtr; /* cleanbit 7 */
484     struct segment_register tr;
485     u64 res10[5];
486     u8 res11[3];
487     u8 _cpl;                    /* cleanbit 8 */
488     u32 res12;
489     u64 _efer;                  /* offset 0x400 + 0xD0 - cleanbit 5 */
490     u64 res13[14];
491     u64 _cr4;                   /* offset 0x400 + 0x148 - cleanbit 5 */
492     u64 _cr3;                   /* cleanbit 5 */
493     u64 _cr0;                   /* cleanbit 5 */
494     u64 _dr7;                   /* cleanbit 6 */
495     u64 _dr6;                   /* cleanbit 6 */
496     u64 rflags;
497     u64 rip;
498     u64 res14[11];
499     u64 rsp;
500     u64 res15[3];
501     u64 rax;
502     u64 star;
503     u64 lstar;
504     u64 cstar;
505     u64 sfmask;
506     u64 kerngsbase;
507     u64 sysenter_cs;
508     u64 sysenter_esp;
509     u64 sysenter_eip;
510     u64 _cr2;                   /* cleanbit 9 */
511     u64 res16[4];
512     u64 _g_pat;                 /* cleanbit 4 */
513     u64 _debugctlmsr;           /* cleanbit 10 */
514     u64 _lastbranchfromip;      /* cleanbit 10 */
515     u64 _lastbranchtoip;        /* cleanbit 10 */
516     u64 _lastintfromip;         /* cleanbit 10 */
517     u64 _lastinttoip;           /* cleanbit 10 */
518     u64 res17[301];
519 };
520 
521 struct svm_domain {
522     /* OSVW MSRs */
523     union {
524         uint64_t raw[2];
525         struct {
526             uint64_t length;
527             uint64_t status;
528         };
529     } osvw;
530 };
531 
532 /*
533  * VMRUN doesn't switch fs/gs/tr/ldtr and SHADOWGS/SYSCALL/SYSENTER state.
534  * Therefore, guest state is in the hardware registers when servicing a
535  * VMExit.
536  *
537  * Immediately after a VMExit, the vmcb is stale, and needs to be brought
538  * into sync by VMSAVE.  If state in the vmcb is modified, a VMLOAD is
539  * needed before the following VMRUN.
540  */
541 enum vmcb_sync_state {
542     vmcb_in_sync,
543     vmcb_needs_vmsave,    /* VMCB out of sync (VMSAVE needed)? */
544     vmcb_needs_vmload     /* VMCB dirty (VMLOAD needed)? */
545 };
546 
547 struct svm_vcpu {
548     struct vmcb_struct *vmcb;
549     u64    vmcb_pa;
550     unsigned long *msrpm;
551     int    launch_core;
552 
553     uint8_t vmcb_sync_state; /* enum vmcb_sync_state */
554 
555     /* VMCB has a cached instruction from #PF/#NPF Decode Assist? */
556     uint8_t cached_insn_len; /* Zero if no cached instruction. */
557 
558     /* Upper four bytes are undefined in the VMCB, therefore we can't
559      * use the fields in the VMCB. Write a 64bit value and then read a 64bit
560      * value is fine unless there's a VMRUN/VMEXIT in between which clears
561      * the upper four bytes.
562      */
563     uint64_t guest_sysenter_cs;
564     uint64_t guest_sysenter_esp;
565     uint64_t guest_sysenter_eip;
566 };
567 
568 struct vmcb_struct *alloc_vmcb(void);
569 void free_vmcb(struct vmcb_struct *vmcb);
570 
571 int  svm_create_vmcb(struct vcpu *v);
572 void svm_destroy_vmcb(struct vcpu *v);
573 
574 void setup_vmcb_dump(void);
575 
576 #define MSR_INTERCEPT_NONE    0
577 #define MSR_INTERCEPT_READ    1
578 #define MSR_INTERCEPT_WRITE   2
579 #define MSR_INTERCEPT_RW      (MSR_INTERCEPT_WRITE | MSR_INTERCEPT_READ)
580 void svm_intercept_msr(struct vcpu *v, uint32_t msr, int enable);
581 #define svm_disable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_NONE)
582 #define svm_enable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_RW)
583 
584 /*
585  * VMCB accessor functions.
586  */
587 
588 #define VMCB_ACCESSORS_(name, type, cleanbit)     \
589 static inline void                                \
590 vmcb_set_ ## name(struct vmcb_struct *vmcb,       \
591                   type value)                     \
592 {                                                 \
593     vmcb->_ ## name = value;                      \
594     vmcb->cleanbits.cleanbit = false;             \
595 }                                                 \
596 static inline type                                \
597 vmcb_get_ ## name(const struct vmcb_struct *vmcb) \
598 {                                                 \
599     return vmcb->_ ## name;                       \
600 }
601 
602 #define VMCB_ACCESSORS(name, cleanbit) \
603         VMCB_ACCESSORS_(name, typeof(alloc_vmcb()->_ ## name), cleanbit)
604 
605 VMCB_ACCESSORS(cr_intercepts, intercepts)
606 VMCB_ACCESSORS(dr_intercepts, intercepts)
607 VMCB_ACCESSORS(exception_intercepts, intercepts)
608 VMCB_ACCESSORS(general1_intercepts, intercepts)
609 VMCB_ACCESSORS(general2_intercepts, intercepts)
610 VMCB_ACCESSORS(pause_filter_count, intercepts)
611 VMCB_ACCESSORS(pause_filter_thresh, intercepts)
612 VMCB_ACCESSORS(tsc_offset, intercepts)
613 VMCB_ACCESSORS(iopm_base_pa, iopm)
614 VMCB_ACCESSORS(msrpm_base_pa, iopm)
615 VMCB_ACCESSORS(guest_asid, asid)
616 VMCB_ACCESSORS(vintr, tpr)
617 VMCB_ACCESSORS(np_ctrl, np)
618 VMCB_ACCESSORS_(np_enable, bool, np)
619 VMCB_ACCESSORS_(sev_enable, bool, np)
620 VMCB_ACCESSORS_(sev_es_enable, bool, np)
621 VMCB_ACCESSORS_(gmet, bool, np)
622 VMCB_ACCESSORS_(vte, bool, np)
623 VMCB_ACCESSORS(h_cr3, np)
624 VMCB_ACCESSORS(g_pat, np)
625 VMCB_ACCESSORS(cr0, cr)
626 VMCB_ACCESSORS(cr3, cr)
627 VMCB_ACCESSORS(cr4, cr)
628 VMCB_ACCESSORS(efer, cr)
629 VMCB_ACCESSORS(dr6, dr)
630 VMCB_ACCESSORS(dr7, dr)
631 VMCB_ACCESSORS(cpl, seg)
632 VMCB_ACCESSORS(cr2, cr2)
633 VMCB_ACCESSORS(debugctlmsr, lbr)
634 VMCB_ACCESSORS(lastbranchfromip, lbr)
635 VMCB_ACCESSORS(lastbranchtoip, lbr)
636 VMCB_ACCESSORS(lastintfromip, lbr)
637 VMCB_ACCESSORS(lastinttoip, lbr)
638 
639 #undef VMCB_ACCESSORS
640 
641 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */
642 
643 /*
644  * Local variables:
645  * mode: C
646  * c-file-style: "BSD"
647  * c-basic-offset: 4
648  * tab-width: 4
649  * indent-tabs-mode: nil
650  * End:
651  */
652