// 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;
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;
uint32_t gap = 0;
PrintDebug("CPU Yield\n");
+
+again:
rdtscll(yield_start);
v3_yield(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!!!
if (!v3_intr_pending(info)) {
v3_advance_time(info);
}
+#endif
+ //PrintError("HLT instruction issued\n");
PrintDebug("CPU Yield Done (%d cycles)\n", gap);
// 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) {