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>
23 #include <palacios/vmx.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_ctrl_regs.h>
26 #include <palacios/vmm_lowlevel.h>
27 #include <palacios/vmm_debug.h>
33 static int inline check_vmcs_write(vmcs_field_t field, addr_t val) {
35 ret = vmcs_write(field, val);
37 if (ret != VMX_SUCCESS) {
38 PrintError(VM_NONE, VCORE_NONE, "VMWRITE error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
45 static int inline check_vmcs_read(vmcs_field_t field, void * val) {
47 ret = vmcs_read(field, val);
49 if (ret != VMX_SUCCESS) {
50 PrintError(VM_NONE, VCORE_NONE, "VMREAD error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
62 typedef enum { ES = 0,
71 IDTR = 18} vmcs_seg_offsets_t;
73 typedef enum {BASE = VMCS_GUEST_ES_BASE,
74 LIMIT = VMCS_GUEST_ES_LIMIT,
75 ACCESS = VMCS_GUEST_ES_ACCESS,
76 SELECTOR = VMCS_GUEST_ES_SELECTOR } vmcs_seg_bases_t;
80 static int v3_read_vmcs_segment(struct v3_segment * seg, vmcs_seg_offsets_t seg_type) {
81 vmcs_field_t selector = VMCS_GUEST_ES_SELECTOR + seg_type;
82 vmcs_field_t base = VMCS_GUEST_ES_BASE + seg_type;
83 vmcs_field_t limit = VMCS_GUEST_ES_LIMIT + seg_type;
84 vmcs_field_t access = VMCS_GUEST_ES_ACCESS + seg_type;
85 struct vmcs_segment vmcs_seg;
87 memset(&vmcs_seg, 0, sizeof(struct vmcs_segment));
89 check_vmcs_read(limit, &(vmcs_seg.limit));
90 check_vmcs_read(base, &(vmcs_seg.base));
92 if ((seg_type != GDTR) && (seg_type != IDTR)) {
93 check_vmcs_read(selector, &(vmcs_seg.selector));
94 check_vmcs_read(access, &(vmcs_seg.access.val));
97 v3_vmxseg_to_seg(&vmcs_seg, seg);
102 static int v3_write_vmcs_segment(struct v3_segment * seg, vmcs_seg_offsets_t seg_type) {
103 vmcs_field_t selector = VMCS_GUEST_ES_SELECTOR + seg_type;
104 vmcs_field_t base = VMCS_GUEST_ES_BASE + seg_type;
105 vmcs_field_t limit = VMCS_GUEST_ES_LIMIT + seg_type;
106 vmcs_field_t access = VMCS_GUEST_ES_ACCESS + seg_type;
107 struct vmcs_segment vmcs_seg;
109 v3_seg_to_vmxseg(seg, &vmcs_seg);
111 check_vmcs_write(limit, vmcs_seg.limit);
112 check_vmcs_write(base, vmcs_seg.base);
114 if ((seg_type != GDTR) && (seg_type != IDTR)) {
115 check_vmcs_write(access, vmcs_seg.access.val);
116 check_vmcs_write(selector, vmcs_seg.selector);
122 int v3_read_vmcs_segments(struct v3_segments * segs) {
123 v3_read_vmcs_segment(&(segs->cs), CS);
124 v3_read_vmcs_segment(&(segs->ds), DS);
125 v3_read_vmcs_segment(&(segs->es), ES);
126 v3_read_vmcs_segment(&(segs->fs), FS);
127 v3_read_vmcs_segment(&(segs->gs), GS);
128 v3_read_vmcs_segment(&(segs->ss), SS);
129 v3_read_vmcs_segment(&(segs->ldtr), LDTR);
130 v3_read_vmcs_segment(&(segs->gdtr), GDTR);
131 v3_read_vmcs_segment(&(segs->idtr), IDTR);
132 v3_read_vmcs_segment(&(segs->tr), TR);
137 int v3_write_vmcs_segments(struct v3_segments * segs) {
138 v3_write_vmcs_segment(&(segs->cs), CS);
139 v3_write_vmcs_segment(&(segs->ds), DS);
140 v3_write_vmcs_segment(&(segs->es), ES);
141 v3_write_vmcs_segment(&(segs->fs), FS);
142 v3_write_vmcs_segment(&(segs->gs), GS);
143 v3_write_vmcs_segment(&(segs->ss), SS);
144 v3_write_vmcs_segment(&(segs->ldtr), LDTR);
145 v3_write_vmcs_segment(&(segs->gdtr), GDTR);
146 v3_write_vmcs_segment(&(segs->idtr), IDTR);
147 v3_write_vmcs_segment(&(segs->tr), TR);
153 void v3_vmxseg_to_seg(struct vmcs_segment * vmcs_seg, struct v3_segment * seg) {
154 memset(seg, 0, sizeof(struct v3_segment));
156 seg->selector = vmcs_seg->selector;
157 seg->limit = vmcs_seg->limit;
158 seg->base = vmcs_seg->base;
160 seg->type = vmcs_seg->access.type;
161 seg->system = vmcs_seg->access.desc_type;
162 seg->dpl = vmcs_seg->access.dpl;
163 seg->present = vmcs_seg->access.present;
164 seg->avail = vmcs_seg->access.avail;
165 seg->long_mode = vmcs_seg->access.long_mode;
166 seg->db = vmcs_seg->access.db;
167 seg->granularity = vmcs_seg->access.granularity;
168 seg->unusable = vmcs_seg->access.unusable;
172 void v3_seg_to_vmxseg(struct v3_segment * seg, struct vmcs_segment * vmcs_seg) {
173 memset(vmcs_seg, 0, sizeof(struct vmcs_segment));
175 vmcs_seg->selector = seg->selector;
176 vmcs_seg->limit = seg->limit;
177 vmcs_seg->base = seg->base;
179 vmcs_seg->access.type = seg->type;
180 vmcs_seg->access.desc_type = seg->system;
181 vmcs_seg->access.dpl = seg->dpl;
182 vmcs_seg->access.present = seg->present;
183 vmcs_seg->access.avail = seg->avail;
184 vmcs_seg->access.long_mode = seg->long_mode;
185 vmcs_seg->access.db = seg->db;
186 vmcs_seg->access.granularity = seg->granularity;
187 vmcs_seg->access.unusable = seg->unusable;
193 int v3_update_vmcs_ctrl_fields(struct guest_info * info) {
195 struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
197 vmx_ret |= check_vmcs_write(VMCS_PIN_CTRLS, arch_data->pin_ctrls.value);
198 vmx_ret |= check_vmcs_write(VMCS_PROC_CTRLS, arch_data->pri_proc_ctrls.value);
200 if (arch_data->pri_proc_ctrls.sec_ctrls) {
201 vmx_ret |= check_vmcs_write(VMCS_SEC_PROC_CTRLS, arch_data->sec_proc_ctrls.value);
204 vmx_ret |= check_vmcs_write(VMCS_EXIT_CTRLS, arch_data->exit_ctrls.value);
205 vmx_ret |= check_vmcs_write(VMCS_ENTRY_CTRLS, arch_data->entry_ctrls.value);
206 vmx_ret |= check_vmcs_write(VMCS_EXCP_BITMAP, arch_data->excp_bmap.value);
208 if (info->shdw_pg_mode == NESTED_PAGING) {
209 vmx_ret |= check_vmcs_write(VMCS_EPT_PTR, info->direct_map_pt);
220 int v3_vmx_save_vmcs(struct guest_info * info) {
221 struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
224 check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
225 check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
227 check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
228 check_vmcs_read(VMCS_CR0_READ_SHDW, &(info->shdw_pg_state.guest_cr0));
229 check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
230 check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
231 check_vmcs_read(VMCS_CR4_READ_SHDW, &(info->shdw_pg_state.guest_cr4));
232 check_vmcs_read(VMCS_GUEST_DR7, &(info->dbg_regs.dr7));
234 check_vmcs_read(VMCS_GUEST_RFLAGS, &(info->ctrl_regs.rflags));
237 check_vmcs_read(VMCS_GUEST_EFER, &(info->ctrl_regs.efer));
238 check_vmcs_read(VMCS_ENTRY_CTRLS, &(vmx_info->entry_ctrls.value));
241 error = v3_read_vmcs_segments(&(info->segments));
243 /* Save MSRs from MSR SAVE Area (whereever that is...)*/
245 info->msrs.star = vmx_info->msr_area->guest_star.hi;
246 info->msrs.star <<= 32;
247 info->msrs.star |= vmx_info->msr_area->guest_star.lo;
249 info->msrs.lstar = vmx_info->msr_area->guest_lstar.hi;
250 info->msrs.lstar <<= 32;
251 info->msrs.lstar |= vmx_info->msr_area->guest_lstar.lo;
253 info->msrs.sfmask = vmx_info->msr_area->guest_fmask.hi;
254 info->msrs.sfmask <<= 32;
255 info->msrs.sfmask |= vmx_info->msr_area->guest_fmask.lo;
257 info->msrs.kern_gs_base = vmx_info->msr_area->guest_kern_gs.hi;
258 info->msrs.kern_gs_base <<= 32;
259 info->msrs.kern_gs_base |= vmx_info->msr_area->guest_kern_gs.lo;
266 int v3_vmx_restore_vmcs(struct guest_info * info) {
267 struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
270 check_vmcs_write(VMCS_GUEST_RIP, info->rip);
271 check_vmcs_write(VMCS_GUEST_RSP, info->vm_regs.rsp);
273 check_vmcs_write(VMCS_GUEST_CR0, info->ctrl_regs.cr0);
274 check_vmcs_write(VMCS_CR0_READ_SHDW, info->shdw_pg_state.guest_cr0);
275 check_vmcs_write(VMCS_GUEST_CR3, info->ctrl_regs.cr3);
276 check_vmcs_write(VMCS_GUEST_CR4, info->ctrl_regs.cr4);
277 check_vmcs_write(VMCS_CR4_READ_SHDW, vmx_info->guest_cr4);
278 check_vmcs_write(VMCS_GUEST_DR7, info->dbg_regs.dr7);
280 check_vmcs_write(VMCS_GUEST_RFLAGS, info->ctrl_regs.rflags);
283 check_vmcs_write(VMCS_GUEST_EFER, info->ctrl_regs.efer);
284 check_vmcs_write(VMCS_ENTRY_CTRLS, vmx_info->entry_ctrls.value);
287 error = v3_write_vmcs_segments(&(info->segments));
289 /* Restore MSRs from MSR SAVE Area (whereever that is...)*/
291 vmx_info->msr_area->guest_star.hi = (info->msrs.star >> 32);
292 vmx_info->msr_area->guest_star.lo = (info->msrs.star & 0xffffffff);
294 vmx_info->msr_area->guest_lstar.hi = (info->msrs.lstar >> 32);
295 vmx_info->msr_area->guest_lstar.lo = (info->msrs.lstar & 0xffffffff);
297 vmx_info->msr_area->guest_fmask.hi = (info->msrs.sfmask >> 32);
298 vmx_info->msr_area->guest_fmask.lo = (info->msrs.sfmask & 0xffffffff);
300 vmx_info->msr_area->guest_kern_gs.hi = (info->msrs.kern_gs_base >> 32);
301 vmx_info->msr_area->guest_kern_gs.lo = (info->msrs.kern_gs_base & 0xffffffff);
309 int v3_update_vmcs_host_state(struct guest_info * info) {
312 struct v3_msr tmp_msr;
317 } __attribute__((packed)) tmp_seg;
320 __asm__ __volatile__ ( "movq %%cr0, %0; "
325 __asm__ __volatile__ ( "movl %%cr0, %0; "
330 vmx_ret |= check_vmcs_write(VMCS_HOST_CR0, tmp);
334 __asm__ __volatile__ ( "movq %%cr3, %0; "
339 __asm__ __volatile__ ( "movl %%cr3, %0; "
344 vmx_ret |= check_vmcs_write(VMCS_HOST_CR3, tmp);
348 __asm__ __volatile__ ( "movq %%cr4, %0; "
353 __asm__ __volatile__ ( "movl %%cr4, %0; "
358 vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp);
361 __asm__ __volatile__(
367 gdtr_base = tmp_seg.base;
368 vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, tmp_seg.base);
370 __asm__ __volatile__(
376 vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, tmp_seg.base);
378 __asm__ __volatile__(
384 vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, tmp_seg.selector);
386 /* The GDTR *index* is bits 3-15 of the selector. */
388 struct tss_descriptor * desc = NULL;
389 desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3)));
391 tmp_seg.base = ((desc->base1) |
392 (desc->base2 << 16) |
393 (desc->base3 << 24) |
395 ((uint64_t)desc->base4 << 32)
401 vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, tmp_seg.base);
406 __asm__ __volatile__ ( "movq %%cs, %0; "
411 __asm__ __volatile__ ( "movl %%cs, %0; "
416 vmx_ret |= check_vmcs_write(VMCS_HOST_CS_SELECTOR, tmp);
419 __asm__ __volatile__ ( "movq %%ss, %0; "
424 __asm__ __volatile__ ( "movl %%ss, %0; "
429 vmx_ret |= check_vmcs_write(VMCS_HOST_SS_SELECTOR, tmp);
432 __asm__ __volatile__ ( "movq %%ds, %0; "
437 __asm__ __volatile__ ( "movl %%ds, %0; "
442 vmx_ret |= check_vmcs_write(VMCS_HOST_DS_SELECTOR, tmp);
445 __asm__ __volatile__ ( "movq %%es, %0; "
450 __asm__ __volatile__ ( "movl %%es, %0; "
455 vmx_ret |= check_vmcs_write(VMCS_HOST_ES_SELECTOR, tmp);
458 __asm__ __volatile__ ( "movq %%fs, %0; "
463 __asm__ __volatile__ ( "movl %%fs, %0; "
468 vmx_ret |= check_vmcs_write(VMCS_HOST_FS_SELECTOR, tmp);
471 __asm__ __volatile__ ( "movq %%gs, %0; "
476 __asm__ __volatile__ ( "movl %%gs, %0; "
481 vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp);
484 #define SYSENTER_CS_MSR 0x00000174
485 #define SYSENTER_ESP_MSR 0x00000175
486 #define SYSENTER_EIP_MSR 0x00000176
487 #define FS_BASE_MSR 0xc0000100
488 #define GS_BASE_MSR 0xc0000101
489 #define EFER_MSR 0xc0000080
493 v3_get_msr(SYSENTER_CS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
494 vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_CS, tmp_msr.lo);
497 v3_get_msr(SYSENTER_ESP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
498 vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_ESP, tmp_msr.value);
501 v3_get_msr(SYSENTER_EIP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
502 vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_EIP, tmp_msr.value);
506 v3_get_msr(FS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
507 vmx_ret |= check_vmcs_write(VMCS_HOST_FS_BASE, tmp_msr.value);
510 v3_get_msr(GS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
511 vmx_ret |= check_vmcs_write(VMCS_HOST_GS_BASE, tmp_msr.value);
515 v3_get_msr(EFER_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
516 vmx_ret |= check_vmcs_write(VMCS_HOST_EFER, tmp_msr.value);
518 // PERF GLOBAL CONTROL
522 v3_get_msr(IA32_PAT_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
523 vmx_ret |= check_vmcs_write(VMCS_HOST_PAT, tmp_msr.value);
526 // save STAR, LSTAR, FMASK, KERNEL_GS_BASE MSRs in MSR load/store area
528 struct vmx_data * vmx_state = (struct vmx_data *)info->vmm_data;
529 struct vmcs_msr_save_area * msr_entries = vmx_state->msr_area;
532 v3_get_msr(IA32_STAR_MSR, &(msr_entries->host_star.hi), &(msr_entries->host_star.lo));
533 v3_get_msr(IA32_LSTAR_MSR, &(msr_entries->host_lstar.hi), &(msr_entries->host_lstar.lo));
534 v3_get_msr(IA32_FMASK_MSR, &(msr_entries->host_fmask.hi), &(msr_entries->host_fmask.lo));
535 v3_get_msr(IA32_KERN_GS_BASE_MSR, &(msr_entries->host_kern_gs.hi), &(msr_entries->host_kern_gs.lo));
550 static inline void print_vmcs_field(vmcs_field_t vmcs_index) {
551 int len = v3_vmcs_get_field_len(vmcs_index);
554 if (vmcs_read(vmcs_index, &val) != VMX_SUCCESS) {
555 PrintError(VM_NONE, VCORE_NONE, "VMCS_READ error for %s\n", v3_vmcs_field_to_str(vmcs_index));
560 PrintDebug(VM_NONE, VCORE_NONE, "\t%s: 0x%.4x\n", v3_vmcs_field_to_str(vmcs_index), (uint16_t)val);
561 } else if (len == 4) {
562 PrintDebug(VM_NONE, VCORE_NONE, "\t%s: 0x%.8x\n", v3_vmcs_field_to_str(vmcs_index), (uint32_t)val);
563 } else if (len == 8) {
564 PrintDebug(VM_NONE, VCORE_NONE, "\t%s: 0x%p\n", v3_vmcs_field_to_str(vmcs_index), (void *)(addr_t)val);
569 static void print_vmcs_segments() {
570 struct v3_segments segs;
572 v3_read_vmcs_segments(&segs);
573 v3_print_segments(&segs);
576 PrintDebug(VM_NONE, VCORE_NONE, " ==> CS\n");
577 print_vmcs_field(VMCS_GUEST_CS_SELECTOR);
578 print_vmcs_field(VMCS_GUEST_CS_BASE);
579 print_vmcs_field(VMCS_GUEST_CS_LIMIT);
580 print_vmcs_field(VMCS_GUEST_CS_ACCESS);
582 PrintDebug(VM_NONE, VCORE_NONE, " ==> SS\n");
583 print_vmcs_field(VMCS_GUEST_SS_SELECTOR);
584 print_vmcs_field(VMCS_GUEST_SS_BASE);
585 print_vmcs_field(VMCS_GUEST_SS_LIMIT);
586 print_vmcs_field(VMCS_GUEST_SS_ACCESS);
588 PrintDebug(VM_NONE, VCORE_NONE, " ==> DS\n");
589 print_vmcs_field(VMCS_GUEST_DS_SELECTOR);
590 print_vmcs_field(VMCS_GUEST_DS_BASE);
591 print_vmcs_field(VMCS_GUEST_DS_LIMIT);
592 print_vmcs_field(VMCS_GUEST_DS_ACCESS);
594 PrintDebug(VM_NONE, VCORE_NONE, " ==> ES\n");
595 print_vmcs_field(VMCS_GUEST_ES_SELECTOR);
596 print_vmcs_field(VMCS_GUEST_ES_BASE);
597 print_vmcs_field(VMCS_GUEST_ES_LIMIT);
598 print_vmcs_field(VMCS_GUEST_ES_ACCESS);
600 PrintDebug(VM_NONE, VCORE_NONE, " ==> FS\n");
601 print_vmcs_field(VMCS_GUEST_FS_SELECTOR);
602 print_vmcs_field(VMCS_GUEST_FS_BASE);
603 print_vmcs_field(VMCS_GUEST_FS_LIMIT);
604 print_vmcs_field(VMCS_GUEST_FS_ACCESS);
606 PrintDebug(VM_NONE, VCORE_NONE, " ==> GS\n");
607 print_vmcs_field(VMCS_GUEST_GS_SELECTOR);
608 print_vmcs_field(VMCS_GUEST_GS_BASE);
609 print_vmcs_field(VMCS_GUEST_GS_LIMIT);
610 print_vmcs_field(VMCS_GUEST_GS_ACCESS);
612 PrintDebug(VM_NONE, VCORE_NONE, " ==> LDTR\n");
613 print_vmcs_field(VMCS_GUEST_LDTR_SELECTOR);
614 print_vmcs_field(VMCS_GUEST_LDTR_BASE);
615 print_vmcs_field(VMCS_GUEST_LDTR_LIMIT);
616 print_vmcs_field(VMCS_GUEST_LDTR_ACCESS);
618 PrintDebug(VM_NONE, VCORE_NONE, " ==> TR\n");
619 print_vmcs_field(VMCS_GUEST_TR_SELECTOR);
620 print_vmcs_field(VMCS_GUEST_TR_BASE);
621 print_vmcs_field(VMCS_GUEST_TR_LIMIT);
622 print_vmcs_field(VMCS_GUEST_TR_ACCESS);
624 PrintDebug(VM_NONE, VCORE_NONE, " ==> GDTR\n");
625 print_vmcs_field(VMCS_GUEST_GDTR_BASE);
626 print_vmcs_field(VMCS_GUEST_GDTR_LIMIT);
628 PrintDebug(VM_NONE, VCORE_NONE, " ==> IDTR\n");
629 print_vmcs_field(VMCS_GUEST_IDTR_BASE);
630 print_vmcs_field(VMCS_GUEST_IDTR_LIMIT);
638 static void print_guest_state()
640 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_GUEST_STATE\n");
641 print_vmcs_field(VMCS_GUEST_RIP);
642 print_vmcs_field(VMCS_GUEST_RSP);
643 print_vmcs_field(VMCS_GUEST_RFLAGS);
644 print_vmcs_field(VMCS_GUEST_CR0);
645 print_vmcs_field(VMCS_GUEST_CR3);
646 print_vmcs_field(VMCS_GUEST_CR4);
647 print_vmcs_field(VMCS_GUEST_DR7);
650 print_vmcs_field(VMCS_GUEST_EFER);
652 print_vmcs_field(VMCS_GUEST_EFER_HIGH);
656 PrintDebug(VM_NONE, VCORE_NONE, "\n");
658 print_vmcs_segments();
660 PrintDebug(VM_NONE, VCORE_NONE, "\n");
662 print_vmcs_field(VMCS_GUEST_DBG_CTL);
664 print_vmcs_field(VMCS_GUEST_DBG_CTL_HIGH);
666 print_vmcs_field(VMCS_GUEST_SYSENTER_CS);
667 print_vmcs_field(VMCS_GUEST_SYSENTER_ESP);
668 print_vmcs_field(VMCS_GUEST_SYSENTER_EIP);
672 print_vmcs_field(VMCS_GUEST_PAT);
674 print_vmcs_field(VMCS_GUEST_PAT_HIGH);
677 //if load IA32_PERF_GLOBAL_CTRL
678 print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL);
680 print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH);
683 print_vmcs_field(VMCS_GUEST_SMBASE);
688 PrintDebug(VM_NONE, VCORE_NONE, "GUEST_NON_REGISTER_STATE\n");
690 print_vmcs_field(VMCS_GUEST_ACTIVITY_STATE);
691 print_vmcs_field(VMCS_GUEST_INT_STATE);
692 print_vmcs_field(VMCS_GUEST_PENDING_DBG_EXCP);
694 // if VMX preempt timer
695 print_vmcs_field(VMCS_PREEMPT_TIMER);
699 static void print_host_state()
701 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_HOST_STATE\n");
703 print_vmcs_field(VMCS_HOST_RIP);
704 print_vmcs_field(VMCS_HOST_RSP);
705 print_vmcs_field(VMCS_HOST_CR0);
706 print_vmcs_field(VMCS_HOST_CR3);
707 print_vmcs_field(VMCS_HOST_CR4);
712 print_vmcs_field(VMCS_HOST_EFER);
714 print_vmcs_field(VMCS_HOST_EFER_HIGH);
718 PrintDebug(VM_NONE, VCORE_NONE, "\n");
719 print_vmcs_field(VMCS_HOST_CS_SELECTOR);
720 print_vmcs_field(VMCS_HOST_SS_SELECTOR);
721 print_vmcs_field(VMCS_HOST_DS_SELECTOR);
722 print_vmcs_field(VMCS_HOST_ES_SELECTOR);
723 print_vmcs_field(VMCS_HOST_FS_SELECTOR);
724 print_vmcs_field(VMCS_HOST_GS_SELECTOR);
725 print_vmcs_field(VMCS_HOST_TR_SELECTOR);
727 PrintDebug(VM_NONE, VCORE_NONE, "\n");
728 print_vmcs_field(VMCS_HOST_FS_BASE);
729 print_vmcs_field(VMCS_HOST_GS_BASE);
730 print_vmcs_field(VMCS_HOST_TR_BASE);
731 print_vmcs_field(VMCS_HOST_GDTR_BASE);
732 print_vmcs_field(VMCS_HOST_IDTR_BASE);
734 PrintDebug(VM_NONE, VCORE_NONE, "\n");
735 print_vmcs_field(VMCS_HOST_SYSENTER_CS);
736 print_vmcs_field(VMCS_HOST_SYSENTER_ESP);
737 print_vmcs_field(VMCS_HOST_SYSENTER_EIP);
741 print_vmcs_field(VMCS_HOST_PAT);
743 print_vmcs_field(VMCS_HOST_PAT_HIGH);
746 // if load IA32_PERF_GLOBAL_CTRL
747 print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL);
749 print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL_HIGH);
754 static void print_exec_ctrls() {
755 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_EXEC_CTRL_FIELDS\n");
756 print_vmcs_field(VMCS_PIN_CTRLS);
757 print_vmcs_field(VMCS_PROC_CTRLS);
759 // if activate secondary controls
760 print_vmcs_field(VMCS_SEC_PROC_CTRLS);
762 print_vmcs_field(VMCS_EXCP_BITMAP);
763 print_vmcs_field(VMCS_PG_FAULT_ERR_MASK);
764 print_vmcs_field(VMCS_PG_FAULT_ERR_MATCH);
766 print_vmcs_field(VMCS_IO_BITMAP_A_ADDR);
768 print_vmcs_field(VMCS_IO_BITMAP_A_ADDR_HIGH);
771 print_vmcs_field(VMCS_IO_BITMAP_B_ADDR);
773 print_vmcs_field(VMCS_IO_BITMAP_B_ADDR_HIGH);
776 print_vmcs_field(VMCS_TSC_OFFSET);
778 print_vmcs_field(VMCS_TSC_OFFSET_HIGH);
781 PrintDebug(VM_NONE, VCORE_NONE, "\n");
783 print_vmcs_field(VMCS_CR0_MASK);
784 print_vmcs_field(VMCS_CR0_READ_SHDW);
785 print_vmcs_field(VMCS_CR4_MASK);
786 print_vmcs_field(VMCS_CR4_READ_SHDW);
788 print_vmcs_field(VMCS_CR3_TGT_CNT);
789 print_vmcs_field(VMCS_CR3_TGT_VAL_0);
790 print_vmcs_field(VMCS_CR3_TGT_VAL_1);
791 print_vmcs_field(VMCS_CR3_TGT_VAL_2);
792 print_vmcs_field(VMCS_CR3_TGT_VAL_3);
794 // Check max number of CR3 targets... may continue...
797 PrintDebug(VM_NONE, VCORE_NONE, "\n");
799 // if virtualize apic accesses
800 print_vmcs_field(VMCS_APIC_ACCESS_ADDR);
802 print_vmcs_field(VMCS_APIC_ACCESS_ADDR_HIGH);
806 print_vmcs_field(VMCS_VAPIC_ADDR);
808 print_vmcs_field(VMCS_VAPIC_ADDR_HIGH);
812 print_vmcs_field(VMCS_TPR_THRESHOLD);
815 // if use MSR bitmaps
816 print_vmcs_field(VMCS_MSR_BITMAP);
818 print_vmcs_field(VMCS_MSR_BITMAP_HIGH);
821 print_vmcs_field(VMCS_EXEC_PTR);
823 print_vmcs_field(VMCS_EXEC_PTR_HIGH);
829 static void print_ept_state() {
830 V3_Print(VM_NONE, VCORE_NONE, "VMCS EPT INFO\n");
833 print_vmcs_field(VMCS_VPID);
835 print_vmcs_field(VMCS_EPT_PTR);
837 print_vmcs_field(VMCS_EPT_PTR_HIGH);
840 print_vmcs_field(VMCS_GUEST_PHYS_ADDR);
842 print_vmcs_field(VMCS_GUEST_PHYS_ADDR_HIGH);
847 print_vmcs_field(VMCS_GUEST_PDPTE0);
849 print_vmcs_field(VMCS_GUEST_PDPTE0_HIGH);
852 print_vmcs_field(VMCS_GUEST_PDPTE1);
854 print_vmcs_field(VMCS_GUEST_PDPTE1_HIGH);
857 print_vmcs_field(VMCS_GUEST_PDPTE2);
859 print_vmcs_field(VMCS_GUEST_PDPTE2_HIGH);
862 print_vmcs_field(VMCS_GUEST_PDPTE3);
864 print_vmcs_field(VMCS_GUEST_PDPTE3_HIGH);
872 static void print_exit_ctrls() {
873 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_EXIT_CTRLS\n");
875 print_vmcs_field(VMCS_EXIT_CTRLS);
878 print_vmcs_field(VMCS_EXIT_MSR_STORE_CNT);
879 print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR);
881 print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR_HIGH);
884 print_vmcs_field(VMCS_EXIT_MSR_LOAD_CNT);
885 print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR);
887 print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR_HIGH);
891 // if pause loop exiting
892 print_vmcs_field(VMCS_PLE_GAP);
893 print_vmcs_field(VMCS_PLE_WINDOW);
898 static void print_entry_ctrls() {
899 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_ENTRY_CTRLS\n");
901 print_vmcs_field(VMCS_ENTRY_CTRLS);
903 print_vmcs_field(VMCS_ENTRY_MSR_LOAD_CNT);
904 print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR);
906 print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR_HIGH);
909 print_vmcs_field(VMCS_ENTRY_INT_INFO);
910 print_vmcs_field(VMCS_ENTRY_EXCP_ERR);
911 print_vmcs_field(VMCS_ENTRY_INSTR_LEN);
917 static void print_exit_info() {
918 PrintDebug(VM_NONE, VCORE_NONE, "VMCS_EXIT_INFO\n");
920 print_vmcs_field(VMCS_EXIT_REASON);
921 print_vmcs_field(VMCS_EXIT_QUAL);
923 print_vmcs_field(VMCS_EXIT_INT_INFO);
924 print_vmcs_field(VMCS_EXIT_INT_ERR);
926 print_vmcs_field(VMCS_IDT_VECTOR_INFO);
927 print_vmcs_field(VMCS_IDT_VECTOR_ERR);
929 print_vmcs_field(VMCS_EXIT_INSTR_LEN);
931 print_vmcs_field(VMCS_GUEST_LINEAR_ADDR);
932 print_vmcs_field(VMCS_EXIT_INSTR_INFO);
934 print_vmcs_field(VMCS_IO_RCX);
935 print_vmcs_field(VMCS_IO_RSI);
936 print_vmcs_field(VMCS_IO_RDI);
937 print_vmcs_field(VMCS_IO_RIP);
940 print_vmcs_field(VMCS_INSTR_ERR);
943 void v3_print_vmcs() {
945 print_vmcs_field(VMCS_LINK_PTR);
947 print_vmcs_field(VMCS_LINK_PTR_HIGH);
964 * Returns the field length in bytes
965 * It doesn't get much uglier than this... Thanks Intel
967 int v3_vmcs_get_field_len(vmcs_field_t field) {
968 struct vmcs_field_encoding * enc = (struct vmcs_field_encoding *)&field;
970 switch (enc->width) {
974 if (enc->access_type == 1) {
977 return sizeof(addr_t);
983 return sizeof(addr_t);
985 PrintError(VM_NONE, VCORE_NONE, "Invalid VMCS field: 0x%x\n", field);
1000 static const char VMCS_VPID_STR[] = "VPID";
1001 static const char VMCS_GUEST_ES_SELECTOR_STR[] = "GUEST_ES_SELECTOR";
1002 static const char VMCS_GUEST_CS_SELECTOR_STR[] = "GUEST_CS_SELECTOR";
1003 static const char VMCS_GUEST_SS_SELECTOR_STR[] = "GUEST_SS_SELECTOR";
1004 static const char VMCS_GUEST_DS_SELECTOR_STR[] = "GUEST_DS_SELECTOR";
1005 static const char VMCS_GUEST_FS_SELECTOR_STR[] = "GUEST_FS_SELECTOR";
1006 static const char VMCS_GUEST_GS_SELECTOR_STR[] = "GUEST_GS_SELECTOR";
1007 static const char VMCS_GUEST_LDTR_SELECTOR_STR[] = "GUEST_LDTR_SELECTOR";
1008 static const char VMCS_GUEST_TR_SELECTOR_STR[] = "GUEST_TR_SELECTOR";
1009 static const char VMCS_HOST_ES_SELECTOR_STR[] = "HOST_ES_SELECTOR";
1010 static const char VMCS_HOST_CS_SELECTOR_STR[] = "HOST_CS_SELECTOR";
1011 static const char VMCS_HOST_SS_SELECTOR_STR[] = "HOST_SS_SELECTOR";
1012 static const char VMCS_HOST_DS_SELECTOR_STR[] = "HOST_DS_SELECTOR";
1013 static const char VMCS_HOST_FS_SELECTOR_STR[] = "HOST_FS_SELECTOR";
1014 static const char VMCS_HOST_GS_SELECTOR_STR[] = "HOST_GS_SELECTOR";
1015 static const char VMCS_HOST_TR_SELECTOR_STR[] = "HOST_TR_SELECTOR";
1016 static const char VMCS_IO_BITMAP_A_ADDR_STR[] = "IO_BITMAP_A_ADDR";
1017 static const char VMCS_IO_BITMAP_A_ADDR_HIGH_STR[] = "IO_BITMAP_A_ADDR_HIGH";
1018 static const char VMCS_IO_BITMAP_B_ADDR_STR[] = "IO_BITMAP_B_ADDR";
1019 static const char VMCS_IO_BITMAP_B_ADDR_HIGH_STR[] = "IO_BITMAP_B_ADDR_HIGH";
1020 static const char VMCS_MSR_BITMAP_STR[] = "MSR_BITMAPS";
1021 static const char VMCS_MSR_BITMAP_HIGH_STR[] = "MSR_BITMAPS_HIGH";
1022 static const char VMCS_EXIT_MSR_STORE_ADDR_STR[] = "EXIT_MSR_STORE_ADDR";
1023 static const char VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR[] = "EXIT_MSR_STORE_ADDR_HIGH";
1024 static const char VMCS_EXIT_MSR_LOAD_ADDR_STR[] = "EXIT_MSR_LOAD_ADDR";
1025 static const char VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR[] = "EXIT_MSR_LOAD_ADDR_HIGH";
1026 static const char VMCS_ENTRY_MSR_LOAD_ADDR_STR[] = "ENTRY_MSR_LOAD_ADDR";
1027 static const char VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR[] = "ENTRY_MSR_LOAD_ADDR_HIGH";
1028 static const char VMCS_EXEC_PTR_STR[] = "VMCS_EXEC_PTR";
1029 static const char VMCS_EXEC_PTR_HIGH_STR[] = "VMCS_EXEC_PTR_HIGH";
1030 static const char VMCS_TSC_OFFSET_STR[] = "TSC_OFFSET";
1031 static const char VMCS_TSC_OFFSET_HIGH_STR[] = "TSC_OFFSET_HIGH";
1032 static const char VMCS_VAPIC_ADDR_STR[] = "VAPIC_PAGE_ADDR";
1033 static const char VMCS_VAPIC_ADDR_HIGH_STR[] = "VAPIC_PAGE_ADDR_HIGH";
1034 static const char VMCS_APIC_ACCESS_ADDR_STR[] = "APIC_ACCESS_ADDR";
1035 static const char VMCS_APIC_ACCESS_ADDR_HIGH_STR[] = "APIC_ACCESS_ADDR_HIGH";
1036 static const char VMCS_EPT_PTR_STR[] = "VMCS_EPT_PTR";
1037 static const char VMCS_EPT_PTR_HIGH_STR[] = "VMCS_EPT_PTR_HIGH";
1038 static const char VMCS_GUEST_PHYS_ADDR_STR[] = "VMCS_GUEST_PHYS_ADDR";
1039 static const char VMCS_GUEST_PHYS_ADDR_HIGH_STR[] = "VMCS_GUEST_PHYS_ADDR_HIGH";
1040 static const char VMCS_LINK_PTR_STR[] = "VMCS_LINK_PTR";
1041 static const char VMCS_LINK_PTR_HIGH_STR[] = "VMCS_LINK_PTR_HIGH";
1042 static const char VMCS_GUEST_DBG_CTL_STR[] = "GUEST_DEBUG_CTL";
1043 static const char VMCS_GUEST_DBG_CTL_HIGH_STR[] = "GUEST_DEBUG_CTL_HIGH";
1044 static const char VMCS_GUEST_PAT_STR[] = "GUEST_PAT";
1045 static const char VMCS_GUEST_PAT_HIGH_STR[] = "GUEST_PAT_HIGH";
1046 static const char VMCS_GUEST_EFER_STR[] = "GUEST_EFER";
1047 static const char VMCS_GUEST_EFER_HIGH_STR[] = "GUEST_EFER_HIGH";
1048 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_STR[] = "GUEST_PERF_GLOBAL_CTRL";
1049 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR[] = "GUEST_PERF_GLOBAL_CTRL_HIGH";
1050 static const char VMCS_GUEST_PDPTE0_STR[] = "GUEST_PDPTE0";
1051 static const char VMCS_GUEST_PDPTE0_HIGH_STR[] = "GUEST_PDPTE0_HIGH";
1052 static const char VMCS_GUEST_PDPTE1_STR[] = "GUEST_PDPTE1";
1053 static const char VMCS_GUEST_PDPTE1_HIGH_STR[] = "GUEST_PDPTE1_HIGH";
1054 static const char VMCS_GUEST_PDPTE2_STR[] = "GUEST_PDPTE2";
1055 static const char VMCS_GUEST_PDPTE2_HIGH_STR[] = "GUEST_PDPTE2_HIGH";
1056 static const char VMCS_GUEST_PDPTE3_STR[] = "GUEST_PDPTE3";
1057 static const char VMCS_GUEST_PDPTE3_HIGH_STR[] = "GUEST_PDPTE3_HIGH";
1058 static const char VMCS_HOST_PAT_STR[] = "HOST_PAT";
1059 static const char VMCS_HOST_PAT_HIGH_STR[] = "HOST_PAT_HIGH";
1060 static const char VMCS_HOST_EFER_STR[] = "VMCS_HOST_EFER";
1061 static const char VMCS_HOST_EFER_HIGH_STR[] = "VMCS_HOST_EFER_HIGH";
1062 static const char VMCS_HOST_PERF_GLOBAL_CTRL_STR[] = "HOST_PERF_GLOBAL_CTRL";
1063 static const char VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR[] = "HOST_PERF_GLOBAL_CTRL_HIGH";
1064 static const char VMCS_PIN_CTRLS_STR[] = "PIN_VM_EXEC_CTRLS";
1065 static const char VMCS_PROC_CTRLS_STR[] = "PROC_VM_EXEC_CTRLS";
1066 static const char VMCS_EXCP_BITMAP_STR[] = "EXCEPTION_BITMAP";
1067 static const char VMCS_PG_FAULT_ERR_MASK_STR[] = "PAGE_FAULT_ERROR_MASK";
1068 static const char VMCS_PG_FAULT_ERR_MATCH_STR[] = "PAGE_FAULT_ERROR_MATCH";
1069 static const char VMCS_CR3_TGT_CNT_STR[] = "CR3_TARGET_COUNT";
1070 static const char VMCS_EXIT_CTRLS_STR[] = "VM_EXIT_CTRLS";
1071 static const char VMCS_EXIT_MSR_STORE_CNT_STR[] = "VM_EXIT_MSR_STORE_COUNT";
1072 static const char VMCS_EXIT_MSR_LOAD_CNT_STR[] = "VM_EXIT_MSR_LOAD_COUNT";
1073 static const char VMCS_ENTRY_CTRLS_STR[] = "VM_ENTRY_CTRLS";
1074 static const char VMCS_ENTRY_MSR_LOAD_CNT_STR[] = "VM_ENTRY_MSR_LOAD_COUNT";
1075 static const char VMCS_ENTRY_INT_INFO_STR[] = "VM_ENTRY_INT_INFO_FIELD";
1076 static const char VMCS_ENTRY_EXCP_ERR_STR[] = "VM_ENTRY_EXCEPTION_ERROR";
1077 static const char VMCS_ENTRY_INSTR_LEN_STR[] = "VM_ENTRY_INSTR_LENGTH";
1078 static const char VMCS_TPR_THRESHOLD_STR[] = "TPR_THRESHOLD";
1079 static const char VMCS_SEC_PROC_CTRLS_STR[] = "VMCS_SEC_PROC_CTRLS";
1080 static const char VMCS_PLE_GAP_STR[] = "PLE_GAP";
1081 static const char VMCS_PLE_WINDOW_STR[] = "PLE_WINDOW";
1082 static const char VMCS_INSTR_ERR_STR[] = "VM_INSTR_ERROR";
1083 static const char VMCS_EXIT_REASON_STR[] = "EXIT_REASON";
1084 static const char VMCS_EXIT_INT_INFO_STR[] = "VM_EXIT_INT_INFO";
1085 static const char VMCS_EXIT_INT_ERR_STR[] = "VM_EXIT_INT_ERROR";
1086 static const char VMCS_IDT_VECTOR_INFO_STR[] = "IDT_VECTOR_INFO";
1087 static const char VMCS_IDT_VECTOR_ERR_STR[] = "IDT_VECTOR_ERROR";
1088 static const char VMCS_EXIT_INSTR_LEN_STR[] = "VM_EXIT_INSTR_LENGTH";
1089 static const char VMCS_EXIT_INSTR_INFO_STR[] = "VMX_INSTR_INFO";
1090 static const char VMCS_GUEST_ES_LIMIT_STR[] = "GUEST_ES_LIMIT";
1091 static const char VMCS_GUEST_CS_LIMIT_STR[] = "GUEST_CS_LIMIT";
1092 static const char VMCS_GUEST_SS_LIMIT_STR[] = "GUEST_SS_LIMIT";
1093 static const char VMCS_GUEST_DS_LIMIT_STR[] = "GUEST_DS_LIMIT";
1094 static const char VMCS_GUEST_FS_LIMIT_STR[] = "GUEST_FS_LIMIT";
1095 static const char VMCS_GUEST_GS_LIMIT_STR[] = "GUEST_GS_LIMIT";
1096 static const char VMCS_GUEST_LDTR_LIMIT_STR[] = "GUEST_LDTR_LIMIT";
1097 static const char VMCS_GUEST_TR_LIMIT_STR[] = "GUEST_TR_LIMIT";
1098 static const char VMCS_GUEST_GDTR_LIMIT_STR[] = "GUEST_GDTR_LIMIT";
1099 static const char VMCS_GUEST_IDTR_LIMIT_STR[] = "GUEST_IDTR_LIMIT";
1100 static const char VMCS_GUEST_ES_ACCESS_STR[] = "GUEST_ES_ACCESS";
1101 static const char VMCS_GUEST_CS_ACCESS_STR[] = "GUEST_CS_ACCESS";
1102 static const char VMCS_GUEST_SS_ACCESS_STR[] = "GUEST_SS_ACCESS";
1103 static const char VMCS_GUEST_DS_ACCESS_STR[] = "GUEST_DS_ACCESS";
1104 static const char VMCS_GUEST_FS_ACCESS_STR[] = "GUEST_FS_ACCESS";
1105 static const char VMCS_GUEST_GS_ACCESS_STR[] = "GUEST_GS_ACCESS";
1106 static const char VMCS_GUEST_LDTR_ACCESS_STR[] = "GUEST_LDTR_ACCESS";
1107 static const char VMCS_GUEST_TR_ACCESS_STR[] = "GUEST_TR_ACCESS";
1108 static const char VMCS_GUEST_INT_STATE_STR[] = "GUEST_INT_STATE";
1109 static const char VMCS_GUEST_ACTIVITY_STATE_STR[] = "GUEST_ACTIVITY_STATE";
1110 static const char VMCS_GUEST_SMBASE_STR[] = "GUEST_SMBASE";
1111 static const char VMCS_GUEST_SYSENTER_CS_STR[] = "GUEST_SYSENTER_CS";
1112 static const char VMCS_PREEMPT_TIMER_STR[] = "PREEMPT_TIMER";
1113 static const char VMCS_HOST_SYSENTER_CS_STR[] = "HOST_SYSENTER_CS";
1114 static const char VMCS_CR0_MASK_STR[] = "CR0_GUEST_HOST_MASK";
1115 static const char VMCS_CR4_MASK_STR[] = "CR4_GUEST_HOST_MASK";
1116 static const char VMCS_CR0_READ_SHDW_STR[] = "CR0_READ_SHADOW";
1117 static const char VMCS_CR4_READ_SHDW_STR[] = "CR4_READ_SHADOW";
1118 static const char VMCS_CR3_TGT_VAL_0_STR[] = "CR3_TARGET_VALUE_0";
1119 static const char VMCS_CR3_TGT_VAL_1_STR[] = "CR3_TARGET_VALUE_1";
1120 static const char VMCS_CR3_TGT_VAL_2_STR[] = "CR3_TARGET_VALUE_2";
1121 static const char VMCS_CR3_TGT_VAL_3_STR[] = "CR3_TARGET_VALUE_3";
1122 static const char VMCS_EXIT_QUAL_STR[] = "EXIT_QUALIFICATION";
1123 static const char VMCS_IO_RCX_STR[] = "IO_RCX";
1124 static const char VMCS_IO_RSI_STR[] = "IO_RSI";
1125 static const char VMCS_IO_RDI_STR[] = "IO_RDI";
1126 static const char VMCS_IO_RIP_STR[] = "IO_RIP";
1127 static const char VMCS_GUEST_LINEAR_ADDR_STR[] = "GUEST_LINEAR_ADDR";
1128 static const char VMCS_GUEST_CR0_STR[] = "GUEST_CR0";
1129 static const char VMCS_GUEST_CR3_STR[] = "GUEST_CR3";
1130 static const char VMCS_GUEST_CR4_STR[] = "GUEST_CR4";
1131 static const char VMCS_GUEST_ES_BASE_STR[] = "GUEST_ES_BASE";
1132 static const char VMCS_GUEST_CS_BASE_STR[] = "GUEST_CS_BASE";
1133 static const char VMCS_GUEST_SS_BASE_STR[] = "GUEST_SS_BASE";
1134 static const char VMCS_GUEST_DS_BASE_STR[] = "GUEST_DS_BASE";
1135 static const char VMCS_GUEST_FS_BASE_STR[] = "GUEST_FS_BASE";
1136 static const char VMCS_GUEST_GS_BASE_STR[] = "GUEST_GS_BASE";
1137 static const char VMCS_GUEST_LDTR_BASE_STR[] = "GUEST_LDTR_BASE";
1138 static const char VMCS_GUEST_TR_BASE_STR[] = "GUEST_TR_BASE";
1139 static const char VMCS_GUEST_GDTR_BASE_STR[] = "GUEST_GDTR_BASE";
1140 static const char VMCS_GUEST_IDTR_BASE_STR[] = "GUEST_IDTR_BASE";
1141 static const char VMCS_GUEST_DR7_STR[] = "GUEST_DR7";
1142 static const char VMCS_GUEST_RSP_STR[] = "GUEST_RSP";
1143 static const char VMCS_GUEST_RIP_STR[] = "GUEST_RIP";
1144 static const char VMCS_GUEST_RFLAGS_STR[] = "GUEST_RFLAGS";
1145 static const char VMCS_GUEST_PENDING_DBG_EXCP_STR[] = "GUEST_PENDING_DEBUG_EXCS";
1146 static const char VMCS_GUEST_SYSENTER_ESP_STR[] = "GUEST_SYSENTER_ESP";
1147 static const char VMCS_GUEST_SYSENTER_EIP_STR[] = "GUEST_SYSENTER_EIP";
1148 static const char VMCS_HOST_CR0_STR[] = "HOST_CR0";
1149 static const char VMCS_HOST_CR3_STR[] = "HOST_CR3";
1150 static const char VMCS_HOST_CR4_STR[] = "HOST_CR4";
1151 static const char VMCS_HOST_FS_BASE_STR[] = "HOST_FS_BASE";
1152 static const char VMCS_HOST_GS_BASE_STR[] = "HOST_GS_BASE";
1153 static const char VMCS_HOST_TR_BASE_STR[] = "HOST_TR_BASE";
1154 static const char VMCS_HOST_GDTR_BASE_STR[] = "HOST_GDTR_BASE";
1155 static const char VMCS_HOST_IDTR_BASE_STR[] = "HOST_IDTR_BASE";
1156 static const char VMCS_HOST_SYSENTER_ESP_STR[] = "HOST_SYSENTER_ESP";
1157 static const char VMCS_HOST_SYSENTER_EIP_STR[] = "HOST_SYSENTER_EIP";
1158 static const char VMCS_HOST_RSP_STR[] = "HOST_RSP";
1159 static const char VMCS_HOST_RIP_STR[] = "HOST_RIP";
1163 const char * v3_vmcs_field_to_str(vmcs_field_t field) {
1166 return VMCS_VPID_STR;
1167 case VMCS_GUEST_ES_SELECTOR:
1168 return VMCS_GUEST_ES_SELECTOR_STR;
1169 case VMCS_GUEST_CS_SELECTOR:
1170 return VMCS_GUEST_CS_SELECTOR_STR;
1171 case VMCS_GUEST_SS_SELECTOR:
1172 return VMCS_GUEST_SS_SELECTOR_STR;
1173 case VMCS_GUEST_DS_SELECTOR:
1174 return VMCS_GUEST_DS_SELECTOR_STR;
1175 case VMCS_GUEST_FS_SELECTOR:
1176 return VMCS_GUEST_FS_SELECTOR_STR;
1177 case VMCS_GUEST_GS_SELECTOR:
1178 return VMCS_GUEST_GS_SELECTOR_STR;
1179 case VMCS_GUEST_LDTR_SELECTOR:
1180 return VMCS_GUEST_LDTR_SELECTOR_STR;
1181 case VMCS_GUEST_TR_SELECTOR:
1182 return VMCS_GUEST_TR_SELECTOR_STR;
1183 case VMCS_HOST_ES_SELECTOR:
1184 return VMCS_HOST_ES_SELECTOR_STR;
1185 case VMCS_HOST_CS_SELECTOR:
1186 return VMCS_HOST_CS_SELECTOR_STR;
1187 case VMCS_HOST_SS_SELECTOR:
1188 return VMCS_HOST_SS_SELECTOR_STR;
1189 case VMCS_HOST_DS_SELECTOR:
1190 return VMCS_HOST_DS_SELECTOR_STR;
1191 case VMCS_HOST_FS_SELECTOR:
1192 return VMCS_HOST_FS_SELECTOR_STR;
1193 case VMCS_HOST_GS_SELECTOR:
1194 return VMCS_HOST_GS_SELECTOR_STR;
1195 case VMCS_HOST_TR_SELECTOR:
1196 return VMCS_HOST_TR_SELECTOR_STR;
1197 case VMCS_IO_BITMAP_A_ADDR:
1198 return VMCS_IO_BITMAP_A_ADDR_STR;
1199 case VMCS_IO_BITMAP_A_ADDR_HIGH:
1200 return VMCS_IO_BITMAP_A_ADDR_HIGH_STR;
1201 case VMCS_IO_BITMAP_B_ADDR:
1202 return VMCS_IO_BITMAP_B_ADDR_STR;
1203 case VMCS_IO_BITMAP_B_ADDR_HIGH:
1204 return VMCS_IO_BITMAP_B_ADDR_HIGH_STR;
1205 case VMCS_MSR_BITMAP:
1206 return VMCS_MSR_BITMAP_STR;
1207 case VMCS_MSR_BITMAP_HIGH:
1208 return VMCS_MSR_BITMAP_HIGH_STR;
1209 case VMCS_EXIT_MSR_STORE_ADDR:
1210 return VMCS_EXIT_MSR_STORE_ADDR_STR;
1211 case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
1212 return VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR;
1213 case VMCS_EXIT_MSR_LOAD_ADDR:
1214 return VMCS_EXIT_MSR_LOAD_ADDR_STR;
1215 case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
1216 return VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR;
1217 case VMCS_ENTRY_MSR_LOAD_ADDR:
1218 return VMCS_ENTRY_MSR_LOAD_ADDR_STR;
1219 case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
1220 return VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR;
1222 return VMCS_EXEC_PTR_STR;
1223 case VMCS_EXEC_PTR_HIGH:
1224 return VMCS_EXEC_PTR_HIGH_STR;
1225 case VMCS_TSC_OFFSET:
1226 return VMCS_TSC_OFFSET_STR;
1227 case VMCS_TSC_OFFSET_HIGH:
1228 return VMCS_TSC_OFFSET_HIGH_STR;
1229 case VMCS_VAPIC_ADDR:
1230 return VMCS_VAPIC_ADDR_STR;
1231 case VMCS_VAPIC_ADDR_HIGH:
1232 return VMCS_VAPIC_ADDR_HIGH_STR;
1233 case VMCS_APIC_ACCESS_ADDR:
1234 return VMCS_APIC_ACCESS_ADDR_STR;
1235 case VMCS_APIC_ACCESS_ADDR_HIGH:
1236 return VMCS_APIC_ACCESS_ADDR_HIGH_STR;
1238 return VMCS_EPT_PTR_STR;
1239 case VMCS_EPT_PTR_HIGH:
1240 return VMCS_EPT_PTR_HIGH_STR;
1241 case VMCS_GUEST_PHYS_ADDR:
1242 return VMCS_GUEST_PHYS_ADDR_STR;
1243 case VMCS_GUEST_PHYS_ADDR_HIGH:
1244 return VMCS_GUEST_PHYS_ADDR_HIGH_STR;
1246 return VMCS_LINK_PTR_STR;
1247 case VMCS_LINK_PTR_HIGH:
1248 return VMCS_LINK_PTR_HIGH_STR;
1249 case VMCS_GUEST_DBG_CTL:
1250 return VMCS_GUEST_DBG_CTL_STR;
1251 case VMCS_GUEST_DBG_CTL_HIGH:
1252 return VMCS_GUEST_DBG_CTL_HIGH_STR;
1253 case VMCS_GUEST_PAT:
1254 return VMCS_GUEST_PAT_STR;
1255 case VMCS_GUEST_PAT_HIGH:
1256 return VMCS_GUEST_PAT_HIGH_STR;
1257 case VMCS_GUEST_EFER:
1258 return VMCS_GUEST_EFER_STR;
1259 case VMCS_GUEST_EFER_HIGH:
1260 return VMCS_GUEST_EFER_HIGH_STR;
1261 case VMCS_GUEST_PERF_GLOBAL_CTRL:
1262 return VMCS_GUEST_PERF_GLOBAL_CTRL_STR;
1263 case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
1264 return VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR;
1265 case VMCS_GUEST_PDPTE0:
1266 return VMCS_GUEST_PDPTE0_STR;
1267 case VMCS_GUEST_PDPTE0_HIGH:
1268 return VMCS_GUEST_PDPTE0_HIGH_STR;
1269 case VMCS_GUEST_PDPTE1:
1270 return VMCS_GUEST_PDPTE1_STR;
1271 case VMCS_GUEST_PDPTE1_HIGH:
1272 return VMCS_GUEST_PDPTE1_HIGH_STR;
1273 case VMCS_GUEST_PDPTE2:
1274 return VMCS_GUEST_PDPTE2_STR;
1275 case VMCS_GUEST_PDPTE2_HIGH:
1276 return VMCS_GUEST_PDPTE2_HIGH_STR;
1277 case VMCS_GUEST_PDPTE3:
1278 return VMCS_GUEST_PDPTE3_STR;
1279 case VMCS_GUEST_PDPTE3_HIGH:
1280 return VMCS_GUEST_PDPTE3_HIGH_STR;
1282 return VMCS_HOST_PAT_STR;
1283 case VMCS_HOST_PAT_HIGH:
1284 return VMCS_HOST_PAT_HIGH_STR;
1285 case VMCS_HOST_EFER:
1286 return VMCS_HOST_EFER_STR;
1287 case VMCS_HOST_EFER_HIGH:
1288 return VMCS_HOST_EFER_HIGH_STR;
1289 case VMCS_HOST_PERF_GLOBAL_CTRL:
1290 return VMCS_HOST_PERF_GLOBAL_CTRL_STR;
1291 case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
1292 return VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR;
1293 case VMCS_PIN_CTRLS:
1294 return VMCS_PIN_CTRLS_STR;
1295 case VMCS_PROC_CTRLS:
1296 return VMCS_PROC_CTRLS_STR;
1297 case VMCS_EXCP_BITMAP:
1298 return VMCS_EXCP_BITMAP_STR;
1299 case VMCS_PG_FAULT_ERR_MASK:
1300 return VMCS_PG_FAULT_ERR_MASK_STR;
1301 case VMCS_PG_FAULT_ERR_MATCH:
1302 return VMCS_PG_FAULT_ERR_MATCH_STR;
1303 case VMCS_CR3_TGT_CNT:
1304 return VMCS_CR3_TGT_CNT_STR;
1305 case VMCS_EXIT_CTRLS:
1306 return VMCS_EXIT_CTRLS_STR;
1307 case VMCS_EXIT_MSR_STORE_CNT:
1308 return VMCS_EXIT_MSR_STORE_CNT_STR;
1309 case VMCS_EXIT_MSR_LOAD_CNT:
1310 return VMCS_EXIT_MSR_LOAD_CNT_STR;
1311 case VMCS_ENTRY_CTRLS:
1312 return VMCS_ENTRY_CTRLS_STR;
1313 case VMCS_ENTRY_MSR_LOAD_CNT:
1314 return VMCS_ENTRY_MSR_LOAD_CNT_STR;
1315 case VMCS_ENTRY_INT_INFO:
1316 return VMCS_ENTRY_INT_INFO_STR;
1317 case VMCS_ENTRY_EXCP_ERR:
1318 return VMCS_ENTRY_EXCP_ERR_STR;
1319 case VMCS_ENTRY_INSTR_LEN:
1320 return VMCS_ENTRY_INSTR_LEN_STR;
1321 case VMCS_TPR_THRESHOLD:
1322 return VMCS_TPR_THRESHOLD_STR;
1323 case VMCS_SEC_PROC_CTRLS:
1324 return VMCS_SEC_PROC_CTRLS_STR;
1326 return VMCS_PLE_GAP_STR;
1327 case VMCS_PLE_WINDOW:
1328 return VMCS_PLE_WINDOW_STR;
1329 case VMCS_INSTR_ERR:
1330 return VMCS_INSTR_ERR_STR;
1331 case VMCS_EXIT_REASON:
1332 return VMCS_EXIT_REASON_STR;
1333 case VMCS_EXIT_INT_INFO:
1334 return VMCS_EXIT_INT_INFO_STR;
1335 case VMCS_EXIT_INT_ERR:
1336 return VMCS_EXIT_INT_ERR_STR;
1337 case VMCS_IDT_VECTOR_INFO:
1338 return VMCS_IDT_VECTOR_INFO_STR;
1339 case VMCS_IDT_VECTOR_ERR:
1340 return VMCS_IDT_VECTOR_ERR_STR;
1341 case VMCS_EXIT_INSTR_LEN:
1342 return VMCS_EXIT_INSTR_LEN_STR;
1343 case VMCS_EXIT_INSTR_INFO:
1344 return VMCS_EXIT_INSTR_INFO_STR;
1345 case VMCS_GUEST_ES_LIMIT:
1346 return VMCS_GUEST_ES_LIMIT_STR;
1347 case VMCS_GUEST_CS_LIMIT:
1348 return VMCS_GUEST_CS_LIMIT_STR;
1349 case VMCS_GUEST_SS_LIMIT:
1350 return VMCS_GUEST_SS_LIMIT_STR;
1351 case VMCS_GUEST_DS_LIMIT:
1352 return VMCS_GUEST_DS_LIMIT_STR;
1353 case VMCS_GUEST_FS_LIMIT:
1354 return VMCS_GUEST_FS_LIMIT_STR;
1355 case VMCS_GUEST_GS_LIMIT:
1356 return VMCS_GUEST_GS_LIMIT_STR;
1357 case VMCS_GUEST_LDTR_LIMIT:
1358 return VMCS_GUEST_LDTR_LIMIT_STR;
1359 case VMCS_GUEST_TR_LIMIT:
1360 return VMCS_GUEST_TR_LIMIT_STR;
1361 case VMCS_GUEST_GDTR_LIMIT:
1362 return VMCS_GUEST_GDTR_LIMIT_STR;
1363 case VMCS_GUEST_IDTR_LIMIT:
1364 return VMCS_GUEST_IDTR_LIMIT_STR;
1365 case VMCS_GUEST_ES_ACCESS:
1366 return VMCS_GUEST_ES_ACCESS_STR;
1367 case VMCS_GUEST_CS_ACCESS:
1368 return VMCS_GUEST_CS_ACCESS_STR;
1369 case VMCS_GUEST_SS_ACCESS:
1370 return VMCS_GUEST_SS_ACCESS_STR;
1371 case VMCS_GUEST_DS_ACCESS:
1372 return VMCS_GUEST_DS_ACCESS_STR;
1373 case VMCS_GUEST_FS_ACCESS:
1374 return VMCS_GUEST_FS_ACCESS_STR;
1375 case VMCS_GUEST_GS_ACCESS:
1376 return VMCS_GUEST_GS_ACCESS_STR;
1377 case VMCS_GUEST_LDTR_ACCESS:
1378 return VMCS_GUEST_LDTR_ACCESS_STR;
1379 case VMCS_GUEST_TR_ACCESS:
1380 return VMCS_GUEST_TR_ACCESS_STR;
1381 case VMCS_GUEST_INT_STATE:
1382 return VMCS_GUEST_INT_STATE_STR;
1383 case VMCS_GUEST_ACTIVITY_STATE:
1384 return VMCS_GUEST_ACTIVITY_STATE_STR;
1385 case VMCS_GUEST_SMBASE:
1386 return VMCS_GUEST_SMBASE_STR;
1387 case VMCS_GUEST_SYSENTER_CS:
1388 return VMCS_GUEST_SYSENTER_CS_STR;
1389 case VMCS_PREEMPT_TIMER:
1390 return VMCS_PREEMPT_TIMER_STR;
1391 case VMCS_HOST_SYSENTER_CS:
1392 return VMCS_HOST_SYSENTER_CS_STR;
1394 return VMCS_CR0_MASK_STR;
1396 return VMCS_CR4_MASK_STR;
1397 case VMCS_CR0_READ_SHDW:
1398 return VMCS_CR0_READ_SHDW_STR;
1399 case VMCS_CR4_READ_SHDW:
1400 return VMCS_CR4_READ_SHDW_STR;
1401 case VMCS_CR3_TGT_VAL_0:
1402 return VMCS_CR3_TGT_VAL_0_STR;
1403 case VMCS_CR3_TGT_VAL_1:
1404 return VMCS_CR3_TGT_VAL_1_STR;
1405 case VMCS_CR3_TGT_VAL_2:
1406 return VMCS_CR3_TGT_VAL_2_STR;
1407 case VMCS_CR3_TGT_VAL_3:
1408 return VMCS_CR3_TGT_VAL_3_STR;
1409 case VMCS_EXIT_QUAL:
1410 return VMCS_EXIT_QUAL_STR;
1412 return VMCS_IO_RCX_STR;
1414 return VMCS_IO_RSI_STR;
1416 return VMCS_IO_RDI_STR;
1418 return VMCS_IO_RIP_STR;
1419 case VMCS_GUEST_LINEAR_ADDR:
1420 return VMCS_GUEST_LINEAR_ADDR_STR;
1421 case VMCS_GUEST_CR0:
1422 return VMCS_GUEST_CR0_STR;
1423 case VMCS_GUEST_CR3:
1424 return VMCS_GUEST_CR3_STR;
1425 case VMCS_GUEST_CR4:
1426 return VMCS_GUEST_CR4_STR;
1427 case VMCS_GUEST_ES_BASE:
1428 return VMCS_GUEST_ES_BASE_STR;
1429 case VMCS_GUEST_CS_BASE:
1430 return VMCS_GUEST_CS_BASE_STR;
1431 case VMCS_GUEST_SS_BASE:
1432 return VMCS_GUEST_SS_BASE_STR;
1433 case VMCS_GUEST_DS_BASE:
1434 return VMCS_GUEST_DS_BASE_STR;
1435 case VMCS_GUEST_FS_BASE:
1436 return VMCS_GUEST_FS_BASE_STR;
1437 case VMCS_GUEST_GS_BASE:
1438 return VMCS_GUEST_GS_BASE_STR;
1439 case VMCS_GUEST_LDTR_BASE:
1440 return VMCS_GUEST_LDTR_BASE_STR;
1441 case VMCS_GUEST_TR_BASE:
1442 return VMCS_GUEST_TR_BASE_STR;
1443 case VMCS_GUEST_GDTR_BASE:
1444 return VMCS_GUEST_GDTR_BASE_STR;
1445 case VMCS_GUEST_IDTR_BASE:
1446 return VMCS_GUEST_IDTR_BASE_STR;
1447 case VMCS_GUEST_DR7:
1448 return VMCS_GUEST_DR7_STR;
1449 case VMCS_GUEST_RSP:
1450 return VMCS_GUEST_RSP_STR;
1451 case VMCS_GUEST_RIP:
1452 return VMCS_GUEST_RIP_STR;
1453 case VMCS_GUEST_RFLAGS:
1454 return VMCS_GUEST_RFLAGS_STR;
1455 case VMCS_GUEST_PENDING_DBG_EXCP:
1456 return VMCS_GUEST_PENDING_DBG_EXCP_STR;
1457 case VMCS_GUEST_SYSENTER_ESP:
1458 return VMCS_GUEST_SYSENTER_ESP_STR;
1459 case VMCS_GUEST_SYSENTER_EIP:
1460 return VMCS_GUEST_SYSENTER_EIP_STR;
1462 return VMCS_HOST_CR0_STR;
1464 return VMCS_HOST_CR3_STR;
1466 return VMCS_HOST_CR4_STR;
1467 case VMCS_HOST_FS_BASE:
1468 return VMCS_HOST_FS_BASE_STR;
1469 case VMCS_HOST_GS_BASE:
1470 return VMCS_HOST_GS_BASE_STR;
1471 case VMCS_HOST_TR_BASE:
1472 return VMCS_HOST_TR_BASE_STR;
1473 case VMCS_HOST_GDTR_BASE:
1474 return VMCS_HOST_GDTR_BASE_STR;
1475 case VMCS_HOST_IDTR_BASE:
1476 return VMCS_HOST_IDTR_BASE_STR;
1477 case VMCS_HOST_SYSENTER_ESP:
1478 return VMCS_HOST_SYSENTER_ESP_STR;
1479 case VMCS_HOST_SYSENTER_EIP:
1480 return VMCS_HOST_SYSENTER_EIP_STR;
1482 return VMCS_HOST_RSP_STR;
1484 return VMCS_HOST_RIP_STR;