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.


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