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.


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