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.


Additional VMX support. Bootstrapping code added.
[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
31 typedef enum {
32     VMCS_GUEST_ES_SELECTOR       = 0x00000800,
33     VMCS_GUEST_CS_SELECTOR       = 0x00000802,
34     VMCS_GUEST_SS_SELECTOR       = 0x00000804,
35     VMCS_GUEST_DS_SELECTOR       = 0x00000806,
36     VMCS_GUEST_FS_SELECTOR       = 0x00000808,
37     VMCS_GUEST_GS_SELECTOR       = 0x0000080A,
38     VMCS_GUEST_LDTR_SELECTOR     = 0x0000080C,
39     VMCS_GUEST_TR_SELECTOR       = 0x0000080E,
40     /* 16 bit host state */
41     VMCS_HOST_ES_SELECTOR        = 0x00000C00,
42     VMCS_HOST_CS_SELECTOR        = 0x00000C02,
43     VMCS_HOST_SS_SELECTOR        = 0x00000C04,
44     VMCS_HOST_DS_SELECTOR        = 0x00000C06,
45     VMCS_HOST_FS_SELECTOR        = 0x00000C08,
46     VMCS_HOST_GS_SELECTOR        = 0x00000C0A,
47     VMCS_HOST_TR_SELECTOR        = 0x00000C0C,
48     /* 64 bit control fields */
49     IO_BITMAP_A_ADDR             = 0x00002000,
50     IO_BITMAP_A_ADDR_HIGH        = 0x00002001,
51     IO_BITMAP_B_ADDR             = 0x00002002,
52     IO_BITMAP_B_ADDR_HIGH        = 0x00002003,
53     MSR_BITMAPS                  = 0x00002004,
54     MSR_BITMAPS_HIGH             = 0x00002005,
55     VM_EXIT_MSR_STORE_ADDR       = 0x00002006,
56     VM_EXIT_MSR_STORE_ADDR_HIGH  = 0x00002007,
57     VM_EXIT_MSR_LOAD_ADDR        = 0x00002008,
58     VM_EXIT_MSR_LOAD_ADDR_HIGH   = 0x00002009,
59     VM_ENTRY_MSR_LOAD_ADDR       = 0x0000200A,
60     VM_ENTRY_MSR_LOAD_ADDR_HIGH  = 0x0000200B,
61     VMCS_EXEC_PTR                = 0x0000200C,
62     VMCS_EXEC_PTR_HIGH           = 0x0000200D,
63     TSC_OFFSET                   = 0x00002010,
64     TSC_OFFSET_HIGH              = 0x00002011,
65     VIRT_APIC_PAGE_ADDR          = 0x00002012,
66     VIRT_APIC_PAGE_ADDR_HIGH     = 0x00002013,
67     /* 64 bit guest state fields */
68     VMCS_LINK_PTR                = 0x00002800,
69     VMCS_LINK_PTR_HIGH           = 0x00002801,
70     GUEST_IA32_DEBUGCTL          = 0x00002802,
71     GUEST_IA32_DEBUGCTL_HIGH     = 0x00002803,
72     GUEST_IA32_PERF_GLOBAL_CTRL  = 0x00002808,
73     GUEST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
74     /* 32 bit control fields */
75     PIN_VM_EXEC_CTRLS            = 0x00004000,
76     PROC_VM_EXEC_CTRLS           = 0x00004002,
77     EXCEPTION_BITMAP             = 0x00004004,
78     PAGE_FAULT_ERROR_MASK        = 0x00004006,
79     PAGE_FAULT_ERROR_MATCH       = 0x00004008,
80     CR3_TARGET_COUNT             = 0x0000400A,
81     VM_EXIT_CTRLS                = 0x0000400C,
82     VM_EXIT_MSR_STORE_COUNT      = 0x0000400E,
83     VM_EXIT_MSR_LOAD_COUNT       = 0x00004010,
84     VM_ENTRY_CTRLS               = 0x00004012,
85     VM_ENTRY_MSR_LOAD_COUNT      = 0x00004014,
86     VM_ENTRY_INT_INFO_FIELD      = 0x00004016,
87     VM_ENTRY_EXCEPTION_ERROR     = 0x00004018,
88     VM_ENTRY_INSTR_LENGTH        = 0x0000401A,
89     TPR_THRESHOLD                = 0x0000401C,
90     /* 32 bit Read Only data fields */
91     VM_INSTR_ERROR               = 0x00004400,
92     EXIT_REASON                  = 0x00004402,
93     VM_EXIT_INT_INFO             = 0x00004404,
94     VM_EXIT_INT_ERROR            = 0x00004406,
95     IDT_VECTOR_INFO              = 0x00004408,
96     IDT_VECTOR_ERROR             = 0x0000440A,
97     VM_EXIT_INSTR_LENGTH         = 0x0000440C,
98     VMX_INSTR_INFO               = 0x0000440E,
99     /* 32 bit Guest state fields */
100     GUEST_ES_LIMIT               = 0x00004800,
101     GUEST_CS_LIMIT               = 0x00004802,
102     GUEST_SS_LIMIT               = 0x00004804,
103     GUEST_DS_LIMIT               = 0x00004806,
104     GUEST_FS_LIMIT               = 0x00004808,
105     GUEST_GS_LIMIT               = 0x0000480A,
106     GUEST_LDTR_LIMIT             = 0x0000480C,
107     GUEST_TR_LIMIT               = 0x0000480E,
108     GUEST_GDTR_LIMIT             = 0x00004810,
109     GUEST_IDTR_LIMIT             = 0x00004812,
110     GUEST_ES_ACCESS              = 0x00004814,
111     GUEST_CS_ACCESS              = 0x00004816,
112     GUEST_SS_ACCESS              = 0x00004818,
113     GUEST_DS_ACCESS              = 0x0000481A,
114     GUEST_FS_ACCESS              = 0x0000481C,
115     GUEST_GS_ACCESS              = 0x0000481E,
116     GUEST_LDTR_ACCESS            = 0x00004820,
117     GUEST_TR_ACCESS              = 0x00004822,
118     GUEST_INT_STATE              = 0x00004824,
119     GUEST_ACTIVITY_STATE         = 0x00004826,
120     GUEST_SMBASE                 = 0x00004828,
121     GUEST_IA32_SYSENTER_CS       = 0x0000482A,
122     /* 32 bit host state field */
123     HOST_IA32_SYSENTER_CS        = 0x00004C00,
124     /* Natural Width Control Fields */
125     CR0_GUEST_HOST_MASK          = 0x00006000,
126     CR4_GUEST_HOST_MASK          = 0x00006002,
127     CR0_READ_SHADOW              = 0x00006004,
128     CR4_READ_SHADOW              = 0x00006006,
129     CR3_TARGET_VALUE_0           = 0x00006008,
130     CR3_TARGET_VALUE_1           = 0x0000600A,
131     CR3_TARGET_VALUE_2           = 0x0000600C,
132     CR3_TARGET_VALUE_3           = 0x0000600E,
133     /* Natural Width Read Only Fields */
134     EXIT_QUALIFICATION           = 0x00006400,
135     IO_RCX                       = 0x00006402,
136     IO_RSI                       = 0x00006404,
137     IO_RDI                       = 0x00006406,
138     IO_RIP                       = 0x00006408,
139     GUEST_LINEAR_ADDR            = 0x0000640A,
140     /* Natural Width Guest State Fields */
141     GUEST_CR0                    = 0x00006800,
142     GUEST_CR3                    = 0x00006802,
143     GUEST_CR4                    = 0x00006804,
144     GUEST_ES_BASE                = 0x00006806,
145     GUEST_CS_BASE                = 0x00006808,
146     GUEST_SS_BASE                = 0x0000680A,
147     GUEST_DS_BASE                = 0x0000680C,
148     GUEST_FS_BASE                = 0x0000680E,
149     GUEST_GS_BASE                = 0x00006810,
150     GUEST_LDTR_BASE              = 0x00006812,
151     GUEST_TR_BASE                = 0x00006814,
152     GUEST_GDTR_BASE              = 0x00006816,
153     GUEST_IDTR_BASE              = 0x00006818,
154     GUEST_DR7                    = 0x0000681A,
155     GUEST_RSP                    = 0x0000681C,
156     GUEST_RIP                    = 0x0000681E,
157     GUEST_RFLAGS                 = 0x00006820,
158     GUEST_PENDING_DEBUG_EXCS     = 0x00006822,
159     GUEST_IA32_SYSENTER_ESP      = 0x00006824,
160     GUEST_IA32_SYSENTER_EIP      = 0x00006826,
161     /* Natural Width Host State Fields */
162     HOST_CR0                     = 0x00006C00,
163     HOST_CR3                     = 0x00006C02,
164     HOST_CR4                     = 0x00006C04,
165     HOST_FS_BASE                 = 0x00006C06,
166     HOST_GS_BASE                 = 0x00006C08,
167     HOST_TR_BASE                 = 0x00006C0A,
168     HOST_GDTR_BASE               = 0x00006C0C,
169     HOST_IDTR_BASE               = 0x00006C0E,
170     HOST_IA32_SYSENTER_ESP       = 0x00006C10,
171     HOST_IA32_SYSENTER_EIP       = 0x00006C12,
172     HOST_RSP                     = 0x00006C14,
173     HOST_RIP                     = 0x00006C16,
174     /* Pin Based VM Execution Controls */
175     /* INTEL MANUAL: 20-10 vol 3B */
176     EXTERNAL_INTERRUPT_EXITING   = 0x00000001,
177     NMI_EXITING                  = 0x00000008,
178     VIRTUAL_NMIS                 = 0x00000020,
179     /* Processor Based VM Execution Controls */
180     /* INTEL MANUAL: 20-11 vol. 3B */
181     INTERRUPT_WINDOWS_EXIT       = 0x00000004,
182     USE_TSC_OFFSETTING           = 0x00000008,
183     HLT_EXITING                  = 0x00000080,
184     INVLPG_EXITING               = 0x00000200,
185     MWAIT_EXITING                = 0x00000400,
186     RDPMC_EXITING                = 0x00000800,
187     RDTSC_EXITING                = 0x00001000,
188     CR8_LOAD_EXITING             = 0x00080000,
189     CR8_STORE_EXITING            = 0x00100000,
190     USE_TPR_SHADOW               = 0x00200000,
191     NMI_WINDOW_EXITING           = 0x00400000,
192     MOVDR_EXITING                = 0x00800000,
193     UNCONDITION_IO_EXITING       = 0x01000000,
194     USE_IO_BITMAPS               = 0x02000000,
195     USE_MSR_BITMAPS              = 0x10000000,
196     MONITOR_EXITING              = 0x20000000,
197     PAUSE_EXITING                = 0x40000000,
198     /* VM-Exit Controls */
199     /* INTEL MANUAL: 20-16 vol. 3B */
200     HOST_ADDR_SPACE_SIZE         = 0x00000200,
201     ACK_IRQ_ON_EXIT              = 0x00008000
202 } vmcs_field_t;
203
204 int vmcs_field_length(vmcs_field_t field);
205 char* vmcs_field_name(vmcs_field_t field);
206
207
208
209 /* VMCS Exit QUALIFICATIONs */
210 struct VMExitIOQual {
211     uint32_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
212     uint32_t dir        : 1; // (0: Out ;; 1: In)
213     uint32_t string     : 1; // (0: not string ;; 1: string)
214     uint32_t REP        : 1; // (0: not REP ;; 1: REP)
215     uint32_t opEnc      : 1; // (0: DX ;; 1: immediate)
216     uint32_t rsvd       : 9; // Set to 0
217     uint32_t port       : 16; // IO Port Number
218 } __attribute__((packed));
219
220
221
222 struct VMExitDBGQual {
223     uint32_t B0         : 1; // Breakpoint 0 condition met
224     uint32_t B1         : 1; // Breakpoint 1 condition met
225     uint32_t B2         : 1; // Breakpoint 2 condition met
226     uint32_t B3         : 1; // Breakpoint 3 condition met
227     uint32_t rsvd       : 9; // reserved to 0
228     uint32_t BD         : 1; // detected DBG reg access
229     uint32_t BS         : 1; // cause either single instr or taken branch
230 } __attribute__((packed));
231
232
233 struct VMExitTSQual {
234     uint32_t selector   : 16; // selector of destination TSS 
235     uint32_t rsvd       : 14; // reserved to 0
236     uint32_t src        : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
237 } __attribute__((packed));
238
239 struct VMExitCRQual {
240     uint32_t crID       : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
241     uint32_t accessType : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
242     uint32_t lmswOpType : 1; // (0: register ; 1: memory)
243     uint32_t rsvd1      : 1; // reserved to 0
244     uint32_t gpr        : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
245     uint32_t rsvd2      : 4; // reserved to 0
246     uint32_t lmswSrc    : 16; // src data for lmsw
247 } __attribute__((packed));
248
249 struct VMExitMovDRQual {
250     uint32_t regID      : 3; // debug register number
251     uint32_t rsvd1      : 1; // reserved to 0
252     uint32_t dir        : 1; // (0: MOV to DR , 1: MOV from DR)
253     uint32_t rsvd2      : 3; // reserved to 0
254     uint32_t gpr        : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
255 } __attribute__((packed));
256
257 /* End Exit Qualifications */
258
259 /* Exit Vector Info */
260 struct VMExitIntInfo {
261     uint32_t nr         : 8; // IRQ number, exception vector, NMI = 2 
262     uint32_t type       : 3; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
263     uint32_t errorCode  : 1; // 1: error Code present
264     uint32_t iret       : 1; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2) 
265     uint32_t rsvd       : 18; // always 0
266     uint32_t valid      : 1; // always 1 if valid
267 } __attribute__((packed));
268
269
270
271
272 /*  End Exit Vector Info */
273
274
275
276
277 /* Segment Selector Access Rights (32 bits) */
278 /* INTEL Manual: 20-4 vol 3B */
279
280
281 struct vmcs_segment_access {
282     union {
283         uint32_t value;
284         struct {
285             uint32_t    type        : 4;
286             uint32_t    desc_type   : 1; 
287             uint32_t    dpl         : 2;
288             uint32_t    present     : 1;
289             uint32_t    rsvd1       : 4;
290             uint32_t    avail       : 1;
291             uint32_t    long_mode   : 1; // CS only (64 bit active), reserved otherwise
292             uint32_t    DB          : 1; 
293             uint32_t    granularity : 1;
294             uint32_t    unusable    : 1; 
295             uint32_t    rsvd2       : 15;
296         } __attribute__((packed));
297     } __attribute__((packed));
298 }__attribute__((packed));
299
300
301 struct vmcs_interrupt_state {
302     uint32_t    sti_blocking    : 1;
303     uint32_t    mov_ss_blocking : 1;
304     uint32_t    smi_blocking    : 1;
305     uint32_t    nmi_blocking    : 1;
306     uint32_t    rsvd1           : 28;
307 } __attribute__((packed));
308
309 struct vmcs_pending_debug {
310     uint32_t    B0  : 1;
311     uint32_t    B1  : 1;
312     uint32_t    B2  : 1;
313     uint32_t    B3  : 1;
314     uint32_t    rsvd1   : 8;
315     uint32_t    break_enabled   : 1;
316     uint32_t    rsvd2   :   1;
317     uint32_t    bs      :   1;
318     uint32_t    rsvd3   :   50;
319 } __attribute__((packed));
320
321
322 struct VMCSExecCtrlFields {
323     uint32_t pinCtrls ; // Table 20-5, Vol 3B. (pg. 20-10)
324     uint32_t procCtrls ; // Table 20-6, Vol 3B. (pg. 20-11)
325     uint32_t execBitmap ; 
326     uint32_t pageFaultErrorMask ; 
327     uint32_t pageFaultErrorMatch ;
328     uint32_t ioBitmapA ; 
329     uint32_t ioBitmapB ;
330     uint64_t tscOffset ;
331     uint32_t cr0GuestHostMask ; // Should be 64 bits?
332     uint32_t cr0ReadShadow ; // Should be 64 bits?
333     uint32_t cr4GuestHostMask ; // Should be 64 bits?
334     uint32_t cr4ReadShadow ; // Should be 64 bits?
335     uint32_t cr3TargetValue0 ; // should be 64 bits?
336     uint32_t cr3TargetValue1 ; // should be 64 bits?
337     uint32_t cr3TargetValue2 ; // should be 64 bits?
338     uint32_t cr3TargetValue3 ; // should be 64 bits?
339     uint32_t cr3TargetCount ;
340     
341
342
343     /* these fields enabled if "use TPR shadow"==1 */
344     /* may not need them */
345     uint64_t virtApicPageAddr ;
346     // uint32_t virtApicPageAddrHigh 
347     uint32_t tprThreshold ;
348     /**/
349
350     uint64_t MSRBitmapsBaseAddr;
351
352     uint64_t vmcsExecPtr ;
353 };
354
355 int CopyOutVMCSExecCtrlFields(struct VMCSExecCtrlFields *p);
356 int CopyInVMCSExecCtrlFields(struct VMCSExecCtrlFields *p);
357
358
359
360
361 struct VMCSExitCtrlFields {
362     uint32_t exitCtrls ; // Table 20-7, Vol. 3B (pg. 20-16)
363     uint32_t msrStoreCount ;
364     uint64_t msrStoreAddr ;
365     uint32_t msrLoadCount ;
366     uint64_t msrLoadAddr ;
367 };
368
369 int CopyOutVMCSExitCtrlFields(struct VMCSExitCtrlFields *p);
370 int CopyInVMCSExitCtrlFields(struct VMCSExitCtrlFields *p);
371
372
373
374 struct VMCSEntryCtrlFields {
375     uint32_t entryCtrls ; // Table 20-9, Vol. 3B (pg. 20-18) 
376     uint32_t msrLoadCount ;
377     uint64_t msrLoadAddr ;
378     uint32_t intInfo ; // Table 20-10, Vol. 3B (pg. 20-19)
379     uint32_t exceptionErrorCode ;
380     uint32_t instrLength ;
381 };
382
383
384 int CopyOutVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p);
385 int CopyInVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p);
386
387
388 struct VMCSExitInfoFields {
389     uint32_t reason; // Table 20-11, Vol. 3B (pg. 20-20)
390     uint32_t qualification ; // Should be 64 bits?
391     uint32_t intInfo ;
392     uint32_t intErrorCode ;
393     uint32_t idtVectorInfo ;
394     uint32_t idtVectorErrorCode ;
395     uint32_t instrLength ;
396     uint64_t guestLinearAddr ; // Should be 64 bits?
397     uint32_t instrInfo ;
398     uint64_t ioRCX ; // Should be 64 bits?
399     uint64_t ioRSI ; // Should be 64 bits?
400     uint64_t ioRDI ; // Should be 64 bits?
401     uint64_t ioRIP ; // Should be 64 bits?
402     uint32_t instrErrorField ;
403
404 };
405
406
407 int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p);
408
409
410
411 typedef struct vmcs_data {
412     uint32_t revision ;
413     uint32_t abort    ;
414 } __attribute__((packed)) vmcs_data_t;
415
416
417 int CopyOutVMCSData(struct VMCSData *p);
418 int CopyInVMCSData(struct VMCSData *p);
419
420 struct VMXRegs {
421     uint32_t edi;
422     uint32_t esi;
423     uint32_t ebp;
424     uint32_t esp;
425     uint32_t ebx;
426     uint32_t edx;
427     uint32_t ecx;
428     uint32_t eax;
429 };
430   
431 void PrintTrace_VMX_Regs(struct VMXRegs *regs);
432 void PrintTrace_VMCSData(struct VMCSData * vmcs);
433 void PrintTrace_VMCSGuestStateArea(struct VMCSGuestStateArea * guestState);
434 void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState);
435 void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls);
436 void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls);
437 void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls);
438 void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo);
439 void PrintTrace_VMCSSegment(char * segname, struct VMCSSegment * seg, int abbr);
440
441
442 //uint_t VMCSRead(uint_t tag, void * val);
443
444
445 #endif // ! __V3VEE__
446
447
448 #endif