X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmx.c;h=2984de8fb5fc7c179dcf98964831b6771207156f;hb=6d3926e16dc1ba6ca0144e65b737e432c48aaa91;hp=de81dfc9df654f5b3e731765819ffbc2e4ba0161;hpb=9feccf93cd8327d1d30a404a92f19716bf5a1e96;p=palacios.git diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index de81dfc..2984de8 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -44,6 +44,10 @@ #include #include +#ifdef V3_CONFIG_MEM_TRACK +#include +#endif + #ifndef V3_CONFIG_DEBUG_VMX #undef PrintDebug #define PrintDebug(fmt, args...) @@ -270,16 +274,19 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) // Cause VM_EXIT whenever CR4.VMXE or CR4.PAE bits are written - vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, CR4_VMXE | CR4_PAE); + vmx_ret |= check_vmcs_write(VMCS_CR4_MASK, CR4_VMXE | CR4_PAE ); - core->ctrl_regs.cr3 = core->direct_map_pt; + v3_activate_passthrough_pt(core); // vmx_state->pinbased_ctrls |= NMI_EXIT; /* Add CR exits */ vmx_state->pri_proc_ctrls.cr3_ld_exit = 1; vmx_state->pri_proc_ctrls.cr3_str_exit = 1; - + + // Note that we intercept cr4.pae writes + // and we have cr4 read-shadowed to the shadow pager's cr4 + vmx_state->pri_proc_ctrls.invlpg_exit = 1; /* Add page fault exits */ @@ -326,7 +333,7 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) - if (v3_init_ept(core, &hw_info) == -1) { + if (v3_init_nested_paging_core(core, &hw_info) == -1) { PrintError(core->vm_info, core, "Error initializing EPT\n"); return -1; } @@ -424,7 +431,7 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) ((struct cr0_32 *)&(core->shdw_pg_state.guest_cr0))->ne = 1; ((struct cr0_32 *)&(core->shdw_pg_state.guest_cr0))->cd = 0; - if (v3_init_ept(core, &hw_info) == -1) { + if (v3_init_nested_paging_core(core, &hw_info) == -1) { PrintError(core->vm_info, core, "Error initializing EPT\n"); return -1; } @@ -539,7 +546,10 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) vmx_ret |= check_vmcs_write(VMCS_LINK_PTR_HIGH, (addr_t)0xffffffffUL); #endif - + if (vmx_ret != VMX_SUCCESS) { + PrintError(core->vm_info, core, "Error configuring VMX\n"); + return -1; + } @@ -614,6 +624,11 @@ static void __init_vmx_vmcs(void * arg) { PrintDebug(core->vm_info, core, "Serializing VMCS: %p\n", (void *)vmx_state->vmcs_ptr_phys); vmx_ret = vmcs_clear(vmx_state->vmcs_ptr_phys); + if (vmx_ret != VMX_SUCCESS) { + PrintError(core->vm_info,core,"VMCS Clear failed\n"); + return; + } + core->core_run_state = CORE_STOPPED; return; } @@ -975,6 +990,10 @@ int v3_vmx_enter(struct guest_info * info) { // Conditionally yield the CPU if the timeslice has expired v3_schedule(info); +#ifdef V3_CONFIG_MEM_TRACK + v3_mem_track_entry(info); +#endif + // Update timer devices late after being in the VM so that as much // of the time in the VM is accounted for as possible. Also do it before // updating IRQ entry state so that any interrupts the timers raise get @@ -1119,6 +1138,8 @@ int v3_vmx_enter(struct guest_info * info) { if (info->shdw_pg_mode == NESTED_PAGING) { check_vmcs_read(VMCS_GUEST_PHYS_ADDR, &(exit_info.ept_fault_addr)); + } else { + exit_info.ept_fault_addr = 0; } //PrintDebug(info->vm_info, info, "VMX Exit taken, id-qual: %u-%lu\n", exit_info.exit_reason, exit_info.exit_qual); @@ -1175,6 +1196,10 @@ int v3_vmx_enter(struct guest_info * info) { v3_handle_timeouts(info, guest_cycles); } +#ifdef V3_CONFIG_MEM_TRACK + v3_mem_track_exit(info); +#endif + return 0; } @@ -1183,6 +1208,20 @@ int v3_start_vmx_guest(struct guest_info * info) { PrintDebug(info->vm_info, info, "Starting VMX core %u\n", info->vcpu_id); +#ifdef V3_CONFIG_MULTIBOOT + if (v3_setup_multiboot_core_for_boot(info)) { + PrintError(info->vm_info, info, "Failed to setup Multiboot core...\n"); + return -1; + } +#endif + +#ifdef V3_CONFIG_HVM + if (v3_setup_hvm_hrt_core_for_boot(info)) { + PrintError(info->vm_info, info, "Failed to setup HRT core...\n"); + return -1; + } +#endif + while (1) { if (info->core_run_state == CORE_STOPPED) { if (info->vcpu_id == 0) { @@ -1230,6 +1269,18 @@ int v3_start_vmx_guest(struct guest_info * info) { } +#ifdef V3_CONFIG_HVM + if (v3_handle_hvm_reset(info) > 0) { + continue; + } +#endif + +#ifdef V3_CONFIG_MULTIBOOT + if (v3_handle_multiboot_reset(info) > 0) { + continue; + } +#endif + #ifdef V3_CONFIG_PMU_TELEMETRY v3_pmu_telemetry_start(info); #endif @@ -1255,9 +1306,15 @@ int v3_start_vmx_guest(struct guest_info * info) { linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); if (info->mem_mode == PHYSICAL_MEM) { - v3_gpa_to_hva(info, linear_addr, &host_addr); + if (v3_gpa_to_hva(info, linear_addr, &host_addr)) { + PrintError(info->vm_info, info, "Cannot translate address\n"); + return -1; + } } else if (info->mem_mode == VIRTUAL_MEM) { - v3_gva_to_hva(info, linear_addr, &host_addr); + if (v3_gva_to_hva(info, linear_addr, &host_addr)) { + PrintError(info->vm_info, info, "Cannot translate address\n"); + return -1; + } } V3_Print(info->vm_info, info, "VMX core %u: Host Address of rip = 0x%p\n", info->vcpu_id, (void *)host_addr);