From: Lei Xia Date: Fri, 23 Apr 2010 18:12:07 +0000 (-0500) Subject: Fix to the HLT exit handler X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=46113012016d5064ca8617dbb39f04c9763fd911;p=palacios.git Fix to the HLT exit handler --- diff --git a/palacios/include/palacios/vmm_time.h b/palacios/include/palacios/vmm_time.h index ff4946a..d805db9 100644 --- a/palacios/include/palacios/vmm_time.h +++ b/palacios/include/palacios/vmm_time.h @@ -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; diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 6de0781..b6bd770 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -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; diff --git a/palacios/src/palacios/vmm_halt.c b/palacios/src/palacios/vmm_halt.c index 056d568..bb28ebc 100644 --- a/palacios/src/palacios/vmm_halt.c +++ b/palacios/src/palacios/vmm_halt.c @@ -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); diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 253ae47..3334d2f 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -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) {