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.


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