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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmcs.h>
24 //extern char * exception_names;
26 // Ignores "HIGH" addresses - 32 bit only for now
30 static inline void print_vmcs_field(uint_t vmcs_index) {
31 int len = v3_vmcs_get_field_len(vmcs_index);
34 if (vmcs_read(vmcs_index, &val, len) != VMX_SUCCESS) {
35 PrintError("VMCS_READ error for index %x\n", vmcs_index);
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);
49 static inline void print_vmcs_segments() {
57 void print_debug_vmcs_load_guest() {
58 const int wordsize = sizeof(addr_t);
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);
68 READ_VMCS_SEG(&tmp_seg,CS,wordsize);
69 print_vmcs_segment("CS", &tmp_seg);
71 READ_VMCS_SEG(&tmp_seg,SS,wordsize);
72 print_vmcs_segment("SS", &tmp_seg);
74 READ_VMCS_SEG(&tmp,DS,wordsize);
75 print_vmcs_segment("DS", &tmp_seg);
77 READ_VMCS_SEG(&tmp_seg,ES,wordsize);
78 print_vmcs_segment("ES", &tmp_seg);
80 READ_VMCS_SEG(&tmp_seg,FS,wordsize);
81 print_vmcs_segment("FS", &tmp_seg);
83 READ_VMCS_SEG(&tmp_seg,GS,wordsize);
84 print_vmcs_segment("GS", &tmp_seg);
86 READ_VMCS_SEG(&tmp_seg,TR,wordsize);
87 print_vmcs_segment("TR", &tmp_seg);
89 READ_VMCS_SEG(&tmp_seg,LDTR,wordsize);
90 print_vmcs_segment("LDTR", &tmp_seg);
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);
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");
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);
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)
118 void print_debug_load_host() {
119 const int wordsize = sizeof(addr_t);
121 vmcs_segment tmp_seg;
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);
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);
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);
148 void print_vmcs_segment(char * name, vmcs_segment* seg)
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);
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);
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);
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);
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);
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);
253 void PrintTrace_VMCSData(struct VMCSData * vmcs) {
254 PrintTrace("VMCSData Structure\n");
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));