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>
21 #include <palacios/vmx_lowlevel.h>
22 #include <palacios/vmm.h>
26 //extern char * exception_names;
28 // Ignores "HIGH" addresses - 32 bit only for now
32 static inline void print_vmcs_field(vmcs_field_t vmcs_index) {
33 int len = v3_vmcs_get_field_len(vmcs_index);
36 if (vmcs_read(vmcs_index, &val, len) != VMX_SUCCESS) {
37 PrintError("VMCS_READ error for index %x\n", vmcs_index);
42 PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint16_t)val);
43 } else if (len == 4) {
44 PrintDebug("%s: %x\n", v3_vmcs_get_field_name(vmcs_index), (uint32_t)val);
45 } else if (len == 8) {
46 PrintDebug("%s: %p\n", v3_vmcs_get_field_name(vmcs_index), (void *)(addr_t)val);
51 static inline void print_vmcs_segments() {
59 void print_debug_vmcs_load_guest() {
60 const int wordsize = sizeof(addr_t);
62 struct vmcs_segment_access tmp_seg;
64 PrintDebug("\n====== Loading Guest State ======\n");
65 PRINT_VMREAD("Guest CR0: %x\n", GUEST_CR0, wordsize);
66 PRINT_VMREAD("Guest CR3: %x\n", GUEST_CR3, wordsize);
67 PRINT_VMREAD("Guest CR4: %x\n", GUEST_CR4, wordsize);
68 PRINT_VMREAD("Guest DR7: %x\n", GUEST_DR7, wordsize);
70 READ_VMCS_SEG(&tmp_seg,CS,wordsize);
71 print_vmcs_segment("CS", &tmp_seg);
73 READ_VMCS_SEG(&tmp_seg,SS,wordsize);
74 print_vmcs_segment("SS", &tmp_seg);
76 READ_VMCS_SEG(&tmp,DS,wordsize);
77 print_vmcs_segment("DS", &tmp_seg);
79 READ_VMCS_SEG(&tmp_seg,ES,wordsize);
80 print_vmcs_segment("ES", &tmp_seg);
82 READ_VMCS_SEG(&tmp_seg,FS,wordsize);
83 print_vmcs_segment("FS", &tmp_seg);
85 READ_VMCS_SEG(&tmp_seg,GS,wordsize);
86 print_vmcs_segment("GS", &tmp_seg);
88 READ_VMCS_SEG(&tmp_seg,TR,wordsize);
89 print_vmcs_segment("TR", &tmp_seg);
91 READ_VMCS_SEG(&tmp_seg,LDTR,wordsize);
92 print_vmcs_segment("LDTR", &tmp_seg);
94 PrintDebug("\n==GDTR==\n");
95 PRINT_VMREAD("GDTR Base: %x\n", GUEST_GDTR_BASE, wordsize);
96 PRINT_VMREAD("GDTR Limit: %x\n", GUEST_GDTR_LIMIT, 32);
99 PrintDebug("\n==LDTR==\n");
100 PRINT_VMREAD("LDTR Base: %x\n", GUEST_LDTR_BASE, wordsize);
101 PRINT_VMREAD("LDTR Limit: %x\n", GUEST_LDTR_LIMIT, 32);
102 PrintDebug("=====\n");
104 PRINT_VMREAD("Guest RSP: %x\n", GUEST_RSP, wordsize);
105 PRINT_VMREAD("Guest RIP: %x\n", GUEST_RIP, wordsize);
106 PRINT_VMREAD("Guest RFLAGS: %x\n", GUEST_RFLAGS, wordsize);
107 PRINT_VMREAD("Guest Activity state: %x\n", GUEST_ACTIVITY_STATE, 32);
108 PRINT_VMREAD("Guest Interruptibility state: %x\n", GUEST_INT_STATE, 32);
109 PRINT_VMREAD("Guest pending debug: %x\n", GUEST_PENDING_DEBUG_EXCS, wordsize);
111 PRINT_VMREAD("IA32_DEBUGCTL: %x\n", GUEST_IA32_DEBUGCTL, 64);
112 PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", GUEST_IA32_SYSENTER_CS, 32);
113 PRINT_VMREAD("IA32_SYSTENTER_ESP: %x\n", GUEST_IA32_SYSENTER_ESP, wordsize);
114 PRINT_VMREAD("IA32_SYSTENTER_EIP: %x\n", GUEST_IA32_SYSENTER_EIP, wordsize);
115 PRINT_VMREAD("IA32_PERF_GLOBAL_CTRL: %x\n", GUEST_IA32_PERF_GLOBAL_CTRL, wordsize);
116 PRINT_VMREAD("VMCS Link Ptr: %x\n", VMCS_LINK_PTR, 64);
117 // TODO: Maybe add VMX preemption timer and PDTE (Intel 20-8 Vol. 3b)
120 void print_debug_load_host() {
121 const int wordsize = sizeof(addr_t);
123 vmcs_segment tmp_seg;
125 PrintDebug("\n====== Host State ========\n");
126 PRINT_VMREAD("Host CR0: %x\n", HOST_CR0, wordsize);
127 PRINT_VMREAD("Host CR3: %x\n", HOST_CR3, wordsize);
128 PRINT_VMREAD("Host CR4: %x\n", HOST_CR4, wordsize);
129 PRINT_VMREAD("Host RSP: %x\n", HOST_RSP, wordsize);
130 PRINT_VMREAD("Host RIP: %x\n", HOST_RIP, wordsize);
131 PRINT_VMREAD("IA32_SYSENTER_CS: %x\n", HOST_IA32_SYSENTER_CS, 32);
132 PRINT_VMREAD("IA32_SYSENTER_ESP: %x\n", HOST_IA32_SYSENTER_ESP, wordsize);
133 PRINT_VMREAD("IA32_SYSENTER_EIP: %x\n", HOST_IA32_SYSENTER_EIP, wordsize);
135 PRINT_VMREAD("Host CS Selector: %x\n", HOST_CS_SELECTOR, 16);
136 PRINT_VMREAD("Host SS Selector: %x\n", HOST_SS_SELECTOR, 16);
137 PRINT_VMREAD("Host DS Selector: %x\n", HOST_DS_SELECTOR, 16);
138 PRINT_VMREAD("Host ES Selector: %x\n", HOST_ES_SELECTOR, 16);
139 PRINT_VMREAD("Host FS Selector: %x\n", HOST_FS_SELECTOR, 16);
140 PRINT_VMREAD("Host GS Selector: %x\n", HOST_GS_SELECTOR, 16);
141 PRINT_VMREAD("Host TR Selector: %x\n", HOST_TR_SELECTOR, 16);
143 PRINT_VMREAD("Host FS Base: %x\n", HOST_FS_BASE, wordsize);
144 PRINT_VMREAD("Host GS Base: %x\n", HOST_GS_BASE, wordsize);
145 PRINT_VMREAD("Host TR Base: %x\n", HOST_TR_BASE, wordsize);
146 PRINT_VMREAD("Host GDTR Base: %x\n", HOST_GDTR_BASE, wordsize);
147 PRINT_VMREAD("Host IDTR Base: %x\n", HOSE_IDTR_BASE, wordsize);
150 void print_vmcs_segment(char * name, vmcs_segment* seg)
152 PrintDebug("\n==VMCS %s Segment==\n",name);
153 PrintDebug("\tSelector: %x\n", seg->selector);
154 PrintDebug("\tBase Address: %x\n", seg->baseAddr);
155 PrintDebug("\tLimit: %x\n", seg->limit);
156 PrintDebug("\tAccess: %x\n", seg->access);
160 * Returns the field length in bytes
162 int v3_vmcs_get_field_len(vmcs_field_t field)
166 case VMCS_GUEST_ES_SELECTOR:
167 case VMCS_GUEST_CS_SELECTOR:
168 case VMCS_GUEST_SS_SELECTOR:
169 case VMCS_GUEST_DS_SELECTOR:
170 case VMCS_GUEST_FS_SELECTOR:
171 case VMCS_GUEST_GS_SELECTOR:
172 case VMCS_GUEST_LDTR_SELECTOR:
173 case VMCS_GUEST_TR_SELECTOR:
174 /* 16 bit host state */
175 case VMCS_HOST_ES_SELECTOR:
176 case VMCS_HOST_CS_SELECTOR:
177 case VMCS_HOST_SS_SELECTOR:
178 case VMCS_HOST_DS_SELECTOR:
179 case VMCS_HOST_FS_SELECTOR:
180 case VMCS_HOST_GS_SELECTOR:
181 case VMCS_HOST_TR_SELECTOR:
183 /* 64 bit control fields */
184 case IO_BITMAP_A_ADDR:
185 case IO_BITMAP_A_ADDR_HIGH:
186 case IO_BITMAP_B_ADDR:
187 case IO_BITMAP_B_ADDR_HIGH:
189 case MSR_BITMAPS_HIGH:
190 case VM_EXIT_MSR_STORE_ADDR:
191 case VM_EXIT_MSR_STORE_ADDR_HIGH:
192 case VM_EXIT_MSR_LOAD_ADDR:
193 case VM_EXIT_MSR_LOAD_ADDR_HIGH:
194 case VM_ENTRY_MSR_LOAD_ADDR:
195 case VM_ENTRY_MSR_LOAD_ADDR_HIGH:
197 case VMCS_EXEC_PTR_HIGH:
199 case TSC_OFFSET_HIGH:
200 case VIRT_APIC_PAGE_ADDR:
201 case VIRT_APIC_PAGE_ADDR_HIGH:
202 /* 64 bit guest state fields */
204 case VMCS_LINK_PTR_HIGH:
205 case GUEST_IA32_DEBUGCTL:
206 case GUEST_IA32_DEBUGCTL_HIGH:
207 case GUEST_IA32_PERF_GLOBAL_CTRL:
208 case GUEST_IA32_PERF_GLOBAL_CTRL_HIGH:
210 /* 32 bit control fields */
211 case PIN_VM_EXEC_CTRLS:
212 case PROC_VM_EXEC_CTRLS:
213 case EXCEPTION_BITMAP:
214 case PAGE_FAULT_ERROR_MASK:
215 case PAGE_FAULT_ERROR_MATCH:
216 case CR3_TARGET_COUNT:
218 case VM_EXIT_MSR_STORE_COUNT:
219 case VM_EXIT_MSR_LOAD_COUNT:
221 case VM_ENTRY_MSR_LOAD_COUNT:
222 case VM_ENTRY_INT_INFO_FIELD:
223 case VM_ENTRY_EXCEPTION_ERROR:
224 case VM_ENTRY_INSTR_LENGTH:
226 /* 32 bit Read Only data fields */
229 case VM_EXIT_INT_INFO:
230 case VM_EXIT_INT_ERROR:
231 case IDT_VECTOR_INFO:
232 case IDT_VECTOR_ERROR:
233 case VM_EXIT_INSTR_LENGTH:
235 /* 32 bit Guest state fields */
242 case GUEST_LDTR_LIMIT:
244 case GUEST_GDTR_LIMIT:
245 case GUEST_IDTR_LIMIT:
246 case GUEST_ES_ACCESS:
247 case GUEST_CS_ACCESS:
248 case GUEST_SS_ACCESS:
249 case GUEST_DS_ACCESS:
250 case GUEST_FS_ACCESS:
251 case GUEST_GS_ACCESS:
252 case GUEST_LDTR_ACCESS:
253 case GUEST_TR_ACCESS:
254 case GUEST_INT_STATE:
255 case GUEST_ACTIVITY_STATE:
257 case GUEST_IA32_SYSENTER_CS:
258 /* 32 bit host state field */
259 case HOST_IA32_SYSENTER_CS:
261 /* Natural Width Control Fields */
262 case CR0_GUEST_HOST_MASK:
263 case CR4_GUEST_HOST_MASK:
264 case CR0_READ_SHADOW:
265 case CR4_READ_SHADOW:
266 case CR3_TARGET_VALUE_0:
267 case CR3_TARGET_VALUE_1:
268 case CR3_TARGET_VALUE_2:
269 case CR3_TARGET_VALUE_3:
270 /* Natural Width Read Only Fields */
271 case EXIT_QUALIFICATION:
276 case GUEST_LINEAR_ADDR:
277 /* Natural Width Guest State Fields */
287 case GUEST_LDTR_BASE:
289 case GUEST_GDTR_BASE:
290 case GUEST_IDTR_BASE:
295 case GUEST_PENDING_DEBUG_EXCS:
296 case GUEST_IA32_SYSENTER_ESP:
297 case GUEST_IA32_SYSENTER_EIP:
298 /* Natural Width Host State Fields */
307 case HOST_IA32_SYSENTER_ESP:
308 case HOST_IA32_SYSENTER_EIP:
321 char* v3_vmcs_get_field_name(vmcs_field_t field)
325 case VMCS_GUEST_ES_SELECTOR:
326 return "VMCS_GUEST_ES_SELECTOR";
327 case VMCS_GUEST_CS_SELECTOR:
328 return "VMCS_GUEST_CS_SELECTOR";
329 case VMCS_GUEST_SS_SELECTOR:
330 return "VMCS_GUEST_SS_SELECTOR";
331 case VMCS_GUEST_DS_SELECTOR:
332 return "VMCS_GUEST_DS_SELECTOR";
333 case VMCS_GUEST_FS_SELECTOR:
334 return "VMCS_GUEST_FS_SELECTOR";
335 case VMCS_GUEST_GS_SELECTOR:
336 return "VMCS_GUEST_GS_SELECTOR";
337 case VMCS_GUEST_LDTR_SELECTOR:
338 return "VMCS_GUEST_LDTR_SELECTOR";
339 case VMCS_GUEST_TR_SELECTOR:
340 return "VMCS_GUEST_TR_SELECTOR";
341 case VMCS_HOST_ES_SELECTOR:
342 return "VMCS_HOST_ES_SELECTOR";
343 case VMCS_HOST_CS_SELECTOR:
344 return "VMCS_HOST_CS_SELECTOR";
345 case VMCS_HOST_SS_SELECTOR:
346 return "VMCS_HOST_SS_SELECTOR";
347 case VMCS_HOST_DS_SELECTOR:
348 return "VMCS_HOST_DS_SELECTOR";
349 case VMCS_HOST_FS_SELECTOR:
350 return "VMCS_HOST_FS_SELECTOR";
351 case VMCS_HOST_GS_SELECTOR:
352 return "VMCS_HOST_GS_SELECTOR";
353 case VMCS_HOST_TR_SELECTOR:
354 return "VMCS_HOST_TR_SELECTOR";
355 case IO_BITMAP_A_ADDR:
356 return "IO_BITMAP_A_ADDR";
357 case IO_BITMAP_A_ADDR_HIGH:
358 return "IO_BITMAP_A_ADDR_HIGH";
359 case IO_BITMAP_B_ADDR:
360 return "IO_BITMAP_B_ADDR";
361 case IO_BITMAP_B_ADDR_HIGH:
362 return "IO_BITMAP_B_ADDR_HIGH";
364 return "MSR_BITMAPS";
365 case MSR_BITMAPS_HIGH:
366 return "MSR_BITMAPS_HIGH";
367 case VM_EXIT_MSR_STORE_ADDR:
368 return "VM_EXIT_MSR_STORE_ADDR";
369 case VM_EXIT_MSR_STORE_ADDR_HIGH:
370 return "VM_EXIT_MSR_STORE_ADDR_HIGH";
371 case VM_EXIT_MSR_LOAD_ADDR:
372 return "VM_EXIT_MSR_LOAD_ADDR";
373 case VM_EXIT_MSR_LOAD_ADDR_HIGH:
374 return "VM_EXIT_MSR_LOAD_ADDR_HIGH";
375 case VM_ENTRY_MSR_LOAD_ADDR:
376 return "VM_ENTRY_MSR_LOAD_ADDR";
377 case VM_ENTRY_MSR_LOAD_ADDR_HIGH:
378 return "VM_ENTRY_MSR_LOAD_ADDR_HIGH";
380 return "VMCS_EXEC_PTR";
381 case VMCS_EXEC_PTR_HIGH:
382 return "VMCS_EXEC_PTR_HIGH";
385 case TSC_OFFSET_HIGH:
386 return "TSC_OFFSET_HIGH";
387 case VIRT_APIC_PAGE_ADDR:
388 return "VIRT_APIC_PAGE_ADDR";
389 case VIRT_APIC_PAGE_ADDR_HIGH:
390 return "VIRT_APIC_PAGE_ADDR_HIGH";
392 return "VMCS_LINK_PTR";
393 case VMCS_LINK_PTR_HIGH:
394 return "VMCS_LINK_PTR_HIGH";
395 case GUEST_IA32_DEBUGCTL:
396 return "GUEST_IA32_DEBUGCTL";
397 case GUEST_IA32_DEBUGCTL_HIGH:
398 return "GUEST_IA32_DEBUGCTL_HIGH";
399 case GUEST_IA32_PERF_GLOBAL_CTRL:
400 return "GUEST_IA32_PERF_GLOBAL_CTRL";
401 case GUEST_IA32_PERF_GLOBAL_CTRL_HIGH:
402 return "GUEST_IA32_PERF_GLOBAL_CTRL_HIGH";
403 case PIN_VM_EXEC_CTRLS:
404 return "PIN_VM_EXEC_CTRLS";
405 case PROC_VM_EXEC_CTRLS:
406 return "PROC_VM_EXEC_CTRLS";
407 case EXCEPTION_BITMAP:
408 return "EXCEPTION_BITMAP";
409 case PAGE_FAULT_ERROR_MASK:
410 return "PAGE_FAULT_ERROR_MASK";
411 case PAGE_FAULT_ERROR_MATCH:
412 return "PAGE_FAULT_ERROR_MATCH";
413 case CR3_TARGET_COUNT:
414 return "CR3_TARGET_COUNT";
416 return "VM_EXIT_CTRLS";
417 case VM_EXIT_MSR_STORE_COUNT:
418 return "VM_EXIT_MSR_STORE_COUNT";
419 case VM_EXIT_MSR_LOAD_COUNT:
420 return "VM_EXIT_MSR_LOAD_COUNT";
422 return "VM_ENTRY_CTRLS";
423 case VM_ENTRY_MSR_LOAD_COUNT:
424 return "VM_ENTRY_MSR_LOAD_COUNT";
425 case VM_ENTRY_INT_INFO_FIELD:
426 return "VM_ENTRY_INT_INFO_FIELD";
427 case VM_ENTRY_EXCEPTION_ERROR:
428 return "VM_ENTRY_EXCEPTION_ERROR";
429 case VM_ENTRY_INSTR_LENGTH:
430 return "VM_ENTRY_INSTR_LENGTH";
432 return "TPR_THRESHOLD";
434 return "VM_INSTR_ERROR";
436 return "EXIT_REASON";
437 case VM_EXIT_INT_INFO:
438 return "VM_EXIT_INT_INFO";
439 case VM_EXIT_INT_ERROR:
440 return "VM_EXIT_INT_ERROR";
441 case IDT_VECTOR_INFO:
442 return "IDT_VECTOR_INFO";
443 case IDT_VECTOR_ERROR:
444 return "IDT_VECTOR_ERROR";
445 case VM_EXIT_INSTR_LENGTH:
446 return "VM_EXIT_INSTR_LENGTH";
448 return "VMX_INSTR_INFO";
450 return "GUEST_ES_LIMIT";
452 return "GUEST_CS_LIMIT";
454 return "GUEST_SS_LIMIT";
456 return "GUEST_DS_LIMIT";
458 return "GUEST_FS_LIMIT";
460 return "GUEST_GS_LIMIT";
461 case GUEST_LDTR_LIMIT:
462 return "GUEST_LDTR_LIMIT";
464 return "GUEST_TR_LIMIT";
465 case GUEST_GDTR_LIMIT:
466 return "GUEST_GDTR_LIMIT";
467 case GUEST_IDTR_LIMIT:
468 return "GUEST_IDTR_LIMIT";
469 case GUEST_ES_ACCESS:
470 return "GUEST_ES_ACCESS";
471 case GUEST_CS_ACCESS:
472 return "GUEST_CS_ACCESS";
473 case GUEST_SS_ACCESS:
474 return "GUEST_SS_ACCESS";
475 case GUEST_DS_ACCESS:
476 return "GUEST_DS_ACCESS";
477 case GUEST_FS_ACCESS:
478 return "GUEST_FS_ACCESS";
479 case GUEST_GS_ACCESS:
480 return "GUEST_GS_ACCESS";
481 case GUEST_LDTR_ACCESS:
482 return "GUEST_LDTR_ACCESS";
483 case GUEST_TR_ACCESS:
484 return "GUEST_TR_ACCESS";
485 case GUEST_INT_STATE:
486 return "GUEST_INT_STATE";
487 case GUEST_ACTIVITY_STATE:
488 return "GUEST_ACTIVITY_STATE";
490 return "GUEST_SMBASE";
491 case GUEST_IA32_SYSENTER_CS:
492 return "GUEST_IA32_SYSENTER_CS";
493 case HOST_IA32_SYSENTER_CS:
494 return "HOST_IA32_SYSENTER_CS";
495 case CR0_GUEST_HOST_MASK:
496 return "CR0_GUEST_HOST_MASK";
497 case CR4_GUEST_HOST_MASK:
498 return "CR4_GUEST_HOST_MASK";
499 case CR0_READ_SHADOW:
500 return "CR0_READ_SHADOW";
501 case CR4_READ_SHADOW:
502 return "CR4_READ_SHADOW";
503 case CR3_TARGET_VALUE_0:
504 return "CR3_TARGET_VALUE_0";
505 case CR3_TARGET_VALUE_1:
506 return "CR3_TARGET_VALUE_1";
507 case CR3_TARGET_VALUE_2:
508 return "CR3_TARGET_VALUE_2";
509 case CR3_TARGET_VALUE_3:
510 return "CR3_TARGET_VALUE_3";
511 case EXIT_QUALIFICATION:
512 return "EXIT_QUALIFICATION";
521 case GUEST_LINEAR_ADDR:
522 return "GUEST_LINEAR_ADDR";
530 return "GUEST_ES_BASE";
532 return "GUEST_CS_BASE";
534 return "GUEST_SS_BASE";
536 return "GUEST_DS_BASE";
538 return "GUEST_FS_BASE";
540 return "GUEST_GS_BASE";
541 case GUEST_LDTR_BASE:
542 return "GUEST_LDTR_BASE";
544 return "GUEST_TR_BASE";
545 case GUEST_GDTR_BASE:
546 return "GUEST_GDTR_BASE";
547 case GUEST_IDTR_BASE:
548 return "GUEST_IDTR_BASE";
556 return "GUEST_RFLAGS";
557 case GUEST_PENDING_DEBUG_EXCS:
558 return "GUEST_PENDING_DEBUG_EXCS";
559 case GUEST_IA32_SYSENTER_ESP:
560 return "GUEST_IA32_SYSENTER_ESP";
561 case GUEST_IA32_SYSENTER_EIP:
562 return "GUEST_IA32_SYSENTER_EIP";
570 return "HOST_FS_BASE";
572 return "HOST_GS_BASE";
574 return "HOST_TR_BASE";
576 return "HOST_GDTR_BASE";
578 return "HOST_IDTR_BASE";
579 case HOST_IA32_SYSENTER_ESP:
580 return "HOST_IA32_SYSENTER_ESP";
581 case HOST_IA32_SYSENTER_EIP:
582 return "HOST_IA32_SYSENTER_EIP";