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.


added support for Intel EPT with(?) and without unrestricted guest support
[palacios.git] / palacios / include / palacios / vmcs.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, Peter Dinda <pdinda@northwestern.edu> 
11  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
12  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
13  * All rights reserved.
14  *
15  * Author: Peter Dinda <pdinda@northwestern.edu>
16  *         Jack Lange <jarusl@cs.northwestern.edu>
17  *
18  * This is free software.  You are permitted to use,
19  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20  */
21
22
23 #ifndef __VMCS_H__
24 #define __VMCS_H__
25
26 #ifdef __V3VEE__
27
28
29 #include <palacios/vmm_types.h>
30 #include <palacios/vm_guest.h>
31
32 /* VM-Exit Controls */
33 /* INTEL MANUAL: 20-16 vol. 3B */
34 #define   HOST_ADDR_SPACE_SIZE          0x00000200
35 #define   ACK_IRQ_ON_EXIT               0x00008000
36
37 /* Control register exit masks */
38 #define   CR4_VMXE      0x00002000
39
40
41
42 struct vmcs_field_encoding {
43     uint8_t access_type    : 1; /*  0 = full, 1 = high, (for accessing 64 bit fields on 32bit CPU) */
44     uint16_t index         : 9;
45     uint8_t type           : 2; /* 0=ctrl, 1=read-only, 2 = guest state, 3 = host state */
46     uint8_t rsvd1          : 1; /* MBZ */
47     uint8_t width          : 2; /* 0 = 16bit, 1 = 64bit, 2 = 32bit, 3 = natural width */
48     uint32_t rsvd2         : 17;
49 } __attribute__((packed));
50
51
52 typedef enum {
53     /* 16 bit control field */
54     VMCS_VPID                    = 0x00000000,
55     /* 16 bit guest state */
56     VMCS_GUEST_ES_SELECTOR       = 0x00000800,
57     VMCS_GUEST_CS_SELECTOR       = 0x00000802,
58     VMCS_GUEST_SS_SELECTOR       = 0x00000804,
59     VMCS_GUEST_DS_SELECTOR       = 0x00000806,
60     VMCS_GUEST_FS_SELECTOR       = 0x00000808,
61     VMCS_GUEST_GS_SELECTOR       = 0x0000080A,
62     VMCS_GUEST_LDTR_SELECTOR     = 0x0000080C,
63     VMCS_GUEST_TR_SELECTOR       = 0x0000080E,
64     /* 16 bit host state */
65     VMCS_HOST_ES_SELECTOR        = 0x00000C00,
66     VMCS_HOST_CS_SELECTOR        = 0x00000C02,
67     VMCS_HOST_SS_SELECTOR        = 0x00000C04,
68     VMCS_HOST_DS_SELECTOR        = 0x00000C06,
69     VMCS_HOST_FS_SELECTOR        = 0x00000C08,
70     VMCS_HOST_GS_SELECTOR        = 0x00000C0A,
71     VMCS_HOST_TR_SELECTOR        = 0x00000C0C,
72     /* 64 bit control fields */
73     VMCS_IO_BITMAP_A_ADDR             = 0x00002000,
74     VMCS_IO_BITMAP_A_ADDR_HIGH        = 0x00002001,
75     VMCS_IO_BITMAP_B_ADDR             = 0x00002002,
76     VMCS_IO_BITMAP_B_ADDR_HIGH        = 0x00002003,
77     VMCS_MSR_BITMAP                   = 0x00002004,
78     VMCS_MSR_BITMAP_HIGH              = 0x00002005,
79     VMCS_EXIT_MSR_STORE_ADDR          = 0x00002006,
80     VMCS_EXIT_MSR_STORE_ADDR_HIGH     = 0x00002007,
81     VMCS_EXIT_MSR_LOAD_ADDR           = 0x00002008,
82     VMCS_EXIT_MSR_LOAD_ADDR_HIGH      = 0x00002009,
83     VMCS_ENTRY_MSR_LOAD_ADDR          = 0x0000200A,
84     VMCS_ENTRY_MSR_LOAD_ADDR_HIGH     = 0x0000200B,
85     VMCS_EXEC_PTR                     = 0x0000200C,
86     VMCS_EXEC_PTR_HIGH                = 0x0000200D,
87     VMCS_TSC_OFFSET                   = 0x00002010,
88     VMCS_TSC_OFFSET_HIGH              = 0x00002011,
89     VMCS_VAPIC_ADDR                   = 0x00002012,
90     VMCS_VAPIC_ADDR_HIGH              = 0x00002013,
91     VMCS_APIC_ACCESS_ADDR             = 0x00002014,
92     VMCS_APIC_ACCESS_ADDR_HIGH        = 0x00002015,
93     VMCS_EPT_PTR                      = 0x0000201A,
94     VMCS_EPT_PTR_HIGH                 = 0x0000201B,
95     /* 64 bit read only data field */
96     VMCS_GUEST_PHYS_ADDR              = 0x00002400,
97     VMCS_GUEST_PHYS_ADDR_HIGH         = 0x00002401,
98     /* 64 bit guest state fields */
99     VMCS_LINK_PTR                     = 0x00002800,
100     VMCS_LINK_PTR_HIGH                = 0x00002801,
101     VMCS_GUEST_DBG_CTL                = 0x00002802,
102     VMCS_GUEST_DBG_CTL_HIGH           = 0x00002803,
103     VMCS_GUEST_PAT                    = 0x00002804,
104     VMCS_GUEST_PAT_HIGH               = 0x00002805,
105     VMCS_GUEST_EFER                   = 0x00002806,
106     VMCS_GUEST_EFER_HIGH              = 0x00002807,
107     VMCS_GUEST_PERF_GLOBAL_CTRL       = 0x00002808,
108     VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH  = 0x00002809,
109     VMCS_GUEST_PDPTE0                 = 0x0000280A,
110     VMCS_GUEST_PDPTE0_HIGH            = 0x0000280B,
111     VMCS_GUEST_PDPTE1                 = 0x0000280C,
112     VMCS_GUEST_PDPTE1_HIGH            = 0x0000280D,
113     VMCS_GUEST_PDPTE2                 = 0x0000280E,
114     VMCS_GUEST_PDPTE2_HIGH            = 0x0000280F,
115     VMCS_GUEST_PDPTE3                 = 0x00002810,
116     VMCS_GUEST_PDPTE3_HIGH            = 0x00002811,
117     /* 64 bit host state fields */
118     VMCS_HOST_PAT                     = 0x00002c00,
119     VMCS_HOST_PAT_HIGH                = 0x00002c01,
120     VMCS_HOST_EFER                    = 0x00002c02,
121     VMCS_HOST_EFER_HIGH               = 0x00002c03,
122     VMCS_HOST_PERF_GLOBAL_CTRL        = 0x00002c04,
123     VMCS_HOST_PERF_GLOBAL_CTRL_HIGH   = 0x00002c05,
124     /* 32 bit control fields */
125     VMCS_PIN_CTRLS                    = 0x00004000,
126     VMCS_PROC_CTRLS                   = 0x00004002,
127     VMCS_EXCP_BITMAP                  = 0x00004004,
128     VMCS_PG_FAULT_ERR_MASK            = 0x00004006,
129     VMCS_PG_FAULT_ERR_MATCH           = 0x00004008,
130     VMCS_CR3_TGT_CNT                  = 0x0000400A,
131     VMCS_EXIT_CTRLS                   = 0x0000400C,
132     VMCS_EXIT_MSR_STORE_CNT           = 0x0000400E,
133     VMCS_EXIT_MSR_LOAD_CNT            = 0x00004010,
134     VMCS_ENTRY_CTRLS                  = 0x00004012,
135     VMCS_ENTRY_MSR_LOAD_CNT           = 0x00004014,
136     VMCS_ENTRY_INT_INFO               = 0x00004016,
137     VMCS_ENTRY_EXCP_ERR               = 0x00004018,
138     VMCS_ENTRY_INSTR_LEN              = 0x0000401A,
139     VMCS_TPR_THRESHOLD                = 0x0000401C,
140     VMCS_SEC_PROC_CTRLS               = 0x0000401e,
141     VMCS_PLE_GAP                      = 0x00004020,
142     VMCS_PLE_WINDOW                   = 0x00004022,
143     /* 32 bit Read Only data fields */
144     VMCS_INSTR_ERR                    = 0x00004400,
145     VMCS_EXIT_REASON                  = 0x00004402,
146     VMCS_EXIT_INT_INFO                = 0x00004404,
147     VMCS_EXIT_INT_ERR                 = 0x00004406,
148     VMCS_IDT_VECTOR_INFO              = 0x00004408,
149     VMCS_IDT_VECTOR_ERR               = 0x0000440A,
150     VMCS_EXIT_INSTR_LEN               = 0x0000440C,
151     VMCS_EXIT_INSTR_INFO              = 0x0000440E,
152     /* 32 bit Guest state fields */
153     VMCS_GUEST_ES_LIMIT               = 0x00004800,
154     VMCS_GUEST_CS_LIMIT               = 0x00004802,
155     VMCS_GUEST_SS_LIMIT               = 0x00004804,
156     VMCS_GUEST_DS_LIMIT               = 0x00004806,
157     VMCS_GUEST_FS_LIMIT               = 0x00004808,
158     VMCS_GUEST_GS_LIMIT               = 0x0000480A,
159     VMCS_GUEST_LDTR_LIMIT             = 0x0000480C,
160     VMCS_GUEST_TR_LIMIT               = 0x0000480E,
161     VMCS_GUEST_GDTR_LIMIT             = 0x00004810,
162     VMCS_GUEST_IDTR_LIMIT             = 0x00004812,
163     VMCS_GUEST_ES_ACCESS              = 0x00004814,
164     VMCS_GUEST_CS_ACCESS              = 0x00004816,
165     VMCS_GUEST_SS_ACCESS              = 0x00004818,
166     VMCS_GUEST_DS_ACCESS              = 0x0000481A,
167     VMCS_GUEST_FS_ACCESS              = 0x0000481C,
168     VMCS_GUEST_GS_ACCESS              = 0x0000481E,
169     VMCS_GUEST_LDTR_ACCESS            = 0x00004820,
170     VMCS_GUEST_TR_ACCESS              = 0x00004822,
171     VMCS_GUEST_INT_STATE              = 0x00004824,
172     VMCS_GUEST_ACTIVITY_STATE         = 0x00004826,
173     VMCS_GUEST_SMBASE                 = 0x00004828,
174     VMCS_GUEST_SYSENTER_CS            = 0x0000482A,
175     VMCS_PREEMPT_TIMER                = 0x0000482E,
176     /* 32 bit host state field */
177     VMCS_HOST_SYSENTER_CS             = 0x00004C00,
178     /* Natural Width Control Fields */
179     VMCS_CR0_MASK                     = 0x00006000,
180     VMCS_CR4_MASK                     = 0x00006002,
181     VMCS_CR0_READ_SHDW                = 0x00006004,
182     VMCS_CR4_READ_SHDW                = 0x00006006,
183     VMCS_CR3_TGT_VAL_0                = 0x00006008,
184     VMCS_CR3_TGT_VAL_1                = 0x0000600A,
185     VMCS_CR3_TGT_VAL_2                = 0x0000600C,
186     VMCS_CR3_TGT_VAL_3                = 0x0000600E,
187     /* Natural Width Read Only Fields */
188     VMCS_EXIT_QUAL                    = 0x00006400,
189     VMCS_IO_RCX                       = 0x00006402,
190     VMCS_IO_RSI                       = 0x00006404,
191     VMCS_IO_RDI                       = 0x00006406,
192     VMCS_IO_RIP                       = 0x00006408,
193     VMCS_GUEST_LINEAR_ADDR            = 0x0000640A,
194     /* Natural Width Guest State Fields */
195     VMCS_GUEST_CR0                    = 0x00006800,
196     VMCS_GUEST_CR3                    = 0x00006802,
197     VMCS_GUEST_CR4                    = 0x00006804,
198     VMCS_GUEST_ES_BASE                = 0x00006806,
199     VMCS_GUEST_CS_BASE                = 0x00006808,
200     VMCS_GUEST_SS_BASE                = 0x0000680A,
201     VMCS_GUEST_DS_BASE                = 0x0000680C,
202     VMCS_GUEST_FS_BASE                = 0x0000680E,
203     VMCS_GUEST_GS_BASE                = 0x00006810,
204     VMCS_GUEST_LDTR_BASE              = 0x00006812,
205     VMCS_GUEST_TR_BASE                = 0x00006814,
206     VMCS_GUEST_GDTR_BASE              = 0x00006816,
207     VMCS_GUEST_IDTR_BASE              = 0x00006818,
208     VMCS_GUEST_DR7                    = 0x0000681A,
209     VMCS_GUEST_RSP                    = 0x0000681C,
210     VMCS_GUEST_RIP                    = 0x0000681E,
211     VMCS_GUEST_RFLAGS                 = 0x00006820,
212     VMCS_GUEST_PENDING_DBG_EXCP       = 0x00006822,
213     VMCS_GUEST_SYSENTER_ESP           = 0x00006824,
214     VMCS_GUEST_SYSENTER_EIP           = 0x00006826,
215     /* Natural Width Host State Fields */
216     VMCS_HOST_CR0                     = 0x00006C00,
217     VMCS_HOST_CR3                     = 0x00006C02,
218     VMCS_HOST_CR4                     = 0x00006C04,
219     VMCS_HOST_FS_BASE                 = 0x00006C06,
220     VMCS_HOST_GS_BASE                 = 0x00006C08,
221     VMCS_HOST_TR_BASE                 = 0x00006C0A,
222     VMCS_HOST_GDTR_BASE               = 0x00006C0C,
223     VMCS_HOST_IDTR_BASE               = 0x00006C0E,
224     VMCS_HOST_SYSENTER_ESP            = 0x00006C10,
225     VMCS_HOST_SYSENTER_EIP            = 0x00006C12,
226     VMCS_HOST_RSP                     = 0x00006C14,
227     VMCS_HOST_RIP                     = 0x00006C16,
228 } vmcs_field_t;
229
230
231
232 struct vmx_exception_bitmap {
233     union {
234         uint32_t value;
235         struct {
236             uint_t de          : 1; // (0) divide by zero
237             uint_t db          : 1; // (1) Debug
238             uint_t nmi         : 1; // (2) Non-maskable interrupt
239             uint_t bp          : 1; // (3) Breakpoint
240             uint_t of          : 1; // (4) Overflow
241             uint_t br          : 1; // (5) Bound-Range
242             uint_t ud          : 1; // (6) Invalid-Opcode
243             uint_t nm          : 1; // (7) Device-not-available
244             uint_t df          : 1; // (8) Double Fault
245             uint_t ex9         : 1; 
246             uint_t ts          : 1; // (10) Invalid TSS
247             uint_t np          : 1; // (11) Segment-not-present
248             uint_t ss          : 1; // (12) Stack
249             uint_t gp          : 1; // (13) General Protection Fault
250             uint_t pf          : 1; // (14) Page fault
251             uint_t ex15        : 1;
252             uint_t mf          : 1; // (15) Floating point exception
253             uint_t ac          : 1; // (16) Alignment-check
254             uint_t mc          : 1; // (17) Machine Check
255             uint_t xf          : 1; // (18) SIMD floating-point
256             uint_t ex20        : 1;
257             uint_t ex21        : 1;
258             uint_t ex22        : 1;
259             uint_t ex23        : 1;
260             uint_t ex24        : 1;
261             uint_t ex25        : 1;
262             uint_t ex26        : 1;
263             uint_t ex27        : 1;
264             uint_t ex28        : 1;
265             uint_t ex29        : 1;
266             uint_t sx          : 1; // (30) Security Exception
267             uint_t ex31        : 1;
268         } __attribute__ ((packed));
269     } __attribute__ ((packed));
270 } __attribute__((packed));
271
272
273
274 struct vmx_intr_state {
275     union {
276         uint32_t value;
277         struct {
278             uint8_t block_sti    : 1;
279             uint8_t block_mov_ss : 1;
280             uint8_t block_smi    : 1;
281             uint8_t block_nmi    : 1;
282             uint32_t rsvd        : 28;
283         } __attribute__((packed));
284     } __attribute__((packed));
285 } __attribute__((packed));
286
287
288 struct vmx_pending_dbg_excps {
289     union {
290         uint64_t value;
291
292         struct {
293             uint32_t lo;
294             uint32_t hi;
295         } __attribute__((packed));
296
297         struct {
298             uint8_t b0       : 1;
299             uint8_t b1       : 1;
300             uint8_t b2       : 1;
301             uint8_t b3       : 1;
302             uint8_t rsvd1    : 8;
303             uint8_t bp_set   : 1;
304             uint8_t rsvd2    : 1;
305             uint8_t bp_ss    : 1;
306             uint64_t rsvd3   : 49;
307         } __attribute__((packed));
308     } __attribute__((packed));
309 } __attribute__((packed));
310
311 /* Segment Selector Access Rights (32 bits) */
312 /* INTEL Manual: 20-4 vol 3B */
313 struct vmcs_segment {
314     uint16_t selector;
315     uint32_t limit;
316     uint64_t base;
317
318     union {
319         uint32_t val;
320         struct {
321             uint32_t    type        : 4;
322             uint32_t    desc_type   : 1; 
323             uint32_t    dpl         : 2;
324             uint32_t    present     : 1;
325             uint32_t    rsvd1       : 4;
326             uint32_t    avail       : 1;
327             uint32_t    long_mode   : 1; // CS only (64 bit active), reserved otherwise
328             uint32_t    db          : 1; 
329             uint32_t    granularity : 1;
330             uint32_t    unusable    : 1; 
331             uint32_t    rsvd2       : 15;
332         } __attribute__((packed));
333     } __attribute__((packed)) access;
334 };
335
336
337 struct vmcs_interrupt_state {
338     union {
339         uint32_t val;
340         struct {
341             uint32_t    sti_blocking    : 1;
342             uint32_t    mov_ss_blocking : 1;
343             uint32_t    smi_blocking    : 1;
344             uint32_t    nmi_blocking    : 1;
345             uint32_t    rsvd1           : 28;
346         } __attribute__((packed));
347     } __attribute__((packed));
348 } __attribute__((packed));
349
350
351
352
353 struct vmcs_data {
354     uint32_t revision ;
355     uint32_t abort    ;
356 } __attribute__((packed));
357
358
359
360 int v3_vmcs_get_field_len(vmcs_field_t field);
361
362 const char * v3_vmcs_field_to_str(vmcs_field_t field);
363
364 void v3_print_vmcs();
365
366
367 int v3_vmx_save_vmcs(struct guest_info * info);
368 int v3_vmx_restore_vmcs(struct guest_info * info);
369
370
371 int v3_update_vmcs_host_state(struct guest_info * info);
372 int v3_update_vmcs_ctrl_fields(struct guest_info * info);
373
374
375 int v3_read_vmcs_segments(struct v3_segments * segs);
376 int v3_write_vmcs_segments(struct v3_segments * segs);
377 void v3_vmxseg_to_seg(struct vmcs_segment * vmcs_seg, struct v3_segment * seg);
378 void v3_seg_to_vmxseg(struct v3_segment * seg, struct vmcs_segment * vmcs_seg);
379
380 #endif // ! __V3VEE__
381
382
383 #endif