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.


Time configuration parameters added. More time control code prototyped,
Patrick G. Bridges [Fri, 1 Oct 2010 21:36:23 +0000 (15:36 -0600)]
but no robust control in place yet.

Kconfig
palacios/include/palacios/vmm_time.h
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmx.c

diff --git a/Kconfig b/Kconfig
index 1049045..9092a67 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -189,7 +189,6 @@ endmenu
 source "Kconfig.stdlibs"
 
 
-
 menu "Virtual Paging"
 
 config SHADOW_PAGING
@@ -217,6 +216,38 @@ config DEBUG_SHDW_PG_VTLB
 endmenu
 
 
+menu "Time Management"
+
+
+config TIME_VIRTUALIZE_TSC
+       bool "Virtualize guest TSC"
+       default n
+       help
+           Virtualize the processor time stamp counter in the guest, 
+           generally increasing consistency between various time sources 
+           but also potentially making guest time run slightly slower
+           than real time.
+
+config TIME_VIRTUAL_TSC_CONTROL
+       bool "Adjust virtual TSC towards real time when possible"
+       default y
+       depends on TIME_VIRTUALIZE_TSC
+       help 
+           Enables control of TSC virtualization so that the TSC
+           attempts to catch up with real time when possible
+
+config TIME_MASK_OVERHEAD
+       bool "Hide virtualization overhead from guest timing"
+       default n
+       depends on TIME_VIRTUALIZE_TSC
+       help
+           Try to mask the overhead of virtualization from guests
+           by not including it in the time updates. Can dramatically
+           slow virtual time compared to real time if VIRTUAL_TSC_CONTROL
+           is not enabled.
+
+endmenu
+
 menu "Symbiotic Functions"
 
 config SYMBIOTIC
index 3f6bbac..0a25833 100644 (file)
@@ -31,14 +31,10 @@ struct guest_info;
 struct vm_time {
     uint32_t cpu_freq; // in kHZ
 
-    // Last time (in guest time) the timers were updated
-    uint64_t last_update;
-    
-    // Cache value to help calculate the guest_tsc
-    uint64_t pause_time;
-
-    // Offset of guest time from host time.
-    sint64_t host_offset;
+    uint64_t last_update;  // Last time (in guest time) the timers were updated
+    uint64_t pause_time;   // Cache value to help calculate the guest_tsc
+    sint64_t host_offset;  // Offset of guest time from host time.
+    sint64_t offset_sum;   // Sum of past and current host_offsets
 
     // Installed Timers 
     uint_t num_timers;
@@ -80,7 +76,8 @@ static inline uint64_t v3_get_host_time(struct vm_time *t) {
 }
 
 static inline uint64_t v3_get_guest_time(struct vm_time *t) {
-    return v3_get_host_time(t) + t->host_offset;
+    if (t->pause_time) return t->pause_time;
+    else return v3_get_host_time(t) + t->host_offset;
 }
 #endif // !__V3VEE__
 
index 55e591e..dc2b660 100644 (file)
@@ -471,14 +471,17 @@ int v3_svm_enter(struct guest_info * info) {
 
     v3_update_timers(info);
     v3_resume_time(info);
+
+#ifdef CONFIG_TIME_TSC_OFFSET
     guest_ctrl->TSC_OFFSET = info->time_state.host_offset;
+#endif
 
     //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_pause_time(info);
-#ifdef OPTION_TIME_MASK_OVERHEAD
+#ifdef CONFIG_TIME_MASK_OVERHEAD
     v3_offset_time(info, -SVM_ENTRY_OVERHEAD);
 #endif
 
index 7814acb..e7d5cfe 100644 (file)
@@ -47,7 +47,8 @@ void v3_init_time(struct guest_info * info) {
     time_state->pause_time = 0;
     time_state->last_update = 0;
     time_state->host_offset = 0;
-    
+    time_state->offset_sum = 0;
+
     INIT_LIST_HEAD(&(time_state->timers));
     time_state->num_timers = 0;
 
@@ -73,14 +74,43 @@ int v3_pause_time(struct guest_info * info) {
     return 0;
 }
 
+/* Use a control-theoretic approach, specifically a PI control approach,
+ * to adjust host_offset towards 0. Overall control documentation in 
+ * palacios/docs/time_control.tex Control parameters are P and I, 
+ * broken into rational numbers
+ */
+
+/* These numbers need to be actually determined by pole placement work. They're 
+ * just blind guesses for now, which is a really bad idea. :) */
+#define P_NUM 1
+#define P_DENOM 2
+#define I_NUM 1
+#define I_DENOM 20
+
+void adjust_time_offset(struct guest_info * info) {
+    /* Set point for control: Desired offset = 0; 
+     * Error = host_offset - 0 = host_offset */
+
+    sint64_t adjust;
+
+    /* Update the integral of the errror */
+    info->time_state.offset_sum += info->time_state.host_offset;
+    adjust = (P_NUM * info->time_state.host_offset) / P_DENOM +
+       (I_NUM * info->time_state.offset_sum) / I_DENOM;
+
+    /* We may want to constrain *adjust* because of
+     * resolution/accuracy constraints. Explore that later. */
+    info->time_state.host_offset -= adjust;
+    return;
+}
+
 int v3_resume_time(struct guest_info * info) {
     uint64_t t = v3_get_host_time(&info->time_state);
     V3_ASSERT(info->time_state.pause_time != 0);
     info->time_state.host_offset = 
        (sint64_t)info->time_state.pause_time - (sint64_t)t;
 #ifdef CONFIG_TIME_TSC_OFFSET_ADJUST
-    /* XXX Adjust host_offset towards zero based on resolution/accuracy
-     * constraints. */
+    adjust_time_offset(info);
 #endif
     info->time_state.pause_time = 0;
     PrintDebug("Time resumed paused at guest time as %llu "
index 9a2e859..16fc5cd 100644 (file)
@@ -225,6 +225,9 @@ static int init_vmcs_bios(struct guest_info * info, struct vmx_data * vmx_state)
     vmx_state->pri_proc_ctrls.invlpg_exit = 1;
     vmx_state->pri_proc_ctrls.use_msr_bitmap = 1;
     vmx_state->pri_proc_ctrls.pause_exit = 1;
+#ifdef CONFIG_TIME_TSC_OFFSET
+    vmx_state->pri_proc_ctrls.tsc_offset = 1;
+#endif
 
     vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_A_ADDR, (addr_t)V3_PAddr(info->vm_info->io_map.arch_data));
     vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_B_ADDR, 
@@ -696,7 +699,7 @@ int v3_vmx_enter(struct guest_info * info) {
     }
 
     v3_pause_time(info);
-#ifdef OPTION_TIME_MASK_OVERHEAD
+#ifdef CONFIG_TIME_MASK_OVERHEAD
     v3_offset_time(info, -VMX_ENTRY_OVERHEAD);
 #endif