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.


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