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