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.


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