X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_time.c;h=cdd9040ca4097d519727b95a0a636a4a5a650426;hb=c36e3174fd73fbdb8af835a44e2e3f0e5d75ca37;hp=67cdee9befbd64cc2c146aa76a4edc7b4ccc89f8;hpb=2d3172e90b9f059548bf5dfcf4f85ed71672aac7;p=palacios.git diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 67cdee9..cdd9040 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -136,7 +136,7 @@ int v3_advance_time(struct guest_info * info, uint64_t *host_cycles) uint64_t dilated_elapsed = (host_elapsed * vm_ts->td_num) / vm_ts->td_denom; uint64_t guest_elapsed = host_to_guest_cycles(info, dilated_elapsed); guest_cycles = guest_elapsed - v3_get_guest_time(&info->time_state); - } else if (*host_cycles) { + } else if (host_cycles) { guest_cycles = host_to_guest_cycles(info, *host_cycles); } else { guest_cycles = 0; @@ -300,59 +300,55 @@ static int tsc_msr_write_hook(struct guest_info *info, uint_t msr_num, struct vm_core_time * time_state = &(info->time_state); uint64_t guest_time, new_tsc; - V3_ASSERT(msr_num == TSC_MSR); + V3_ASSERT(msr_num == TSC_MSR); - new_tsc = (((uint64_t)msr_val.hi) << 32) | (uint64_t)msr_val.lo; - guest_time = v3_get_guest_time(time_state); - time_state->tsc_guest_offset = (sint64_t)(new_tsc - guest_time); + new_tsc = (((uint64_t)msr_val.hi) << 32) | (uint64_t)msr_val.lo; + guest_time = v3_get_guest_time(time_state); + time_state->tsc_guest_offset = (sint64_t)(new_tsc - guest_time); - return 0; -} + return 0; + } static int handle_time_configuration(struct v3_vm_info * vm, v3_cfg_tree_t *cfg) { - v3_cfg_tree_t * slave; + char *source, *dilation; - vm->time_state.flags = 0; + vm->time_state.flags = V3_TIME_SLAVE_HOST; vm->time_state.td_num = vm->time_state.td_denom = 1; if (!cfg) return 0; - slave = v3_cfg_subtree(cfg, "slave"); - - if (slave) { - char *source = v3_cfg_val(slave, "source"); - v3_cfg_tree_t *dilation = v3_cfg_subtree(slave, "dilation"); - if (source) { - if (strcasecmp(source, "host") == 0) { - PrintDebug("Slaving VM guest time to host time.\n"); - vm->time_state.flags |= V3_TIME_SLAVE_HOST; - } else { - PrintError("Unknown time source for slaving.\n"); - } - } - if (dilation && (vm->time_state.flags & V3_TIME_SLAVE_HOST)) { - char *str1, *str2; + source = v3_cfg_val(cfg, "source"); + if (source) { + if (strcasecmp(source, "none") == 0) { + vm->time_state.flags &= ~V3_TIME_SLAVE_HOST; + } else if (strcasecmp(source, "host") != 0) { + PrintError("Unknown time source for VM core time management.\n"); + } else { + PrintDebug("VM time slaved to host TSC.\n"); + } + } + + dilation = v3_cfg_val(cfg, "dilation"); + if (dilation) { + if (!(vm->time_state.flags & VM_TIME_SLAVE_HOST)) { + PrintError("Time dilation only valid when slaved to host time.\n"); + } else { uint32_t num = 1, denom = 1; - if ((str1 = v3_cfg_val(dilation, "value"))) { - denom = atoi(str1); - } else if ((str1 = v3_cfg_val(dilation, "num")) - && (str2 = v3_cfg_val(dilation, "denom"))) { - num = atoi(str1); - denom = atoi(str2); - } + denom = atoi(dilation); if ((num > 0) && (denom > 0)) { vm->time_state.td_num = num; vm->time_state.td_denom = denom; } - if ((vm->time_state.td_num != 1) - || (vm->time_state.td_denom != 1)) { - V3_Print("Time dilated from host time by a factor of %d/%d" - " in guest.\n", denom, num); - } else { - PrintError("Time dilation specifier in configuration did not" - " result in actual time dilation in VM.\n"); - } + } + if ((vm->time_state.td_num != 1) + || (vm->time_state.td_denom != 1)) { + V3_Print("Time dilated from host time by a factor of %d/%d" + " in guest.\n", vm->time_state.td_denom, + vm->time_state.td_num); + } else { + PrintError("Time dilation specifier in configuration did not" + " result in actual time dilation in VM.\n"); } } return 0; @@ -397,11 +393,11 @@ void v3_deinit_time_vm(struct v3_vm_info * vm) { static uint32_t gcd ( uint32_t a, uint32_t b ) { - uint32_t c; - while ( a != 0 ) { - c = a; a = b%a; b = c; - } - return b; + uint32_t c; + while ( a != 0 ) { + c = a; a = b%a; b = c; + } + return b; } static int compute_core_ratios(struct guest_info * info, @@ -414,7 +410,7 @@ static int compute_core_ratios(struct guest_info * info, * If the GCD is too small, make it "big enough" */ khzGCD = gcd(hostKhz, guestKhz); if (khzGCD < 1024) - khzGCD = 1000; + khzGCD = 1024; time_state->clock_ratio_num = guestKhz / khzGCD; time_state->clock_ratio_denom = hostKhz / khzGCD; @@ -440,42 +436,43 @@ void v3_init_time_core(struct guest_info * info) { } if ( (khz == NULL) || - (time_state->guest_cpu_freq <= 0) || - (time_state->guest_cpu_freq > time_state->host_cpu_freq) ) { - + (time_state->guest_cpu_freq <= 0)) { +/* || (time_state->guest_cpu_freq > time_state->host_cpu_freq) ) { */ time_state->guest_cpu_freq = time_state->host_cpu_freq; } + compute_core_ratios(info, time_state->host_cpu_freq, + time_state->guest_cpu_freq); + + time_state->flags = 0; + if (info->vm_info->time_state.flags & V3_TIME_SLAVE_HOST) { + time_state->flags |= VM_TIME_SLAVE_HOST; + } + if ((time_state->clock_ratio_denom != 1) || + (time_state->clock_ratio_num != 1)) { + time_state->flags |= VM_TIME_TRAP_RDTSC; + } + PrintDebug("Logical Core %d (vcpu=%d) CPU frequency set to %d KHz (host CPU frequency = %d KHz).\n", info->pcpu_id, info->vcpu_id, time_state->guest_cpu_freq, time_state->host_cpu_freq); - - compute_core_ratios(info, time_state->host_cpu_freq, - time_state->guest_cpu_freq); - PrintDebug(" td_mult = %d/%d, cl_mult = %u/%u, ipc_mult = %u/%u.\n", info->vm_info->time_state.td_num, info->vm_info->time_state.td_denom, time_state->clock_ratio_num, time_state->clock_ratio_denom, time_state->ipc_ratio_num, time_state->ipc_ratio_denom); + PrintDebug(" source = %s, rdtsc trapping = %s\n", + (time_state->flags & VM_TIME_SLAVE_HOST) ? "host" : "none", + (time_state->flags & VM_TIME_TRAP_RDTSC) ? "true" : "false"); + time_state->guest_cycles = 0; time_state->tsc_guest_offset = 0; time_state->last_update = 0; - time_state->initial_host_time = 0; - time_state->flags = 0; - if (info->vm_info->time_state.flags & V3_TIME_SLAVE_HOST) { - time_state->flags |= VM_TIME_SLAVE_HOST; - } - if ((time_state->clock_ratio_denom != 1) || - (time_state->clock_ratio_num != 1)) { - time_state->flags |= VM_TIME_TRAP_RDTSC; - } - INIT_LIST_HEAD(&(time_state->timers)); time_state->num_timers = 0; - + time_state->tsc_aux.lo = 0; time_state->tsc_aux.hi = 0; } @@ -489,5 +486,4 @@ void v3_deinit_time_core(struct guest_info * core) { list_for_each_entry_safe(tmr, tmp, &(time_state->timers), timer_link) { v3_remove_timer(core, tmr); } - }