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.


Initial testing of new time handling on VMX, initial implementation of new
Patrick G. Bridges [Mon, 20 Sep 2010 21:56:03 +0000 (15:56 -0600)]
time handling on SVM.

Kconfig
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_handler.c

diff --git a/Kconfig b/Kconfig
index 0e87296..1049045 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -324,7 +324,12 @@ config DEBUG_INTERRUPTS
        help 
          This turns on debugging for the interrupt system
 
-
+config DEBUG_TIME
+       bool "Timing"
+       default n
+       depends on DEBUG_ON
+       help
+         This turns on debugging of system time virtualization
 
 config DEBUG_IO
        bool "IO"
index 3131cf2..55e591e 100644 (file)
@@ -416,7 +416,6 @@ static int update_irq_entry_state(struct guest_info * info) {
 int v3_svm_enter(struct guest_info * info) {
     vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); 
-    ullong_t tmp_tsc;
     addr_t exit_code = 0, exit_info1 = 0, exit_info2 = 0;
 
     // Conditionally yield the CPU if the timeslice has expired
@@ -470,31 +469,27 @@ int v3_svm_enter(struct guest_info * info) {
 #endif
 
 
-    rdtscll(tmp_tsc);
-    v3_update_timers(info, (tmp_tsc - info->time_state.cached_host_tsc));
-    rdtscll(info->time_state.cached_host_tsc);
-    //    guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+    v3_update_timers(info);
+    v3_resume_time(info);
+    guest_ctrl->TSC_OFFSET = info->time_state.host_offset;
 
     //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_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip);
 
+    v3_pause_time(info);
+#ifdef OPTION_TIME_MASK_OVERHEAD
+    v3_offset_time(info, -SVM_ENTRY_OVERHEAD);
+#endif
 
-    v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
+    //V3_Print("SVM Returned: Exit Code: %x, guest_rip=%lx\n", (uint32_t)(guest_ctrl->exit_code), (unsigned long)guest_state->rip);
 
-    //rdtscll(tmp_tsc);
-    //    v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
+    v3_last_exit = (uint32_t)(guest_ctrl->exit_code);
 
     //PrintDebug("SVM Returned\n");
     
     info->num_exits++;
 
-
-
-
     // Save Guest state from VMCB
     info->rip = guest_state->rip;
     info->vm_regs.rsp = guest_state->rsp;
@@ -590,8 +585,7 @@ int v3_start_svm_guest(struct guest_info *info) {
     //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
     
     info->vm_info->run_state = VM_RUNNING;
-    rdtscll(info->yield_start_cycle);
-
+    v3_start_time(info);
 
     while (1) {
        if (v3_svm_enter(info) == -1) {
index 4bd30ef..3604bc2 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vm_guest.h>
 
+#ifndef CONFIG_DEBUG_TIME
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
 static int handle_cpufreq_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) {
     struct vm_time * time_state = &(info->time_state);
 
@@ -62,6 +67,8 @@ uint64_t v3_get_guest_time(struct guest_info * info) {
 int v3_start_time(struct guest_info * info) {
     /* We start running with guest_time == host_time */
     uint64_t t = v3_get_host_time(info); 
+
+    PrintDebug("Starting initial guest time as %llu\n", t);
     info->time_state.last_update = t;
     info->time_state.pause_time = t;
     return 0;
@@ -70,17 +77,24 @@ int v3_start_time(struct guest_info * info) {
 int v3_pause_time(struct guest_info * info) {
     V3_ASSERT(info->time_state.pause_time == 0);
     info->time_state.pause_time = v3_get_guest_time(info);
+    PrintDebug("Time paused at guest time as %llu\n", 
+              info->time_state.pause_time);
     return 0;
 }
 
 int v3_resume_time(struct guest_info * info) {
     uint64_t t = v3_get_host_time(info);
     V3_ASSERT(info->time_state.pause_time != 0);
-#ifdef OPTION_TIME_ADJUST_TSC_OFFSET
-#endif
     info->time_state.host_offset = 
        (sint64_t)info->time_state.pause_time - (sint64_t)t;
+#ifdef OPTION_TIME_ADJUST_TSC_OFFSET
+    /* XXX Adjust host_offset towards zero based on resolution/accuracy
+     * constraints. */
+#endif
     info->time_state.pause_time = 0;
+    PrintDebug("Time resumed paused at guest time as %llu "
+              "offset %lld from host time.\n", t, info->time_state.host_offset);
+
     return 0;
 }
 
index a297be2..bb93054 100644 (file)
@@ -672,7 +672,8 @@ int v3_vmx_enter(struct guest_info * info) {
     tsc_offset_low = (uint32_t)(info->time_state.host_offset & 0xffffffff);
     check_vmcs_write(VMCS_TSC_OFFSET_HIGH, tsc_offset_high);
     check_vmcs_write(VMCS_TSC_OFFSET, tsc_offset_low);
-                    
+    PrintDebug("Stored 0x %x %x into vmcs TSC offset.\n", 
+              tsc_offset_high, tsc_offset_low);
     if (info->vm_info->run_state == VM_STOPPED) {
        info->vm_info->run_state = VM_RUNNING;
        ret = v3_vmx_launch(&(info->vm_regs), info, &(info->ctrl_regs));
index d88210d..9d29f9f 100644 (file)
@@ -99,6 +99,17 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf
             }
 
             break;
+
+#if 0
+        case VMEXIT_RDTSC:
+           if (v3_handle_rdtsc(info) == -1) {
+               PrintError("Error Handling RDTSC instruction\n");
+               return -1;
+           }
+           
+           break;
+#endif
+
         case VMEXIT_CPUID:
            if (v3_handle_cpuid(info) == -1) {
                PrintError("Error Handling CPUID instruction\n");