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.


Fix to the HLT exit handler
Lei Xia [Fri, 23 Apr 2010 18:12:07 +0000 (13:12 -0500)]
palacios/include/palacios/vmm_time.h
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_halt.c
palacios/src/palacios/vmx.c

index ff4946a..d805db9 100644 (file)
@@ -36,6 +36,13 @@ struct vm_time {
     // Cache value to help calculate the guest_tsc
     ullong_t cached_host_tsc;
 
+       
+    /* The total num of numcycles spent in the halt handler 
+         that the halt handler has already updated to the 
+         timer infrastructure about.   That is, "update_time" has been
+     */
+    ullong_t cached_hlt_tsc;
+
     // The number of cycles pending for notification to the timers
     //ullong_t pending_cycles;
 
index 6de0781..b6bd770 100644 (file)
@@ -468,7 +468,8 @@ int v3_svm_enter(struct guest_info * info) {
 
 
     rdtscll(tmp_tsc);
-    v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
+    v3_update_time(info, (tmp_tsc - info->time_state.cached_host_tsc - info->time_state.cached_hlt_tsc));
+    info->time_state.cached_hlt_tsc = 0;
     rdtscll(info->time_state.cached_host_tsc);
     //    guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
 
index 056d568..bb28ebc 100644 (file)
@@ -44,6 +44,8 @@ int v3_handle_halt(struct guest_info * info) {
        uint32_t gap = 0;
        
        PrintDebug("CPU Yield\n");
+
+again:
        
        rdtscll(yield_start);
        v3_yield(info);
@@ -52,7 +54,26 @@ int v3_handle_halt(struct guest_info * info) {
     
        //v3_update_time(info, yield_stop - yield_start);
        gap = yield_stop - yield_start;
+        /*
+           If we got here, either an interrupt has occured or
+           sufficient time has passed that we may need to inject 
+           a timer interrupt.  
+           First, we will update time, which may or may not inject an
+           interrupt 
+        */
+       v3_update_time(info, gap);
+       info->time_state.cached_hlt_tsc += gap;
 
+       /* At this point, we either have some combination of 
+           interrupts, including perhaps a timer interrupt, or 
+           no interrupt.
+        */
+       if (!v3_intr_pending(info)) {
+       /* if no interrupt, then we yield again */
+           goto again;
+       }
+
+#if 0
        /*  WARNING!!! WARNING!!!
         *  
         * DO NOT REMOVE THIS CONDITIONAL!!!
@@ -65,7 +86,9 @@ int v3_handle_halt(struct guest_info * info) {
        if (!v3_intr_pending(info)) {
            v3_advance_time(info);
        }
+#endif
 
+      //PrintError("HLT instruction issued\n");
        
        PrintDebug("CPU Yield Done (%d cycles)\n", gap);
        
index 253ae47..3334d2f 100644 (file)
@@ -660,7 +660,8 @@ int v3_vmx_enter(struct guest_info * info) {
 
     // We do timer injection here to track real host time.
     rdtscll(tmp_tsc);
-    v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
+    v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc - info->time_state.cached_hlt_tsc);
+    info->time_state.cached_hlt_tsc = 0;
     rdtscll(info->time_state.cached_host_tsc);
 
     if (info->vm_info->run_state == VM_STOPPED) {