if (info->cpl != 0) {
v3_raise_exception(info, GPF_EXCEPTION);
} else {
-
- uint64_t yield_start = 0;
- uint64_t yield_stop = 0;
- uint32_t gap = 0;
-
PrintDebug("CPU Yield\n");
-
- rdtscll(yield_start);
- v3_yield(info);
- rdtscll(yield_stop);
-
-
- //v3_update_time(info, yield_stop - yield_start);
- gap = yield_stop - yield_start;
- /* 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_advance_time(info);
+ while (!v3_intr_pending(info)) {
+ /* Since we're in an exit, time is already paused here, so no need to pause again. */
+ v3_yield(info);
+ v3_update_timers(info);
+
+ /* 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 do halt */
+ asm("hlt");
+ }
}
-
-
- PrintDebug("CPU Yield Done (%d cycles)\n", gap);
info->rip += 1;
}