*/
// disable global interrupts for vm state transition
-
v3_clgi();
// reenable global interrupts after vm exit
v3_stgi();
+
+ // Conditionally yield the CPU if the timeslice has expired
+ v3_yield_cond(info);
+
+
v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
num_exits++;
}
}
-
- // Conditionally yield the CPU if the timeslice has expired
- v3_yield_cond(info);
-
if (v3_handle_svm_exit(info) != 0) {
vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
addr_t host_addr;
//
-// This should trigger a #GP if cpl!=0, otherwise, yield to host
+// This should trigger a #GP if cpl != 0, otherwise, yield to host
//
int v3_handle_svm_halt(struct guest_info * info) {
v3_raise_exception(info, GPF_EXCEPTION);
} else {
- ullong_t yield_start = 0;
- ullong_t yield_stop = 0;
+ uint64_t yield_start = 0;
+ uint64_t yield_stop = 0;
uint32_t gap = 0;
PrintDebug("CPU Yield\n");
//v3_update_time(info, yield_stop - yield_start);
gap = yield_stop - yield_start;
- v3_raise_irq(info, 0);
+ /* WARNING!!! WARNING!!!
+ *
+ * DO NOT REMOVE THIS CONDITIONAL!!!
+ *
+ * It is common for an OS to issue an IO op, and then sit in a halt loop
+ * waiting for the device to complete and raise an irq.
+ * If you remove this then the timer interrupt will ALWAYS subvert the completion
+ * interrupt and stall the guest.
+ */
+ if (!v3_intr_pending(info)) {
+ v3_raise_irq(info, 0);
+ }
PrintDebug("CPU Yield Done (%d cycles)\n", gap);