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=7661832e86ccf6f0595f0a879f97fd6f4ac18f53;hpb=8e158e5f8b789a55de714b6c888270389126c5b6;p=palacios.git diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 7661832..a3a5e5e 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -296,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 @@ -478,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;