X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmx_handler.c;h=5af3122c84f432abe2e6579a61294bc14e3eb594;hb=cf780b903a02efc700d51dbadcc90115f016256c;hp=e5da7622e724c3dd556e27d0b51b1153d182eb95;hpb=1ebf37356d541b20aef0ff6d383861558875a604;p=palacios.releases.git diff --git a/palacios/src/palacios/vmx_handler.c b/palacios/src/palacios/vmx_handler.c index e5da762..5af3122 100644 --- a/palacios/src/palacios/vmx_handler.c +++ b/palacios/src/palacios/vmx_handler.c @@ -31,18 +31,21 @@ #include #include #include +#include -#ifndef CONFIG_DEBUG_VMX +#ifndef V3_CONFIG_DEBUG_VMX #undef PrintDebug #define PrintDebug(fmt, args...) #endif -#ifdef CONFIG_TELEMETRY +#ifdef V3_CONFIG_TELEMETRY #include #endif /* At this point the GPRs are already copied into the guest_info state */ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_info) { + struct vmx_basic_exit_info * basic_info = (struct vmx_basic_exit_info *)&(exit_info->exit_reason); + /* PrintError("Handling VMEXIT: %s (%u), %lu (0x%lx)\n", v3_vmx_exit_code_to_str(exit_info->exit_reason), @@ -52,20 +55,40 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf v3_print_vmcs(); */ -#ifdef CONFIG_TELEMETRY + + if (basic_info->entry_error == 1) { + switch (basic_info->reason) { + case VMEXIT_INVALID_GUEST_STATE: + PrintError("VM Entry failed due to invalid guest state\n"); + PrintError("Printing VMCS: (NOTE: This VMCS may not belong to the correct guest)\n"); + v3_print_vmcs(); + break; + case VMEXIT_INVALID_MSR_LOAD: + PrintError("VM Entry failed due to error loading MSRs\n"); + break; + default: + PrintError("Entry failed for unknown reason (%d)\n", basic_info->reason); + break; + } + + return -1; + } + + +#ifdef V3_CONFIG_TELEMETRY if (info->vm_info->enable_telemetry) { v3_telemetry_start_exit(info); } #endif - switch (exit_info->exit_reason) { + switch (basic_info->reason) { case VMEXIT_INFO_EXCEPTION_OR_NMI: { pf_error_t error_code = *(pf_error_t *)&(exit_info->int_err); // JRL: Change "0x0e" to a macro value - if ((uint8_t)exit_info->int_info == 0x0e) { -#ifdef CONFIG_DEBUG_SHADOW_PAGING + if ((uint8_t)exit_info->int_info == 14) { +#ifdef V3_CONFIG_DEBUG_SHADOW_PAGING PrintDebug("Page Fault at %p error_code=%x\n", (void *)exit_info->exit_qual, *(uint32_t *)&error_code); #endif @@ -74,6 +97,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf PrintError("Error handling shadow page fault\n"); return -1; } + } else { PrintError("Page fault in unimplemented paging mode\n"); return -1; @@ -86,6 +110,16 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; } + case VMEXIT_EPT_VIOLATION: { + struct ept_exit_qual * ept_qual = (struct ept_exit_qual *)&(exit_info->exit_qual); + + if (v3_handle_ept_fault(info, exit_info->ept_fault_addr, ept_qual) == -1) { + PrintError("Error handling EPT fault\n"); + return -1; + } + + break; + } case VMEXIT_INVLPG: if (info->shdw_pg_mode == SHADOW_PAGING) { if (v3_handle_shadow_invlpg(info) == -1) { @@ -97,7 +131,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; case VMEXIT_RDTSC: -#ifdef CONFIG_DEBUG_TIME +#ifdef V3_CONFIG_DEBUG_TIME PrintDebug("RDTSC\n"); #endif if (v3_handle_rdtsc(info) == -1) { @@ -190,12 +224,22 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf return -1; } break; + case 4: + //PrintDebug("Handling CR4 Access\n"); + if (v3_vmx_handle_cr4_access(info, cr_qual) == -1) { + PrintError("Error in CR4 access handler\n"); + return -1; + } + break; default: PrintError("Unhandled CR access: %d\n", cr_qual->cr_id); return -1; } - info->rip += exit_info->instr_len; + // TODO: move RIP increment into all of the above individual CR + // handlers, not just v3_vmx_handle_cr4_access() + if (cr_qual->cr_id != 4) + info->rip += exit_info->instr_len; break; } @@ -208,6 +252,9 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf } break; + + + case VMEXIT_PAUSE: // Handled as NOP info->rip += 2; @@ -220,16 +267,18 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf // This is handled in the atomic part of the vmx code, // not in the generic (interruptable) vmx handler break; + + default: PrintError("Unhandled VMEXIT: %s (%u), %lu (0x%lx)\n", - v3_vmx_exit_code_to_str(exit_info->exit_reason), - exit_info->exit_reason, + v3_vmx_exit_code_to_str(basic_info->reason), + basic_info->reason, exit_info->exit_qual, exit_info->exit_qual); return -1; } -#ifdef CONFIG_TELEMETRY +#ifdef V3_CONFIG_TELEMETRY if (info->vm_info->enable_telemetry) { v3_telemetry_end_exit(info, exit_info->exit_reason); } @@ -271,12 +320,12 @@ static const char VMEXIT_MOV_DR_STR[] = "VMEXIT_MOV_DR"; static const char VMEXIT_IO_INSTR_STR[] = "VMEXIT_IO_INSTR"; static const char VMEXIT_RDMSR_STR[] = "VMEXIT_RDMSR"; static const char VMEXIT_WRMSR_STR[] = "VMEXIT_WRMSR"; -static const char VMEXIT_ENTRY_FAIL_INVALID_GUEST_STATE_STR[] = "VMEXIT_ENTRY_FAIL_INVALID_GUEST_STATE"; -static const char VMEXIT_ENTRY_FAIL_MSR_LOAD_STR[] = "VMEXIT_ENTRY_FAIL_MSR_LOAD"; +static const char VMEXIT_INVALID_GUEST_STATE_STR[] = "VMEXIT_INVALID_GUEST_STATE"; +static const char VMEXIT_INVALID_MSR_LOAD_STR[] = "VMEXIT_INVALID_MSR_LOAD"; static const char VMEXIT_MWAIT_STR[] = "VMEXIT_MWAIT"; static const char VMEXIT_MONITOR_STR[] = "VMEXIT_MONITOR"; static const char VMEXIT_PAUSE_STR[] = "VMEXIT_PAUSE"; -static const char VMEXIT_ENTRY_FAILURE_MACHINE_CHECK_STR[] = "VMEXIT_ENTRY_FAILURE_MACHINE_CHECK"; +static const char VMEXIT_INVALID_MACHINE_CHECK_STR[] = "VMEXIT_INVALIDE_MACHINE_CHECK"; static const char VMEXIT_TPR_BELOW_THRESHOLD_STR[] = "VMEXIT_TPR_BELOW_THRESHOLD"; static const char VMEXIT_APIC_STR[] = "VMEXIT_APIC"; static const char VMEXIT_GDTR_IDTR_STR[] = "VMEXIT_GDTR_IDTR"; @@ -357,18 +406,18 @@ const char * v3_vmx_exit_code_to_str(vmx_exit_t exit) return VMEXIT_RDMSR_STR; case VMEXIT_WRMSR: return VMEXIT_WRMSR_STR; - case VMEXIT_ENTRY_FAIL_INVALID_GUEST_STATE: - return VMEXIT_ENTRY_FAIL_INVALID_GUEST_STATE_STR; - case VMEXIT_ENTRY_FAIL_MSR_LOAD: - return VMEXIT_ENTRY_FAIL_MSR_LOAD_STR; + case VMEXIT_INVALID_GUEST_STATE: + return VMEXIT_INVALID_GUEST_STATE_STR; + case VMEXIT_INVALID_MSR_LOAD: + return VMEXIT_INVALID_MSR_LOAD_STR; case VMEXIT_MWAIT: return VMEXIT_MWAIT_STR; case VMEXIT_MONITOR: return VMEXIT_MONITOR_STR; case VMEXIT_PAUSE: return VMEXIT_PAUSE_STR; - case VMEXIT_ENTRY_FAILURE_MACHINE_CHECK: - return VMEXIT_ENTRY_FAILURE_MACHINE_CHECK_STR; + case VMEXIT_INVALID_MACHINE_CHECK: + return VMEXIT_INVALID_MACHINE_CHECK_STR; case VMEXIT_TPR_BELOW_THRESHOLD: return VMEXIT_TPR_BELOW_THRESHOLD_STR; case VMEXIT_APIC: