X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmx.c;h=bc45c9b444b882e33666fa869e989be46e4d13d4;hb=3e31ab96d49dcd604f85f9f81a7acc37a43ef036;hp=bdfc8c04cb19fa8ac923a71cfd8d35679fec1bc4;hpb=55e1aec9b0d2358b02721d3d331089e100f3fe27;p=palacios.git diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index bdfc8c0..bc45c9b 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -349,13 +349,6 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) // save STAR, LSTAR, FMASK, KERNEL_GS_BASE MSRs in MSR load/store area { -#define IA32_STAR 0xc0000081 -#define IA32_LSTAR 0xc0000082 -#define IA32_FMASK 0xc0000084 -#define IA32_KERN_GS_BASE 0xc0000102 - -#define IA32_CSTAR 0xc0000083 // Compatibility mode STAR (ignored for now... hopefully its not that important...) - int msr_ret = 0; struct vmcs_msr_entry * exit_store_msrs = NULL; @@ -387,24 +380,42 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) entry_load_msrs = (struct vmcs_msr_entry *)(vmx_state->msr_area + (sizeof(struct vmcs_msr_entry) * 8)); - exit_store_msrs[0].index = IA32_STAR; - exit_store_msrs[1].index = IA32_LSTAR; - exit_store_msrs[2].index = IA32_FMASK; - exit_store_msrs[3].index = IA32_KERN_GS_BASE; + exit_store_msrs[0].index = IA32_STAR_MSR; + exit_store_msrs[1].index = IA32_LSTAR_MSR; + exit_store_msrs[2].index = IA32_FMASK_MSR; + exit_store_msrs[3].index = IA32_KERN_GS_BASE_MSR; memcpy(exit_store_msrs, exit_load_msrs, sizeof(struct vmcs_msr_entry) * 4); memcpy(exit_store_msrs, entry_load_msrs, sizeof(struct vmcs_msr_entry) * 4); - v3_get_msr(IA32_STAR, &(exit_load_msrs[0].hi), &(exit_load_msrs[0].lo)); - v3_get_msr(IA32_LSTAR, &(exit_load_msrs[1].hi), &(exit_load_msrs[1].lo)); - v3_get_msr(IA32_FMASK, &(exit_load_msrs[2].hi), &(exit_load_msrs[2].lo)); - v3_get_msr(IA32_KERN_GS_BASE, &(exit_load_msrs[3].hi), &(exit_load_msrs[3].lo)); + v3_get_msr(IA32_STAR_MSR, &(exit_load_msrs[0].hi), &(exit_load_msrs[0].lo)); + v3_get_msr(IA32_LSTAR_MSR, &(exit_load_msrs[1].hi), &(exit_load_msrs[1].lo)); + v3_get_msr(IA32_FMASK_MSR, &(exit_load_msrs[2].hi), &(exit_load_msrs[2].lo)); + v3_get_msr(IA32_KERN_GS_BASE_MSR, &(exit_load_msrs[3].hi), &(exit_load_msrs[3].lo)); msr_ret |= check_vmcs_write(VMCS_EXIT_MSR_STORE_ADDR, (addr_t)V3_PAddr(exit_store_msrs)); msr_ret |= check_vmcs_write(VMCS_EXIT_MSR_LOAD_ADDR, (addr_t)V3_PAddr(exit_load_msrs)); msr_ret |= check_vmcs_write(VMCS_ENTRY_MSR_LOAD_ADDR, (addr_t)V3_PAddr(entry_load_msrs)); + + v3_hook_msr(core->vm_info, IA32_STAR_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, IA32_LSTAR_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, IA32_FMASK_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, IA32_KERN_GS_BASE_MSR, NULL, NULL, NULL); + + + // IMPORTANT: These SYSCALL MSRs are currently not handled by hardware or cached + // We should really emulate these ourselves, or ideally include them in the MSR store area if there is room + v3_hook_msr(core->vm_info, IA32_CSTAR_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, SYSENTER_CS_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, SYSENTER_ESP_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, SYSENTER_EIP_MSR, NULL, NULL, NULL); + + v3_hook_msr(core->vm_info, FS_BASE_MSR, NULL, NULL, NULL); + v3_hook_msr(core->vm_info, GS_BASE_MSR, NULL, NULL, NULL); + + } /* Sanity check ctrl/reg fields against hw_defaults */ @@ -750,7 +761,7 @@ static void print_exit_log(struct guest_info * info) { */ int v3_vmx_enter(struct guest_info * info) { int ret = 0; - //uint32_t tsc_offset_low, tsc_offset_high; + uint32_t tsc_offset_low, tsc_offset_high; struct vmx_exit_info exit_info; struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data); @@ -795,10 +806,10 @@ int v3_vmx_enter(struct guest_info * info) { // Perform last-minute time bookkeeping prior to entering the VM v3_time_enter_vm(info); - // tsc_offset_high = (uint32_t)((v3_tsc_host_offset(&info->time_state) >> 32) & 0xffffffff); - // tsc_offset_low = (uint32_t)(v3_tsc_host_offset(&info->time_state) & 0xffffffff); - // check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high); - // check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low); + tsc_offset_high = (uint32_t)((v3_tsc_host_offset(&info->time_state) >> 32) & 0xffffffff); + tsc_offset_low = (uint32_t)(v3_tsc_host_offset(&info->time_state) & 0xffffffff); + check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high); + check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low); if (v3_update_vmcs_host_state(info)) { v3_enable_ints(); @@ -909,6 +920,12 @@ int v3_start_vmx_guest(struct guest_info * info) { PrintDebug("VMX core %u: Waiting for core initialization\n", info->vcpu_id); while (info->core_run_state == CORE_STOPPED) { + + if (info->vm_info->run_state == VM_STOPPED) { + // The VM was stopped before this core was initialized. + return 0; + } + v3_yield(info); //PrintDebug("VMX core %u: still waiting for INIT\n",info->vcpu_id); }