X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_time.c;h=a3a5e5eb94441b1b99c1fca2ff54eb42c5e44ecf;hb=457220e0485aefc6efecbc81ab1343b9cb65d8ba;hp=2295b3fc90d8ac340ba93eef6dfbbacb10681bf0;hpb=8a3dbb70c29175bad79764a0b2f3961b98138bb2;p=palacios.git diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 2295b3f..a3a5e5e 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -58,7 +58,7 @@ * (1) Add support for temporarily skewing guest time off of where it should * be to support slack simulation of guests. The idea is that simulators * set this skew to be the difference between how much time passed for a - * simulated feature and a real implementation of that feature, making + * simulated feature and a real implementation of that feature, making time * pass at a different rate from real time on this core. The VMM will then * attempt to move this skew back towards 0 subject to resolution/accuracy * constraints from various system timers. @@ -66,6 +66,12 @@ * The main effort in doing this will be to get accuracy/resolution * information from each local timer and to use this to bound how much skew * is removed on each exit. + * + * (2) Look more into sychronizing the offsets *across* virtual and physical + * cores so that multicore guests stay mostly in sync. + * + * (3) Look into using the AMD TSC multiplier feature and adding explicit time + * dilation support to time handling. */ @@ -290,6 +296,52 @@ void v3_update_timers(struct guest_info * info) { } } +/* Handle TSC timeout hooks */ +struct v3_timeout_hook * +v3_add_timeout_hook(struct guest_info * info, v3_timeout_callback_t callback, + void * priv_data) { + struct v3_timeout_hook * timeout = NULL; + timeout = (struct v3_timeout_hook *)V3_Malloc(sizeof(struct v3_timeout_hook)); + V3_ASSERT(timeout != NULL); + + timeout->callback = callback; + timeout->private_data = priv_data; + + list_add(&(timeout->hook_link), &(info->time_state.timeout_hooks)); + return timeout; +} + +int +v3_remove_timeout_hook(struct guest_info * info, struct v3_timeout_hook * hook) { + list_del(&(hook->hook_link)); + V3_Free(hook); + return 0; +} + +int v3_schedule_timeout(struct guest_info * info, ullong_t guest_timeout) { + struct vm_time *time_state = &info->time_state; + /* Note that virtualization architectures that support it (like newer + * VMX systems) will turn on an active preemption timeout if + * available to get this timeout as closely as possible. Other systems + * only catch it in the periodic interrupt and so are less precise */ + if (guest_timeout < time_state->next_timeout) { + time_state->next_timeout = guest_timeout; + } + return 0; +} + +int v3_check_timeout( struct guest_info * info ) { + struct vm_time *time_state = &info->time_state; + if (time_state->next_timeout <= v3_get_guest_time(time_state)) { + struct v3_timeout_hook * tmp_timeout; + time_state->next_timeout = (ullong_t)-1; + list_for_each_entry(tmp_timeout, &(time_state->timeout_hooks), hook_link) { + tmp_timeout->callback(info, tmp_timeout->private_data); + } + } + return 0; +} + /* * Handle full virtualization of the time stamp counter. As noted * above, we don't store the actual value of the TSC, only the guest's @@ -472,6 +524,9 @@ void v3_init_time_core(struct guest_info * info) { time_state->guest_host_offset = 0; time_state->tsc_guest_offset = 0; + INIT_LIST_HEAD(&(time_state->timeout_hooks)); + time_state->next_timeout = (ullong_t)-1; + INIT_LIST_HEAD(&(time_state->timers)); time_state->num_timers = 0;