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 refactoring
[palacios.git] / palacios / src / palacios / vmcs.c
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, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmcs.h>
21
22
23
24 //extern char * exception_names;
25 //
26 // Ignores "HIGH" addresses - 32 bit only for now
27 //
28
29
30 static inline void print_vmcs_field(uint_t vmcs_index) {
31     int len = v3_vmcs_get_field_len(vmcs_index);
32     addr_t val;
33     
34     if (vmcs_read(vmcs_index, &val, len) != VMX_SUCCESS) {
35         PrintError("VMCS_READ error for index %x\n", vmcs_index);
36         return;
37     };
38     
39     if (len == 2) {
40         PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint16_t)val);
41     } else if (len == 4) {
42         PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint32_t)val);
43     } else if (len == 8) {
44         PrintDebug("%s: %p\n", v3_vmcs_get_field_name(vmcs_index), (void *)(addr_t)val);
45     }
46 }
47
48
49 static inline void print_vmcs_segments() {
50     // see vm_guest.c
51 }
52
53
54
55
56
57 void print_debug_vmcs_load_guest() {
58     const int wordsize = sizeof(addr_t);
59     uint64_t temp;
60     vmcs_segment tmp_seg;
61
62     PrintDebug("\n====== Loading Guest State ======\n");
63     PRINT_VMREAD("Guest CR0: %x\n", GUEST_CR0, wordsize);
64     PRINT_VMREAD("Guest CR3: %x\n", GUEST_CR3, wordsize);
65     PRINT_VMREAD("Guest CR4: %x\n", GUEST_CR4, wordsize);
66     PRINT_VMREAD("Guest DR7: %x\n", GUEST_DR7, wordsize);
67
68     READ_VMCS_SEG(&tmp_seg,CS,wordsize);
69     print_vmcs_segment("CS", &tmp_seg);
70     
71     READ_VMCS_SEG(&tmp_seg,SS,wordsize);
72     print_vmcs_segment("SS", &tmp_seg);
73
74     READ_VMCS_SEG(&tmp,DS,wordsize);
75     print_vmcs_segment("DS", &tmp_seg);
76
77     READ_VMCS_SEG(&tmp_seg,ES,wordsize);
78     print_vmcs_segment("ES", &tmp_seg);
79
80     READ_VMCS_SEG(&tmp_seg,FS,wordsize);
81     print_vmcs_segment("FS", &tmp_seg);
82
83     READ_VMCS_SEG(&tmp_seg,GS,wordsize);
84     print_vmcs_segment("GS", &tmp_seg);
85
86     READ_VMCS_SEG(&tmp_seg,TR,wordsize);
87     print_vmcs_segment("TR", &tmp_seg);
88
89     READ_VMCS_SEG(&tmp_seg,LDTR,wordsize);
90     print_vmcs_segment("LDTR", &tmp_seg);
91     
92     PrintDebug("\n==GDTR==\n");
93     PRINT_VMREAD("GDTR Base: %x\n", GUEST_GDTR_BASE, wordsize);
94     PRINT_VMREAD("GDTR Limit: %x\n", GUEST_GDTR_LIMIT, 32);
95     PrintDebug("====\n");
96
97     PrintDebug("\n==LDTR==\n");
98     PRINT_VMREAD("LDTR Base: %x\n", GUEST_LDTR_BASE, wordsize);
99     PRINT_VMREAD("LDTR Limit: %x\n", GUEST_LDTR_LIMIT, 32);
100     PrintDebug("=====\n");
101
102     PRINT_VMREAD("Guest RSP: %x\n", GUEST_RSP, wordsize);
103     PRINT_VMREAD("Guest RIP: %x\n", GUEST_RIP, wordsize);
104     PRINT_VMREAD("Guest RFLAGS: %x\n", GUEST_RFLAGS, wordsize);
105     PRINT_VMREAD("Guest Activity state: %x\n", GUEST_ACTIVITY_STATE, 32);
106     PRINT_VMREAD("Guest Interruptibility state: %x\n", GUEST_INT_STATE, 32);
107     PRINT_VMREAD("Guest pending debug: %x\n", GUEST_PENDING_DEBUG_EXCS, wordsize);
108
109     PRINT_VMREAD("IA32_DEBUGCTL: %x\n", GUEST_IA32_DEBUGCTL, 64);
110     PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", GUEST_IA32_SYSENTER_CS, 32);
111     PRINT_VMREAD("IA32_SYSTENTER_ESP: %x\n", GUEST_IA32_SYSENTER_ESP, wordsize);
112     PRINT_VMREAD("IA32_SYSTENTER_EIP: %x\n", GUEST_IA32_SYSENTER_EIP, wordsize);
113     PRINT_VMREAD("IA32_PERF_GLOBAL_CTRL: %x\n", GUEST_IA32_PERF_GLOBAL_CTRL, wordsize);
114     PRINT_VMREAD("VMCS Link Ptr: %x\n", VMCS_LINK_PTR, 64);
115     // TODO: Maybe add VMX preemption timer and PDTE (Intel 20-8 Vol. 3b)
116 }
117
118 void print_debug_load_host() {
119     const int wordsize = sizeof(addr_t);
120     uint64_t temp;
121     vmcs_segment tmp_seg;
122
123     PrintDebug("\n====== Host State ========\n");
124     PRINT_VMREAD("Host CR0: %x\n", HOST_CR0, wordsize);
125     PRINT_VMREAD("Host CR3: %x\n", HOST_CR3, wordsize);
126     PRINT_VMREAD("Host CR4: %x\n", HOST_CR4, wordsize);
127     PRINT_VMREAD("Host RSP: %x\n", HOST_RSP, wordsize);
128     PRINT_VMREAD("Host RIP: %x\n", HOST_RIP, wordsize);
129     PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", HOST_IA32_SYSENTER_CS, 32);
130     PRINT_VMREAD("IA32_SYSENTER_ESP: %x\n", HOST_IA32_SYSENTER_ESP, wordsize);
131     PRINT_VMREAD("IA32_SYSENTER_EIP: %x\n", HOST_IA32_SYSENTER_EIP, wordsize);
132         
133     PRINT_VMREAD("Host CS Selector: %x\n", HOST_CS_SELECTOR, 16);
134     PRINT_VMREAD("Host SS Selector: %x\n", HOST_SS_SELECTOR, 16);
135     PRINT_VMREAD("Host DS Selector: %x\n", HOST_DS_SELECTOR, 16);
136     PRINT_VMREAD("Host ES Selector: %x\n", HOST_ES_SELECTOR, 16);
137     PRINT_VMREAD("Host FS Selector: %x\n", HOST_FS_SELECTOR, 16);
138     PRINT_VMREAD("Host GS Selector: %x\n", HOST_GS_SELECTOR, 16);
139     PRINT_VMREAD("Host TR Selector: %x\n", HOST_TR_SELECTOR, 16);
140
141     PRINT_VMREAD("Host FS Base: %x\n", HOST_FS_BASE, wordsize);
142     PRINT_VMREAD("Host GS Base: %x\n", HOST_GS_BASE, wordsize);
143     PRINT_VMREAD("Host TR Base: %x\n", HOST_TR_BASE, wordsize);
144     PRINT_VMREAD("Host GDTR Base: %x\n", HOST_GDTR_BASE, wordsize);
145     PRINT_VMREAD("Host IDTR Base: %x\n", HOSE_IDTR_BASE, wordsize);
146 }
147
148 void print_vmcs_segment(char * name, vmcs_segment* seg)
149 {
150     PrintDebug("\n==VMCS %s Segment==\n",name);
151     PrintDebug("\tSelector: %x\n", seg->selector);
152     PrintDebug("\tBase Address: %x\n", seg->baseAddr);
153     PrintDebug("\tLimit: %x\n", seg->limit);
154     PrintDebug("\tAccess: %x\n", seg->access);
155 }
156
157 void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState) {
158   PrintTrace("\n==> Host State Area\n");
159   PrintTrace("HOST_CR0: %x\n", (uint_t)hostState->cr0);
160   PrintTrace("HOST_CR3: %x\n", (uint_t)hostState->cr3);
161   PrintTrace("HOST_CR4: %x\n", (uint_t)hostState->cr4);
162   PrintTrace("HOST_RSP: %x\n", (uint_t)hostState->rsp);
163   PrintTrace("HOST_RIP: %x\n", (uint_t)hostState->rip);
164   PrintTrace("VMCS_HOST_CS_SELECTOR: %x\n", (uint_t)hostState->csSelector);
165   PrintTrace("VMCS_HOST_SS_SELECTOR: %x\n", (uint_t)hostState->ssSelector);
166   PrintTrace("VMCS_HOST_DS_SELECTOR: %x\n", (uint_t)hostState->dsSelector);
167   PrintTrace("VMCS_HOST_ES_SELECTOR: %x\n", (uint_t)hostState->esSelector);
168   PrintTrace("VMCS_HOST_FS_SELECTOR: %x\n", (uint_t)hostState->fsSelector);
169   PrintTrace("VMCS_HOST_GS_SELECTOR: %x\n", (uint_t)hostState->gsSelector);
170   PrintTrace("VMCS_HOST_TR_SELECTOR: %x\n", (uint_t)hostState->trSelector);
171   PrintTrace("HOST_FS_BASE: %x\n", (uint_t)hostState->fsBaseAddr);
172   PrintTrace("HOST_GS_BASE: %x\n", (uint_t)hostState->gsBaseAddr);
173   PrintTrace("HOST_TR_BASE: %x\n", (uint_t)hostState->trBaseAddr);
174   PrintTrace("HOST_GDTR_BASE: %x\n", (uint_t)hostState->gdtrBaseAddr);
175   PrintTrace("HOST_IDTR_BASE: %x\n", (uint_t)hostState->idtrBaseAddr);
176   PrintTrace("HOST_IA32_SYSENTER_CS: %x\n", (uint_t)hostState->sysenter_cs);
177   PrintTrace("HOST_IA32_SYSENTER_ESP: %x\n", (uint_t)hostState->sysenter_esp);
178   PrintTrace("HOST_IA32_SYSENTER_EIP: %x\n", (uint_t)hostState->sysenter_eip);
179 }
180
181 void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls) {
182   PrintTrace("\n==> VM-Execution Controls:\n");
183   PrintTrace("PIN_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->pinCtrls);
184   PrintTrace("PROC_VM_EXEC_CTRLS: %x\n", (uint_t) execCtrls->procCtrls);
185   PrintTrace("EXCEPTION_BITMAP: %x\n", (uint_t) execCtrls->execBitmap);
186   PrintTrace("PAGE_FAULT_ERROR_MASK: %x\n", (uint_t) execCtrls->pageFaultErrorMask);
187   PrintTrace("PAGE_FAULT_ERROR_MATCH: %x\n", (uint_t) execCtrls->pageFaultErrorMatch);
188   PrintTrace("IO_BITMAP_A_ADDR: %x\n", (uint_t) execCtrls->ioBitmapA);
189   //  PrintTrace("IO_BITMAP_A_ADDR_HIGH: %x\n", (uint_t) execCtrls->);
190   PrintTrace("IO_BITMAP_B_ADDR: %x\n", (uint_t) execCtrls->ioBitmapB);
191   // PrintTrace("IO_BITMAP_B_ADDR_HIGH: %x\n", (uint_t) execCtrls->);
192   PrintTrace("TSC_OFFSET: %x\n", (uint_t) execCtrls->tscOffset & 0xffffffff);
193   PrintTrace("TSC_OFFSET_HIGH: %x\n", (uint_t) (execCtrls->tscOffset >> 32) & 0xffffffff);
194   PrintTrace("CR0_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr0GuestHostMask);
195   PrintTrace("CR0_READ_SHADOW: %x\n", (uint_t) execCtrls->cr0ReadShadow);
196   PrintTrace("CR4_GUEST_HOST_MASK: %x\n", (uint_t) execCtrls->cr4GuestHostMask);
197   PrintTrace("CR4_READ_SHADOW: %x\n", (uint_t) execCtrls->cr4ReadShadow);
198   PrintTrace("CR3_TARGET_COUNT: %x\n", (uint_t) execCtrls->cr3TargetCount);
199   PrintTrace("CR3_TARGET_VALUE_0: %x\n", (uint_t) execCtrls->cr3TargetValue0);
200   PrintTrace("CR3_TARGET_VALUE_1: %x\n", (uint_t) execCtrls->cr3TargetValue1);
201   PrintTrace("CR3_TARGET_VALUE_2: %x\n", (uint_t) execCtrls->cr3TargetValue2);
202   PrintTrace("CR3_TARGET_VALUE_3: %x\n", (uint_t) execCtrls->cr3TargetValue3);
203   PrintTrace("VIRT_APIC_PAGE_ADDR: %x\n", (uint_t) execCtrls->virtApicPageAddr & 0xffffffff);
204   PrintTrace("VIRT_APIC_PAGE_ADDR_HIGH: %x\n", (uint_t) (execCtrls->virtApicPageAddr >> 32) & 0xffffffff);
205   PrintTrace("TPR_THRESHOLD: %x\n", (uint_t) execCtrls->tprThreshold);
206   PrintTrace("MSR_BITMAPS: %x\n", (uint_t) execCtrls->MSRBitmapsBaseAddr & 0xffffffff);
207   PrintTrace("MSR_BITMAPS_HIGH: %x\n", (uint_t) (execCtrls->MSRBitmapsBaseAddr >> 32) & 0xffffffff);
208   PrintTrace("VMCS_EXEC_PTR: %x\n", (uint_t) execCtrls->vmcsExecPtr & 0xffffffff);
209   PrintTrace("VMCS_EXEC_PTR_HIGH: %x\n", (uint_t) (execCtrls->vmcsExecPtr >> 32) & 0xffffffff);
210 }
211
212 void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls) {
213   PrintTrace("\n==> VM Exit Controls\n");
214   PrintTrace("VM_EXIT_CTRLS: %x\n", (uint_t) exitCtrls->exitCtrls);
215   PrintTrace("VM_EXIT_MSR_STORE_COUNT: %x\n", (uint_t) exitCtrls->msrStoreCount);
216   PrintTrace("VM_EXIT_MSR_STORE_ADDR: %x\n", (uint_t) exitCtrls->msrStoreAddr & 0xffffffff);
217   PrintTrace("VM_EXIT_MSR_STORE_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrStoreAddr >> 32) & 0xffffffff);
218   PrintTrace("VM_EXIT_MSR_LOAD_COUNT: %x\n", (uint_t) exitCtrls->msrLoadCount);
219   PrintTrace("VM_EXIT_MSR_LOAD_ADDR: %x\n", (uint_t) exitCtrls->msrLoadAddr & 0xffffffff);
220   PrintTrace("VM_EXIT_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (exitCtrls->msrLoadAddr >> 32) & 0xffffffff);
221 }
222
223 void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls) {
224   PrintTrace("\n==> VM Entry Controls\n");
225   PrintTrace("VM_ENTRY_CTRLS: %x\n", (uint_t) entryCtrls->entryCtrls);
226   PrintTrace("VM_ENTRY_MSR_LOAD_COUNT: %x\n", (uint_t) entryCtrls->msrLoadCount);
227   PrintTrace("VM_ENTRY_MSR_LOAD_ADDR: %x\n", (uint_t) entryCtrls->msrLoadAddr & 0xffffffff);
228   PrintTrace("VM_ENTRY_MSR_LOAD_ADDR_HIGH: %x\n", (uint_t) (entryCtrls->msrLoadAddr >> 32) & 0xffffffff);
229   PrintTrace("VM_ENTRY_INT_INFO_FIELD: %x\n", (uint_t) entryCtrls->intInfo);
230   PrintTrace("VM_ENTRY_EXCEPTION_ERROR: %x\n", (uint_t) entryCtrls->exceptionErrorCode);
231   PrintTrace("VM_ENTRY_INSTR_LENGTH: %x\n", (uint_t) entryCtrls->instrLength);
232 }
233
234 void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo) {
235   PrintTrace("\n==> VM Exit Info\n");
236   PrintTrace("EXIT_REASON: %x\n", (uint_t) exitInfo->reason);
237   PrintTrace("EXIT_QUALIFICATION: %x\n", (uint_t) exitInfo->qualification);
238   PrintTrace("VM_EXIT_INT_INFO: %x\n", (uint_t) exitInfo->intInfo);
239   PrintTrace("VM_EXIT_INT_ERROR: %x\n", (uint_t) exitInfo->intErrorCode);
240   PrintTrace("IDT_VECTOR_INFO: %x\n", (uint_t) exitInfo->idtVectorInfo);
241   PrintTrace("IDT_VECTOR_ERROR: %x\n", (uint_t) exitInfo->idtVectorErrorCode);
242   PrintTrace("VM_EXIT_INSTR_LENGTH: %x\n", (uint_t) exitInfo->instrLength);
243   PrintTrace("GUEST_LINEAR_ADDR: %x\n", (uint_t) exitInfo->guestLinearAddr);
244   PrintTrace("VMX_INSTR_INFO: %x\n", (uint_t) exitInfo->instrInfo);
245   PrintTrace("IO_RCX: %x\n", (uint_t) exitInfo->ioRCX);
246   PrintTrace("IO_RSI: %x\n", (uint_t) exitInfo->ioRSI);
247   PrintTrace("IO_RDI: %x\n", (uint_t) exitInfo->ioRDI);
248   PrintTrace("IO_RIP: %x\n", (uint_t) exitInfo->ioRIP);
249   PrintTrace("VM_INSTR_ERROR: %x\n", (uint_t) exitInfo->instrErrorField);
250 }
251
252
253 void PrintTrace_VMCSData(struct VMCSData * vmcs) {
254   PrintTrace("VMCSData Structure\n");
255
256   PrintTrace_VMCSGuestStateArea(&(vmcs->guestStateArea));
257   PrintTrace_VMCSHostStateArea(&(vmcs->hostStateArea));
258   PrintTrace_VMCSExecCtrlFields(&(vmcs->execCtrlFields));
259   PrintTrace_VMCSExitCtrlFields(&(vmcs->exitCtrlFields));
260   PrintTrace_VMCSEntryCtrlFields(&(vmcs->entryCtrlFields));
261   PrintTrace_VMCSExitInfoFields(&(vmcs->exitInfoFields));
262   PrintTrace("\n");
263 }