From: Patrick G. Bridges Date: Thu, 29 Mar 2012 20:17:00 +0000 (-0600) Subject: Fixed conditional yield frequency calculation in yield_cond. Added runtime X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=9fce3687216ee6401cbf006a6fd14b6f7e16db6e;p=palacios.releases.git Fixed conditional yield frequency calculation in yield_cond. Added runtime control of whether RDTSC traps to both SVM and VMX. --- diff --git a/palacios/include/palacios/vmm_time.h b/palacios/include/palacios/vmm_time.h index bcb19e6..4b3cb2e 100644 --- a/palacios/include/palacios/vmm_time.h +++ b/palacios/include/palacios/vmm_time.h @@ -37,6 +37,8 @@ struct v3_time { char follow_host_time; }; +#define V3_TIME_TRAP_RDTSC 0x1 + /* Per-core time information */ struct vm_core_time { uint32_t host_cpu_freq; // in kHZ @@ -56,6 +58,8 @@ struct vm_core_time { uint64_t vm_pause_host_time; // Host time when we went into the VMM struct v3_msr tsc_aux; // Auxilliary MSR for RDTSCP + int time_flags; + // Installed Timers slaved off of the guest monotonic TSC uint_t num_timers; struct list_head timers; diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 8eb1f61..962a34b 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -129,10 +129,9 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * core) { ctrl_area->instrs.HLT = 1; -#ifdef V3_CONFIG_TIME_VIRTUALIZE_TSC - ctrl_area->instrs.RDTSC = 1; - ctrl_area->svm_instrs.RDTSCP = 1; -#endif + /* Set at VMM launch as needed */ + ctrl_area->instrs.RDTSC = 0; + ctrl_area->svm_instrs.RDTSCP = 0; // guest_state->cr0 = 0x00000001; // PE @@ -518,6 +517,20 @@ static int update_irq_entry_state(struct guest_info * info) { return 0; } +int +v3_svm_config_tsc_virtualization(struct guest_info * info) { + vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); + + if (info->time_state.time_flags & V3_TIME_TRAP_RDTSC) { + ctrl_area->instrs.RDTSC = 1; + ctrl_area->svm_instrs.RDTSCP = 1; + } else { + ctrl_area->instrs.RDTSC = 0; + ctrl_area->svm_instrs.RDTSCP = 0; + ctrl_area->TSC_OFFSET = v3_tsc_host_offset(&info->time_state); + } + return 0; +} /* * CAUTION and DANGER!!! @@ -531,7 +544,6 @@ 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)); addr_t exit_code = 0, exit_info1 = 0, exit_info2 = 0; - sint64_t tsc_offset; uint64_t guest_cycles = 0; // Conditionally yield the CPU if the timeslice has expired @@ -591,9 +603,7 @@ int v3_svm_enter(struct guest_info * info) { #endif v3_time_enter_vm(info); - tsc_offset = v3_tsc_host_offset(&info->time_state); - guest_ctrl->TSC_OFFSET = tsc_offset; - + v3_svm_config_tsc_virtualization(info); //V3_Print("Calling v3_svm_launch\n"); { diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index d2d01fb..8bd6c0a 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -697,8 +697,8 @@ void v3_yield_cond(struct guest_info * info) { // (void *)cur_cycle, (void *)info->yield_start_cycle, // (void *)info->yield_cycle_period); + info->yield_start_cycle += info->vm_info->yield_cycle_period; V3_Yield(); - info->yield_start_cycle = v3_get_host_time(&info->time_state); } } diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 38f5f6e..00e8869 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -420,6 +420,8 @@ void v3_init_time_core(struct guest_info * info) { time_state->vm_enter_host_time = 0; time_state->vm_pause_host_time = 0; + time_state->time_flags = 0; // XXX need to set virtualize TSC flag or not... + INIT_LIST_HEAD(&(time_state->timers)); time_state->num_timers = 0; diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index a30cb4e..87dfac0 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -835,7 +835,33 @@ static void print_exit_log(struct guest_info * info) { } +int +v3_vmx_config_tsc_virtualization(struct guest_info * info) { + struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data); + + if (info->time_state.time_flags & V3_TIME_TRAP_RDTSC) { + if (!vmx_info->pri_proc_ctrls.rdtsc_exit) { + vmx_info->pri_proc_ctrls.rdtsc_exit = 1; + check_vmcs_write(VMCS_PROC_CTRLS, vmx_info->pri_proc_ctrls.value); + } + } else { + sint64_t tsc_offset; + uint32_t tsc_offset_low, tsc_offset_high; + + if (vmx_info->pri_proc_ctrls.rdtsc_exit) { + vmx_info->pri_proc_ctrls.rdtsc_exit = 0; + check_vmcs_write(VMCS_PROC_CTRLS, vmx_info->pri_proc_ctrls.value); + } + tsc_offset = v3_tsc_host_offset(&info->time_state); + tsc_offset_high = (uint32_t)(( tsc_offset >> 32) & 0xffffffff); + tsc_offset_low = (uint32_t)(tsc_offset & 0xffffffff); + + check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high); + check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low); + } + return 0; +} /* * CAUTION and DANGER!!! @@ -847,8 +873,6 @@ static void print_exit_log(struct guest_info * info) { */ int v3_vmx_enter(struct guest_info * info) { int ret = 0; - sint64_t tsc_offset; - 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); uint64_t guest_cycles = 0; @@ -892,13 +916,7 @@ 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 = v3_tsc_host_offset(&info->time_state); - tsc_offset_high = (uint32_t)(( tsc_offset >> 32) & 0xffffffff); - tsc_offset_low = (uint32_t)(tsc_offset & 0xffffffff); - - check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high); - check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low); + v3_vmx_config_tsc_virtualization(info);