X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fsvm.c;h=bb65a6fbbf87723cc90e32189a442c1cd25f09bc;hb=b3e5aa263c35961c74e0b7ed96b8510e8c6d7d0d;hp=f59bdc7ead2844fd3628452dd50cdb865fa1909b;hpb=29b7ff8811c82ab543f5c969e44ff217637a09c7;p=palacios.git diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index f59bdc7..bb65a6f 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -218,6 +218,11 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * core) { ctrl_area->instrs.INTR = 1; + v3_hook_msr(core->vm_info, EFER_MSR, + &v3_handle_efer_read, + &v3_handle_efer_write, + core); + if (core->shdw_pg_mode == SHADOW_PAGING) { PrintDebug("Creating initial shadow page table\n"); @@ -246,10 +251,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * core) { ctrl_area->cr_reads.cr3 = 1; ctrl_area->cr_writes.cr3 = 1; - v3_hook_msr(core->vm_info, EFER_MSR, - &v3_handle_efer_read, - &v3_handle_efer_write, - core); + ctrl_area->instrs.INVLPG = 1; @@ -291,7 +293,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * core) { int v3_init_svm_vmcb(struct guest_info * core, v3_vm_class_t vm_class) { PrintDebug("Allocating VMCB\n"); - core->vmm_data = (void*)Allocate_VMCB(); + core->vmm_data = (void *)Allocate_VMCB(); if (core->vmm_data == NULL) { PrintError("Could not allocate VMCB, Exiting...\n"); @@ -311,7 +313,7 @@ int v3_init_svm_vmcb(struct guest_info * core, v3_vm_class_t vm_class) { int v3_deinit_svm_vmcb(struct guest_info * core) { - V3_FreePages(core->vmm_data, 1); + V3_FreePages(V3_PAddr(core->vmm_data), 1); return 0; } @@ -451,14 +453,18 @@ int v3_svm_enter(struct guest_info * info) { vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); addr_t exit_code = 0, exit_info1 = 0, exit_info2 = 0; - v3_adjust_time(info); - // Conditionally yield the CPU if the timeslice has expired v3_yield_cond(info); + // Perform any additional yielding needed for time adjustment + v3_adjust_time(info); + // disable global interrupts for vm state transition v3_clgi(); + // Update timer devices prior to entering VM. + v3_update_timers(info); + // Synchronize the guest state to the VMCB guest_state->cr0 = info->ctrl_regs.cr0; guest_state->cr2 = info->ctrl_regs.cr2; @@ -503,19 +509,20 @@ int v3_svm_enter(struct guest_info * info) { } #endif - v3_update_timers(info); + v3_time_enter_vm(info); guest_ctrl->TSC_OFFSET = v3_tsc_host_offset(&info->time_state); //V3_Print("Calling v3_svm_launch\n"); - v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]); + v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[V3_Get_CPU()]); //V3_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip); v3_last_exit = (uint32_t)(guest_ctrl->exit_code); - //PrintDebug("SVM Returned\n"); - + // Immediate exit from VM time bookkeeping + v3_time_exit_vm(info); + info->num_exits++; // Save Guest state from VMCB @@ -567,6 +574,7 @@ int v3_svm_enter(struct guest_info * info) { if (v3_handle_svm_exit(info, exit_code, exit_info1, exit_info2) != 0) { PrintError("Error in SVM exit handler\n"); + PrintError(" last exit was %d\n", v3_last_exit); return -1; } @@ -769,7 +777,27 @@ void v3_init_svm_cpu(int cpu_id) { +void v3_deinit_svm_cpu(int cpu_id) { + reg_ex_t msr; + extern v3_cpu_arch_t v3_cpu_types[]; + + // reset SVM_VM_HSAVE_PA_MSR + // Does setting it to NULL disable?? + msr.r_reg = 0; + v3_set_msr(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low); + + // Disable SVM? + v3_get_msr(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low)); + msr.e_reg.low &= ~EFER_MSR_svm_enable; + v3_set_msr(EFER_MSR, 0, msr.e_reg.low); + + v3_cpu_types[cpu_id] = V3_INVALID_CPU; + V3_FreePages((void *)host_vmcbs[cpu_id], 4); + + V3_Print("Host CPU %d host area freed, and SVM disabled\n", cpu_id); + return; +}