Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


modified copyright tags
[palacios.git] / palacios / include / palacios / vmcb.h
1 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
2 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
3
4 #ifndef __VMCB_H
5 #define __VMCB_H
6
7 #ifdef __V3VEE__
8
9 #include <palacios/vmm_types.h>
10 #include <palacios/vm_guest.h>
11
12 #define VMCB_CTRL_AREA_OFFSET                   0x0
13 #define VMCB_STATE_SAVE_AREA_OFFSET             0x400
14
15
16 #define GET_VMCB_CTRL_AREA(page)         (page + VMCB_CTRL_AREA_OFFSET)
17 #define GET_VMCB_SAVE_STATE_AREA(page)   (page + VMCB_STATE_SAVE_AREA_OFFSET)
18
19
20 #if __TINYC__
21 #define PACKED
22 #else
23 #define PACKED __attribute__((packed))
24 #endif
25
26
27 typedef void vmcb_t;
28
29
30 struct Ctrl_Registers {
31     uint_t cr0        : 1        PACKED;
32     uint_t cr1        : 1        PACKED;
33     uint_t cr2        : 1        PACKED;
34     uint_t cr3        : 1        PACKED;
35     uint_t cr4        : 1        PACKED;
36     uint_t cr5        : 1        PACKED;
37     uint_t cr6        : 1        PACKED;
38     uint_t cr7        : 1        PACKED;
39     uint_t cr8        : 1        PACKED;
40     uint_t cr9        : 1        PACKED;
41     uint_t cr10       : 1        PACKED;
42     uint_t cr11       : 1        PACKED;
43     uint_t cr12       : 1        PACKED;
44     uint_t cr13       : 1        PACKED;
45     uint_t cr14       : 1        PACKED;
46     uint_t cr15       : 1        PACKED;
47 };
48
49
50 struct Debug_Registers {
51     uint_t dr0        : 1        PACKED;
52     uint_t dr1        : 1        PACKED;
53     uint_t dr2        : 1        PACKED;
54     uint_t dr3        : 1        PACKED;
55     uint_t dr4        : 1        PACKED;
56     uint_t dr5        : 1        PACKED;
57     uint_t dr6        : 1        PACKED;
58     uint_t dr7        : 1        PACKED;
59     uint_t dr8        : 1        PACKED;
60     uint_t dr9        : 1        PACKED;
61     uint_t dr10       : 1        PACKED;
62     uint_t dr11       : 1        PACKED;
63     uint_t dr12       : 1        PACKED;
64     uint_t dr13       : 1        PACKED;
65     uint_t dr14       : 1        PACKED;
66     uint_t dr15       : 1        PACKED;
67 };
68
69
70 struct Exception_Vectors {
71     uint_t de          : 1        PACKED; // (0) divide by zero
72     uint_t db          : 1        PACKED; // (1) Debug
73     uint_t nmi         : 1        PACKED; // (2) Non-maskable interrupt
74     uint_t bp          : 1        PACKED; // (3) Breakpoint
75     uint_t of          : 1        PACKED; // (4) Overflow
76     uint_t br          : 1        PACKED; // (5) Bound-Range
77     uint_t ud          : 1        PACKED; // (6) Invalid-Opcode
78     uint_t nm          : 1        PACKED; // (7) Device-not-available
79     uint_t df          : 1        PACKED; // (8) Double Fault
80     uint_t ex9         : 1        PACKED; 
81     uint_t ts          : 1        PACKED; // (10) Invalid TSS
82     uint_t np          : 1        PACKED; // (11) Segment-not-present
83     uint_t ss          : 1        PACKED; // (12) Stack
84     uint_t gp          : 1        PACKED; // (13) General Protection Fault
85     uint_t pf          : 1        PACKED; // (14) Page fault
86     uint_t ex15        : 1        PACKED;
87     uint_t mf          : 1        PACKED; // (15) Floating point exception
88     uint_t ac          : 1        PACKED; // (16) Alignment-check
89     uint_t mc          : 1        PACKED; // (17) Machine Check
90     uint_t xf          : 1        PACKED; // (18) SIMD floating-point
91     uint_t ex20        : 1        PACKED;
92     uint_t ex21        : 1        PACKED;
93     uint_t ex22        : 1        PACKED;
94     uint_t ex23        : 1        PACKED;
95     uint_t ex24        : 1        PACKED;
96     uint_t ex25        : 1        PACKED;
97     uint_t ex26        : 1        PACKED;
98     uint_t ex27        : 1        PACKED;
99     uint_t ex28        : 1        PACKED;
100     uint_t ex29        : 1        PACKED;
101     uint_t sx          : 1        PACKED; // (30) Security Exception
102     uint_t ex31        : 1        PACKED;
103 };
104
105
106 struct Instr_Intercepts {
107     uint_t INTR        : 1        PACKED;
108     uint_t NMI         : 1        PACKED;
109     uint_t SMI         : 1        PACKED;
110     uint_t INIT        : 1        PACKED;
111     uint_t VINTR       : 1        PACKED;
112     uint_t CR0         : 1        PACKED;
113     uint_t RD_IDTR     : 1        PACKED;
114     uint_t RD_GDTR     : 1        PACKED;
115     uint_t RD_LDTR     : 1        PACKED;
116     uint_t RD_TR       : 1        PACKED;
117     uint_t WR_IDTR     : 1        PACKED;
118     uint_t WR_GDTR     : 1        PACKED;
119     uint_t WR_LDTR     : 1        PACKED;
120     uint_t WR_TR       : 1        PACKED;
121     uint_t RDTSC       : 1        PACKED;
122     uint_t RDPMC       : 1        PACKED;
123     uint_t PUSHF       : 1        PACKED;
124     uint_t POPF        : 1        PACKED;
125     uint_t CPUID       : 1        PACKED;
126     uint_t RSM         : 1        PACKED;
127     uint_t IRET        : 1        PACKED;
128     uint_t INTn        : 1        PACKED;
129     uint_t INVD        : 1        PACKED;
130     uint_t PAUSE       : 1        PACKED;
131     uint_t HLT         : 1        PACKED;
132     uint_t INVLPG      : 1        PACKED;
133     uint_t INVLPGA     : 1        PACKED;
134     uint_t IOIO_PROT   : 1        PACKED;
135     uint_t MSR_PROT    : 1        PACKED;
136     uint_t task_switch : 1        PACKED;
137     uint_t FERR_FREEZE : 1        PACKED;
138     uint_t shutdown_evts: 1       PACKED;
139 };
140
141 struct SVM_Instr_Intercepts { 
142   uint_t VMRUN      : 1         PACKED;
143   uint_t VMMCALL    : 1         PACKED;
144   uint_t VMLOAD     : 1         PACKED;
145   uint_t VMSAVE     : 1         PACKED;
146   uint_t STGI       : 1         PACKED;
147   uint_t CLGI       : 1         PACKED;
148   uint_t SKINIT     : 1         PACKED;
149   uint_t RDTSCP     : 1         PACKED;
150   uint_t ICEBP      : 1         PACKED;
151   uint_t WBINVD     : 1         PACKED;
152   uint_t MONITOR    : 1         PACKED;
153   uint_t MWAIT_always : 1       PACKED;
154   uint_t MWAIT_if_armed : 1     PACKED;
155   uint_t reserved  : 19         PACKED;  // Should be 0
156 };
157
158
159 struct Guest_Control {
160   uchar_t V_TPR                 PACKED;
161   uint_t V_IRQ      : 1         PACKED;
162   uint_t rsvd1      : 7         PACKED;  // Should be 0
163   uint_t V_INTR_PRIO : 4        PACKED;
164   uint_t V_IGN_TPR  : 1         PACKED;
165   uint_t rsvd2      : 3         PACKED;  // Should be 0
166   uint_t V_INTR_MASKING : 1     PACKED;
167   uint_t rsvd3      : 7         PACKED;  // Should be 0
168   uchar_t V_INTR_VECTOR         PACKED;
169   uint_t rsvd4      : 24        PACKED;  // Should be 0
170 };
171
172 #define SVM_INJECTION_EXTERNAL_INTR 0
173 #define SVM_INJECTION_VIRTUAL_INTR  0
174 #define SVM_INJECTION_NMI           2
175 #define SVM_INJECTION_EXCEPTION     3
176 #define SVM_INJECTION_SOFT_INTR     4
177
178 struct Interrupt_Info {
179   uint_t vector       : 8         PACKED;
180   uint_t type         : 3         PACKED;
181   uint_t ev           : 1         PACKED;
182   uint_t rsvd         : 19        PACKED;
183   uint_t valid        : 1         PACKED;
184   uint_t error_code   : 32        PACKED;
185 };
186
187
188 typedef struct VMCB_Control_Area {
189   // offset 0x0
190   struct Ctrl_Registers cr_reads         PACKED;
191   struct Ctrl_Registers cr_writes        PACKED;
192   struct Debug_Registers dr_reads        PACKED;
193   struct Debug_Registers dr_writes       PACKED;
194   struct Exception_Vectors exceptions    PACKED;
195   struct Instr_Intercepts instrs         PACKED;
196   struct SVM_Instr_Intercepts svm_instrs PACKED;
197
198   uchar_t rsvd1[44]                     PACKED;  // Should be 0
199
200   // offset 0x040
201   ullong_t IOPM_BASE_PA                 PACKED;
202   ullong_t MSRPM_BASE_PA                PACKED;
203   ullong_t TSC_OFFSET                   PACKED;
204
205   uint_t guest_ASID                     PACKED;
206   uchar_t TLB_CONTROL                   PACKED;
207
208   uchar_t rsvd2[3]                      PACKED;  // Should be 0
209
210   struct Guest_Control guest_ctrl        PACKED;
211   
212   uint_t interrupt_shadow  : 1          PACKED;
213   uint_t rsvd3             : 31         PACKED;  // Should be 0
214   uint_t rsvd4                          PACKED;  // Should be 0
215
216   ullong_t exit_code                    PACKED;
217   ullong_t exit_info1                   PACKED;
218   ullong_t exit_info2                   PACKED;
219
220   /* This could be a typo in the manual....
221    * It doesn't actually say that there is a reserved bit
222    * But it does say that the EXITINTINFO field is in bits 63-1
223    * ALL other occurances mention a 1 bit reserved field
224    */
225   //  uint_t rsvd5             : 1          PACKED;
226   //ullong_t exit_int_info   : 63         PACKED;
227   /* ** */
228
229   // AMD Manual 2, pg 391, sect: 15.19
230   struct Interrupt_Info exit_int_info  PACKED;
231
232   //  uint_t NP_ENABLE         : 1          PACKED;
233   //ullong_t rsvd6           : 63         PACKED;  // Should be 0 
234   ullong_t NP_ENABLE                    PACKED;
235
236   uchar_t rsvd7[16]                     PACKED;  // Should be 0
237
238   // Offset 0xA8
239   struct Interrupt_Info EVENTINJ                     PACKED;
240
241
242   /* This could be a typo in the manual....
243    * It doesn't actually say that there is a reserved bit
244    * But it does say that the EXITINTINFO field is in bits 63-1
245    * ALL other occurances mention a 1 bit reserved field
246    */
247   //  uint_t rsvd8              : 1         PACKED;
248   //ullong_t N_CR3            : 63        PACKED;
249   ullong_t N_CR3                        PACKED;
250   /* ** */
251
252
253   uint_t LBR_VIRTUALIZATION_ENABLE : 1  PACKED;
254   ullong_t rsvd9            : 63        PACKED;   // Should be 0
255
256 } vmcb_ctrl_t;
257
258
259
260
261
262
263 struct vmcb_selector {
264   ushort_t selector                   PACKED;
265
266   /* These attributes are basically a direct map of the attribute fields of a segment desc.
267    * The segment limit in the middle is removed and the fields are fused together
268    * There IS empty space at the end... See AMD Arch vol3, sect. 4.7.1,  pg 78
269    */
270   union {
271     ushort_t raw                      PACKED;
272     struct {
273       uint_t type              : 4    PACKED; // segment type, [see Intel vol. 3b, sect. 3.4.5.1 (because I have the books)]
274       uint_t S                 : 1    PACKED; // System=0, code/data=1
275       uint_t dpl               : 2    PACKED; // priviledge level, corresonds to protection ring
276       uint_t P                 : 1    PACKED; // present flag
277       uint_t avl               : 1    PACKED; // available for use by system software
278       uint_t L                 : 1    PACKED; // long mode (64 bit?)
279       uint_t db                : 1    PACKED; // default op size (0=16 bit seg, 1=32 bit seg)
280       uint_t G                 : 1    PACKED; // Granularity, (0=bytes, 1=4k)
281       uint_t rsvd              : 4    PACKED;
282     } fields;
283   } attrib;
284   uint_t  limit                       PACKED;
285   ullong_t base                       PACKED;
286 };
287
288
289 typedef struct VMCB_State_Save_Area {
290   struct vmcb_selector es            PACKED; // only lower 32 bits of base are implemented
291   struct vmcb_selector cs            PACKED; // only lower 32 bits of base are implemented
292   struct vmcb_selector ss            PACKED; // only lower 32 bits of base are implemented
293   struct vmcb_selector ds            PACKED; // only lower 32 bits of base are implemented
294   struct vmcb_selector fs            PACKED; 
295   struct vmcb_selector gs            PACKED; 
296
297   struct vmcb_selector gdtr          PACKED; // selector+attrib are reserved, only lower 16 bits of limit are implemented
298   struct vmcb_selector ldtr          PACKED; 
299   struct vmcb_selector idtr          PACKED; // selector+attrib are reserved, only lower 16 bits of limit are implemented
300   struct vmcb_selector tr            PACKED; 
301
302   uchar_t rsvd1[43]                  PACKED;
303
304   //offset 0x0cb
305   uchar_t cpl                        PACKED; // if the guest is real-mode then the CPL is forced to 0
306                                              // if the guest is virtual-mode then the CPL is forced to 3
307
308   uint_t rsvd2                       PACKED;
309
310   // offset 0x0d0
311   ullong_t efer                      PACKED;
312
313   uchar_t rsvd3[112]                 PACKED;
314   
315   //offset 0x148
316   ullong_t cr4                       PACKED;
317   ullong_t cr3                       PACKED;
318   ullong_t cr0                       PACKED;
319   ullong_t dr7                       PACKED;
320   ullong_t dr6                       PACKED;
321   ullong_t rflags                    PACKED;
322   ullong_t rip                       PACKED;
323
324   uchar_t rsvd4[88]                  PACKED;
325   
326   //offset 0x1d8
327   ullong_t rsp                       PACKED;
328
329   uchar_t rsvd5[24]                  PACKED;
330
331   //offset 0x1f8
332   ullong_t rax                       PACKED;
333   ullong_t star                      PACKED;
334   ullong_t lstar                     PACKED;
335   ullong_t cstar                     PACKED;
336   ullong_t sfmask                    PACKED;
337   ullong_t KernelGsBase              PACKED;
338   ullong_t sysenter_cs               PACKED;
339   ullong_t sysenter_esp              PACKED;
340   ullong_t sysenter_eip              PACKED;
341   ullong_t cr2                       PACKED;
342
343
344   uchar_t rsvd6[32]                  PACKED;
345
346   //offset 0x268
347   ullong_t g_pat                     PACKED; // Guest PAT                     
348                                              //   -- only used if nested paging is enabled
349   ullong_t dbgctl                    PACKED; // Guest DBGCTL MSR               
350                                              //   -- only used if the LBR registers are virtualized
351   ullong_t br_from                   PACKED; // Guest LastBranchFromIP MSR
352                                              //   -- only used if the LBR registers are virtualized
353   ullong_t br_to                     PACKED; // Guest LastBranchToIP MSR   
354                                              //   -- only used if the LBR registers are virtualized
355   ullong_t lastexcpfrom              PACKED; // Guest LastExceptionFromIP MSR
356                                              //   -- only used if the LBR registers are virtualized
357   ullong_t lastexcpto                PACKED; // Guest LastExceptionToIP MSR 
358                                              //   -- only used if the LBR registers are virtualized
359
360 } vmcb_saved_state_t;
361
362 void PrintDebugVMCB(vmcb_t * vmcb);
363
364
365 void set_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
366 void get_vmcb_segments(vmcb_t * vmcb, struct v3_segments * segs);
367
368 #endif // ! __V3VEE__
369
370 #endif