X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmx.c;h=87dfac0e57d31ac0bb8451a26e08543a415c7ce8;hb=d6a4d7bf28c8962ad6a1499d0b74b9e5cdf892ad;hp=b5ec7689aefaa1fdda597f238980b01735f5390d;hpb=92082ed86bcfd503e28dbedb24c79c3dc797dc87;p=palacios.git diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index b5ec768..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; @@ -856,9 +880,6 @@ int v3_vmx_enter(struct guest_info * 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_disable_ints(); @@ -866,6 +887,7 @@ int v3_vmx_enter(struct guest_info * info) { // 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 // handled on the next VM entry. Must be done with interrupts disabled. + v3_advance_time(info); v3_update_timers(info); if (vmcs_store() != vmx_info->vmcs_ptr_phys) { @@ -894,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);