Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


bug fixes for VMX
[palacios.git] / palacios / src / palacios / vmm_time.c
index 2295b3f..a3a5e5e 100644 (file)
@@ -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.
  *     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;