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.


More minor fixes on time keeping. VMM clock now appears to be essentially accurate...
Patrick G. Bridges [Thu, 21 Oct 2010 17:22:21 +0000 (11:22 -0600)]
palacios/include/palacios/vmm_time.h
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmx.c

index 4364358..74c7584 100644 (file)
@@ -48,9 +48,6 @@ struct vm_time {
     struct list_head timers;
 };
 
-
-
-
 struct vm_timer_ops {
     void (*update_timer)(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
     void (*advance_timer)(struct guest_info * info, void * private_data);
@@ -63,19 +60,17 @@ struct vm_timer {
     struct list_head timer_link;
 };
 
+// Basic functions for handling passage of time in palacios
+void v3_init_time(struct guest_info * info);
+int v3_start_time(struct guest_info * info);
+int v3_adjust_time(struct guest_info * info);
 
-
-
+// Basic functions for attaching timers to the passage of time
 int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data);
 int v3_remove_timer(struct guest_info * info, struct vm_timer * timer);
 void v3_update_timers(struct guest_info * info);
 
-
-void v3_init_time(struct guest_info * info);
-int v3_start_time(struct guest_info * info);
-int v3_adjust_time(struct guest_info * info);
-
-// Returns host time
+// Functions to return the different notions of time in Palacios.
 static inline uint64_t v3_get_host_time(struct vm_time *t) {
     uint64_t tmp;
     rdtscll(tmp);
@@ -97,13 +92,17 @@ static inline sint64_t v3_tsc_host_offset(struct vm_time *time_state) {
     return time_state->guest_host_offset + time_state->tsc_guest_offset;
 }
 
-
+// Functions for handling exits on the TSC when fully virtualizing 
+// the timestamp counter.
 #define TSC_MSR     0x10
 #define TSC_AUX_MSR 0xC0000103
 
 int v3_handle_rdtscp(struct guest_info *info);
 int v3_handle_rdtsc(struct guest_info *info);
 
+
+
+
 #endif // !__V3VEE__
 
 #endif
index 3ac98d4..35f2047 100644 (file)
@@ -480,14 +480,16 @@ int v3_svm_enter(struct guest_info * info) {
 
     v3_update_timers(info);
 
+    /* If this guest is frequency-lagged behind host time, wait 
+     * for the appropriate host time before resuming the guest. */
+    v3_adjust_time(info);
+
     guest_ctrl->TSC_OFFSET = v3_tsc_host_offset(&info->time_state);
 
     //V3_Print("Calling v3_svm_launch\n");
 
     v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]);
 
-    v3_adjust_time(info);
-
     //V3_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip);
 
     v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
index b04a266..44affe4 100644 (file)
  * the passage of time:
  * (1) The host timestamp counter - read directly from HW and never written
  * (2) A monotonic guest timestamp counter used to measure the progression of
- *     time in the guest. This is computed as a multipler/offset from (1) above
+ *     time in the guest. This is computed using an offsets from (1) above.
  * (3) The actual guest timestamp counter (which can be written by
  *     writing to the guest TSC MSR - MSR 0x10) from the monotonic guest TSC.
  *     This is also computed as an offset from (2) above when the TSC and
  *     this offset is updated when the TSC MSR is written.
  *
+ * The value used to offset the guest TSC from the host TSC is the *sum* of all
+ * of these offsets (2 and 3) above
+ * 
  * Because all other devices are slaved off of the passage of time in the guest,
  * it is (2) above that drives the firing of other timers in the guest, 
  * including timer devices such as the Programmable Interrupt Timer (PIT).
  *
- *  
- *
+ * Future additions:
+ * (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 
+ *     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.
  */
 
 
@@ -89,20 +102,22 @@ int v3_adjust_time(struct guest_info * info) {
     } else {
        uint64_t guest_time, guest_elapsed, desired_elapsed;
        uint64_t host_time, target_host_time;
+
        guest_time = v3_get_guest_time(time_state);
+
+       /* Compute what host time this guest time should correspond to. */
        guest_elapsed = (guest_time - time_state->initial_time);
        desired_elapsed = (guest_elapsed * time_state->host_cpu_freq) / time_state->guest_cpu_freq;
-
        target_host_time = time_state->initial_time + desired_elapsed;
-       host_time = v3_get_host_time(time_state);
 
+       /* Yield until that host time is reached */
+       host_time = v3_get_host_time(time_state);
        while (host_time < target_host_time) {
            v3_yield(info);
            host_time = v3_get_host_time(time_state);
        }
 
-       time_state->guest_host_offset = guest_time - host_time;
-
+       time_state->guest_host_offset = (sint64_t)guest_time - (sint64_t)host_time;
     }
     return 0;
 }
@@ -306,3 +321,6 @@ void v3_init_time(struct guest_info * info) {
 
 
 
+
+
+
index beb2437..332e6ad 100644 (file)
@@ -670,6 +670,10 @@ int v3_vmx_enter(struct guest_info * info) {
 
     v3_update_timers(info);
 
+    /* If this guest is frequency-lagged behind host time, wait 
+     * for the appropriate host time before resuming the guest. */
+    v3_adjust_time(info);
+
     tsc_offset_high = (uint32_t)((v3_tsc_host_offset(&info->time_state) >> 32) & 0xffffffff);
     tsc_offset_low = (uint32_t)(v3_tsc_host_offset(&info->time_state) & 0xffffffff);
     check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high);
@@ -695,10 +699,6 @@ int v3_vmx_enter(struct guest_info * info) {
        return -1;
     }
 
-    /* If this guest is frequency-lagged behind host time, wait 
-     * for the appropriate host time. */
-    v3_adjust_time(info);
-
     info->num_exits++;
 
     /* Update guest state */