From: Patrick G. Bridges Date: Mon, 20 Sep 2010 21:56:03 +0000 (-0600) Subject: Initial testing of new time handling on VMX, initial implementation of new X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=7711c884eae1625fdf136e6442c270d4992e22b4;p=palacios.git Initial testing of new time handling on VMX, initial implementation of new time handling on SVM. --- diff --git a/Kconfig b/Kconfig index 0e87296..1049045 100644 --- a/Kconfig +++ b/Kconfig @@ -324,7 +324,12 @@ config DEBUG_INTERRUPTS help This turns on debugging for the interrupt system - +config DEBUG_TIME + bool "Timing" + default n + depends on DEBUG_ON + help + This turns on debugging of system time virtualization config DEBUG_IO bool "IO" diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 3131cf2..55e591e 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -416,7 +416,6 @@ static int update_irq_entry_state(struct guest_info * info) { int v3_svm_enter(struct guest_info * info) { vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); - ullong_t tmp_tsc; addr_t exit_code = 0, exit_info1 = 0, exit_info2 = 0; // Conditionally yield the CPU if the timeslice has expired @@ -470,31 +469,27 @@ int v3_svm_enter(struct guest_info * info) { #endif - rdtscll(tmp_tsc); - v3_update_timers(info, (tmp_tsc - info->time_state.cached_host_tsc)); - rdtscll(info->time_state.cached_host_tsc); - // guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc; + v3_update_timers(info); + v3_resume_time(info); + guest_ctrl->TSC_OFFSET = info->time_state.host_offset; //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_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip); + v3_pause_time(info); +#ifdef OPTION_TIME_MASK_OVERHEAD + v3_offset_time(info, -SVM_ENTRY_OVERHEAD); +#endif - v3_last_exit = (uint32_t)(guest_ctrl->exit_code); + //V3_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip); - //rdtscll(tmp_tsc); - // v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc); + v3_last_exit = (uint32_t)(guest_ctrl->exit_code); //PrintDebug("SVM Returned\n"); info->num_exits++; - - - // Save Guest state from VMCB info->rip = guest_state->rip; info->vm_regs.rsp = guest_state->rsp; @@ -590,8 +585,7 @@ int v3_start_svm_guest(struct guest_info *info) { //PrintDebugVMCB((vmcb_t*)(info->vmm_data)); info->vm_info->run_state = VM_RUNNING; - rdtscll(info->yield_start_cycle); - + v3_start_time(info); while (1) { if (v3_svm_enter(info) == -1) { diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 4bd30ef..3604bc2 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -21,6 +21,11 @@ #include #include +#ifndef CONFIG_DEBUG_TIME +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + static int handle_cpufreq_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) { struct vm_time * time_state = &(info->time_state); @@ -62,6 +67,8 @@ uint64_t v3_get_guest_time(struct guest_info * info) { int v3_start_time(struct guest_info * info) { /* We start running with guest_time == host_time */ uint64_t t = v3_get_host_time(info); + + PrintDebug("Starting initial guest time as %llu\n", t); info->time_state.last_update = t; info->time_state.pause_time = t; return 0; @@ -70,17 +77,24 @@ int v3_start_time(struct guest_info * info) { int v3_pause_time(struct guest_info * info) { V3_ASSERT(info->time_state.pause_time == 0); info->time_state.pause_time = v3_get_guest_time(info); + PrintDebug("Time paused at guest time as %llu\n", + info->time_state.pause_time); return 0; } int v3_resume_time(struct guest_info * info) { uint64_t t = v3_get_host_time(info); V3_ASSERT(info->time_state.pause_time != 0); -#ifdef OPTION_TIME_ADJUST_TSC_OFFSET -#endif info->time_state.host_offset = (sint64_t)info->time_state.pause_time - (sint64_t)t; +#ifdef OPTION_TIME_ADJUST_TSC_OFFSET + /* XXX Adjust host_offset towards zero based on resolution/accuracy + * constraints. */ +#endif info->time_state.pause_time = 0; + PrintDebug("Time resumed paused at guest time as %llu " + "offset %lld from host time.\n", t, info->time_state.host_offset); + return 0; } diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index a297be2..bb93054 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -672,7 +672,8 @@ int v3_vmx_enter(struct guest_info * info) { tsc_offset_low = (uint32_t)(info->time_state.host_offset & 0xffffffff); check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high); check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low); - + PrintDebug("Stored 0x %x %x into vmcs TSC offset.\n", + tsc_offset_high, tsc_offset_low); if (info->vm_info->run_state == VM_STOPPED) { info->vm_info->run_state = VM_RUNNING; ret = v3_vmx_launch(&(info->vm_regs), info, &(info->ctrl_regs)); diff --git a/palacios/src/palacios/vmx_handler.c b/palacios/src/palacios/vmx_handler.c index d88210d..9d29f9f 100644 --- a/palacios/src/palacios/vmx_handler.c +++ b/palacios/src/palacios/vmx_handler.c @@ -99,6 +99,17 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf } break; + +#if 0 + case VMEXIT_RDTSC: + if (v3_handle_rdtsc(info) == -1) { + PrintError("Error Handling RDTSC instruction\n"); + return -1; + } + + break; +#endif + case VMEXIT_CPUID: if (v3_handle_cpuid(info) == -1) { PrintError("Error Handling CPUID instruction\n");