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