* (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.
* 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.
*/
}
}
+/* 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
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;