1740b1759SClaudio Fontana /* 2740b1759SClaudio Fontana * QEMU System Emulator 3740b1759SClaudio Fontana * 4740b1759SClaudio Fontana * Copyright (c) 2003-2008 Fabrice Bellard 5740b1759SClaudio Fontana * 6740b1759SClaudio Fontana * Permission is hereby granted, free of charge, to any person obtaining a copy 7740b1759SClaudio Fontana * of this software and associated documentation files (the "Software"), to deal 8740b1759SClaudio Fontana * in the Software without restriction, including without limitation the rights 9740b1759SClaudio Fontana * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10740b1759SClaudio Fontana * copies of the Software, and to permit persons to whom the Software is 11740b1759SClaudio Fontana * furnished to do so, subject to the following conditions: 12740b1759SClaudio Fontana * 13740b1759SClaudio Fontana * The above copyright notice and this permission notice shall be included in 14740b1759SClaudio Fontana * all copies or substantial portions of the Software. 15740b1759SClaudio Fontana * 16740b1759SClaudio Fontana * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17740b1759SClaudio Fontana * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18740b1759SClaudio Fontana * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19740b1759SClaudio Fontana * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20740b1759SClaudio Fontana * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21740b1759SClaudio Fontana * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22740b1759SClaudio Fontana * THE SOFTWARE. 23740b1759SClaudio Fontana */ 24740b1759SClaudio Fontana 25740b1759SClaudio Fontana #include "qemu/osdep.h" 26740b1759SClaudio Fontana #include "qemu/cutils.h" 27740b1759SClaudio Fontana #include "migration/vmstate.h" 28740b1759SClaudio Fontana #include "qapi/error.h" 29740b1759SClaudio Fontana #include "qemu/error-report.h" 30740b1759SClaudio Fontana #include "exec/exec-all.h" 31740b1759SClaudio Fontana #include "sysemu/cpus.h" 32740b1759SClaudio Fontana #include "sysemu/qtest.h" 33740b1759SClaudio Fontana #include "qemu/main-loop.h" 34740b1759SClaudio Fontana #include "qemu/option.h" 35740b1759SClaudio Fontana #include "qemu/seqlock.h" 36740b1759SClaudio Fontana #include "sysemu/replay.h" 37740b1759SClaudio Fontana #include "sysemu/runstate.h" 38740b1759SClaudio Fontana #include "hw/core/cpu.h" 39740b1759SClaudio Fontana #include "sysemu/cpu-timers.h" 40740b1759SClaudio Fontana #include "sysemu/cpu-throttle.h" 41740b1759SClaudio Fontana #include "timers-state.h" 42740b1759SClaudio Fontana 43740b1759SClaudio Fontana /* 44740b1759SClaudio Fontana * ICOUNT: Instruction Counter 45740b1759SClaudio Fontana * 46740b1759SClaudio Fontana * this module is split off from cpu-timers because the icount part 47740b1759SClaudio Fontana * is TCG-specific, and does not need to be built for other accels. 48740b1759SClaudio Fontana */ 49740b1759SClaudio Fontana static bool icount_sleep = true; 50740b1759SClaudio Fontana /* Arbitrarily pick 1MIPS as the minimum allowable speed. */ 51740b1759SClaudio Fontana #define MAX_ICOUNT_SHIFT 10 52740b1759SClaudio Fontana 53740b1759SClaudio Fontana /* 54740b1759SClaudio Fontana * 0 = Do not count executed instructions. 55740b1759SClaudio Fontana * 1 = Fixed conversion of insn to ns via "shift" option 56740b1759SClaudio Fontana * 2 = Runtime adaptive algorithm to compute shift 57740b1759SClaudio Fontana */ 58740b1759SClaudio Fontana int use_icount; 59740b1759SClaudio Fontana 60740b1759SClaudio Fontana static void icount_enable_precise(void) 61740b1759SClaudio Fontana { 62740b1759SClaudio Fontana use_icount = 1; 63740b1759SClaudio Fontana } 64740b1759SClaudio Fontana 65740b1759SClaudio Fontana static void icount_enable_adaptive(void) 66740b1759SClaudio Fontana { 67740b1759SClaudio Fontana use_icount = 2; 68740b1759SClaudio Fontana } 69740b1759SClaudio Fontana 70740b1759SClaudio Fontana /* 71740b1759SClaudio Fontana * The current number of executed instructions is based on what we 72740b1759SClaudio Fontana * originally budgeted minus the current state of the decrementing 73740b1759SClaudio Fontana * icount counters in extra/u16.low. 74740b1759SClaudio Fontana */ 758191d368SClaudio Fontana static int64_t icount_get_executed(CPUState *cpu) 76740b1759SClaudio Fontana { 77740b1759SClaudio Fontana return (cpu->icount_budget - 78740b1759SClaudio Fontana (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra)); 79740b1759SClaudio Fontana } 80740b1759SClaudio Fontana 81740b1759SClaudio Fontana /* 82740b1759SClaudio Fontana * Update the global shared timer_state.qemu_icount to take into 83740b1759SClaudio Fontana * account executed instructions. This is done by the TCG vCPU 84740b1759SClaudio Fontana * thread so the main-loop can see time has moved forward. 85740b1759SClaudio Fontana */ 868191d368SClaudio Fontana static void icount_update_locked(CPUState *cpu) 87740b1759SClaudio Fontana { 888191d368SClaudio Fontana int64_t executed = icount_get_executed(cpu); 89740b1759SClaudio Fontana cpu->icount_budget -= executed; 90740b1759SClaudio Fontana 91740b1759SClaudio Fontana qatomic_set_i64(&timers_state.qemu_icount, 92740b1759SClaudio Fontana timers_state.qemu_icount + executed); 93740b1759SClaudio Fontana } 94740b1759SClaudio Fontana 95740b1759SClaudio Fontana /* 96740b1759SClaudio Fontana * Update the global shared timer_state.qemu_icount to take into 97740b1759SClaudio Fontana * account executed instructions. This is done by the TCG vCPU 98740b1759SClaudio Fontana * thread so the main-loop can see time has moved forward. 99740b1759SClaudio Fontana */ 1008191d368SClaudio Fontana void icount_update(CPUState *cpu) 101740b1759SClaudio Fontana { 102740b1759SClaudio Fontana seqlock_write_lock(&timers_state.vm_clock_seqlock, 103740b1759SClaudio Fontana &timers_state.vm_clock_lock); 1048191d368SClaudio Fontana icount_update_locked(cpu); 105740b1759SClaudio Fontana seqlock_write_unlock(&timers_state.vm_clock_seqlock, 106740b1759SClaudio Fontana &timers_state.vm_clock_lock); 107740b1759SClaudio Fontana } 108740b1759SClaudio Fontana 1098191d368SClaudio Fontana static int64_t icount_get_raw_locked(void) 110740b1759SClaudio Fontana { 111740b1759SClaudio Fontana CPUState *cpu = current_cpu; 112740b1759SClaudio Fontana 113740b1759SClaudio Fontana if (cpu && cpu->running) { 114740b1759SClaudio Fontana if (!cpu->can_do_io) { 115740b1759SClaudio Fontana error_report("Bad icount read"); 116740b1759SClaudio Fontana exit(1); 117740b1759SClaudio Fontana } 118740b1759SClaudio Fontana /* Take into account what has run */ 1198191d368SClaudio Fontana icount_update_locked(cpu); 120740b1759SClaudio Fontana } 121740b1759SClaudio Fontana /* The read is protected by the seqlock, but needs atomic64 to avoid UB */ 122740b1759SClaudio Fontana return qatomic_read_i64(&timers_state.qemu_icount); 123740b1759SClaudio Fontana } 124740b1759SClaudio Fontana 1258191d368SClaudio Fontana static int64_t icount_get_locked(void) 126740b1759SClaudio Fontana { 1278191d368SClaudio Fontana int64_t icount = icount_get_raw_locked(); 128740b1759SClaudio Fontana return qatomic_read_i64(&timers_state.qemu_icount_bias) + 1298191d368SClaudio Fontana icount_to_ns(icount); 130740b1759SClaudio Fontana } 131740b1759SClaudio Fontana 1328191d368SClaudio Fontana int64_t icount_get_raw(void) 133740b1759SClaudio Fontana { 134740b1759SClaudio Fontana int64_t icount; 135740b1759SClaudio Fontana unsigned start; 136740b1759SClaudio Fontana 137740b1759SClaudio Fontana do { 138740b1759SClaudio Fontana start = seqlock_read_begin(&timers_state.vm_clock_seqlock); 1398191d368SClaudio Fontana icount = icount_get_raw_locked(); 140740b1759SClaudio Fontana } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); 141740b1759SClaudio Fontana 142740b1759SClaudio Fontana return icount; 143740b1759SClaudio Fontana } 144740b1759SClaudio Fontana 145740b1759SClaudio Fontana /* Return the virtual CPU time, based on the instruction counter. */ 1468191d368SClaudio Fontana int64_t icount_get(void) 147740b1759SClaudio Fontana { 148740b1759SClaudio Fontana int64_t icount; 149740b1759SClaudio Fontana unsigned start; 150740b1759SClaudio Fontana 151740b1759SClaudio Fontana do { 152740b1759SClaudio Fontana start = seqlock_read_begin(&timers_state.vm_clock_seqlock); 1538191d368SClaudio Fontana icount = icount_get_locked(); 154740b1759SClaudio Fontana } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); 155740b1759SClaudio Fontana 156740b1759SClaudio Fontana return icount; 157740b1759SClaudio Fontana } 158740b1759SClaudio Fontana 1598191d368SClaudio Fontana int64_t icount_to_ns(int64_t icount) 160740b1759SClaudio Fontana { 161740b1759SClaudio Fontana return icount << qatomic_read(&timers_state.icount_time_shift); 162740b1759SClaudio Fontana } 163740b1759SClaudio Fontana 164740b1759SClaudio Fontana /* 165740b1759SClaudio Fontana * Correlation between real and virtual time is always going to be 166740b1759SClaudio Fontana * fairly approximate, so ignore small variation. 167740b1759SClaudio Fontana * When the guest is idle real and virtual time will be aligned in 168740b1759SClaudio Fontana * the IO wait loop. 169740b1759SClaudio Fontana */ 170740b1759SClaudio Fontana #define ICOUNT_WOBBLE (NANOSECONDS_PER_SECOND / 10) 171740b1759SClaudio Fontana 172740b1759SClaudio Fontana static void icount_adjust(void) 173740b1759SClaudio Fontana { 174740b1759SClaudio Fontana int64_t cur_time; 175740b1759SClaudio Fontana int64_t cur_icount; 176740b1759SClaudio Fontana int64_t delta; 177740b1759SClaudio Fontana 178740b1759SClaudio Fontana /* If the VM is not running, then do nothing. */ 179740b1759SClaudio Fontana if (!runstate_is_running()) { 180740b1759SClaudio Fontana return; 181740b1759SClaudio Fontana } 182740b1759SClaudio Fontana 183740b1759SClaudio Fontana seqlock_write_lock(&timers_state.vm_clock_seqlock, 184740b1759SClaudio Fontana &timers_state.vm_clock_lock); 185740b1759SClaudio Fontana cur_time = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, 186740b1759SClaudio Fontana cpu_get_clock_locked()); 1878191d368SClaudio Fontana cur_icount = icount_get_locked(); 188740b1759SClaudio Fontana 189740b1759SClaudio Fontana delta = cur_icount - cur_time; 190740b1759SClaudio Fontana /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ 191740b1759SClaudio Fontana if (delta > 0 192fe852ac2SPavel Dovgalyuk && timers_state.last_delta + ICOUNT_WOBBLE < delta * 2 193740b1759SClaudio Fontana && timers_state.icount_time_shift > 0) { 194740b1759SClaudio Fontana /* The guest is getting too far ahead. Slow time down. */ 195740b1759SClaudio Fontana qatomic_set(&timers_state.icount_time_shift, 196740b1759SClaudio Fontana timers_state.icount_time_shift - 1); 197740b1759SClaudio Fontana } 198740b1759SClaudio Fontana if (delta < 0 199fe852ac2SPavel Dovgalyuk && timers_state.last_delta - ICOUNT_WOBBLE > delta * 2 200740b1759SClaudio Fontana && timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) { 201740b1759SClaudio Fontana /* The guest is getting too far behind. Speed time up. */ 202740b1759SClaudio Fontana qatomic_set(&timers_state.icount_time_shift, 203740b1759SClaudio Fontana timers_state.icount_time_shift + 1); 204740b1759SClaudio Fontana } 205fe852ac2SPavel Dovgalyuk timers_state.last_delta = delta; 206740b1759SClaudio Fontana qatomic_set_i64(&timers_state.qemu_icount_bias, 207740b1759SClaudio Fontana cur_icount - (timers_state.qemu_icount 208740b1759SClaudio Fontana << timers_state.icount_time_shift)); 209740b1759SClaudio Fontana seqlock_write_unlock(&timers_state.vm_clock_seqlock, 210740b1759SClaudio Fontana &timers_state.vm_clock_lock); 211740b1759SClaudio Fontana } 212740b1759SClaudio Fontana 213740b1759SClaudio Fontana static void icount_adjust_rt(void *opaque) 214740b1759SClaudio Fontana { 215740b1759SClaudio Fontana timer_mod(timers_state.icount_rt_timer, 216740b1759SClaudio Fontana qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); 217740b1759SClaudio Fontana icount_adjust(); 218740b1759SClaudio Fontana } 219740b1759SClaudio Fontana 220740b1759SClaudio Fontana static void icount_adjust_vm(void *opaque) 221740b1759SClaudio Fontana { 222740b1759SClaudio Fontana timer_mod(timers_state.icount_vm_timer, 223740b1759SClaudio Fontana qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 224740b1759SClaudio Fontana NANOSECONDS_PER_SECOND / 10); 225740b1759SClaudio Fontana icount_adjust(); 226740b1759SClaudio Fontana } 227740b1759SClaudio Fontana 2288191d368SClaudio Fontana int64_t icount_round(int64_t count) 229740b1759SClaudio Fontana { 230740b1759SClaudio Fontana int shift = qatomic_read(&timers_state.icount_time_shift); 231740b1759SClaudio Fontana return (count + (1 << shift) - 1) >> shift; 232740b1759SClaudio Fontana } 233740b1759SClaudio Fontana 234740b1759SClaudio Fontana static void icount_warp_rt(void) 235740b1759SClaudio Fontana { 236740b1759SClaudio Fontana unsigned seq; 237740b1759SClaudio Fontana int64_t warp_start; 238740b1759SClaudio Fontana 239740b1759SClaudio Fontana /* 240740b1759SClaudio Fontana * The icount_warp_timer is rescheduled soon after vm_clock_warp_start 241740b1759SClaudio Fontana * changes from -1 to another value, so the race here is okay. 242740b1759SClaudio Fontana */ 243740b1759SClaudio Fontana do { 244740b1759SClaudio Fontana seq = seqlock_read_begin(&timers_state.vm_clock_seqlock); 245740b1759SClaudio Fontana warp_start = timers_state.vm_clock_warp_start; 246740b1759SClaudio Fontana } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq)); 247740b1759SClaudio Fontana 248740b1759SClaudio Fontana if (warp_start == -1) { 249740b1759SClaudio Fontana return; 250740b1759SClaudio Fontana } 251740b1759SClaudio Fontana 252740b1759SClaudio Fontana seqlock_write_lock(&timers_state.vm_clock_seqlock, 253740b1759SClaudio Fontana &timers_state.vm_clock_lock); 254740b1759SClaudio Fontana if (runstate_is_running()) { 255740b1759SClaudio Fontana int64_t clock = REPLAY_CLOCK_LOCKED(REPLAY_CLOCK_VIRTUAL_RT, 256740b1759SClaudio Fontana cpu_get_clock_locked()); 257740b1759SClaudio Fontana int64_t warp_delta; 258740b1759SClaudio Fontana 259740b1759SClaudio Fontana warp_delta = clock - timers_state.vm_clock_warp_start; 260740b1759SClaudio Fontana if (icount_enabled() == 2) { 261740b1759SClaudio Fontana /* 262740b1759SClaudio Fontana * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too 263740b1759SClaudio Fontana * far ahead of real time. 264740b1759SClaudio Fontana */ 2658191d368SClaudio Fontana int64_t cur_icount = icount_get_locked(); 266740b1759SClaudio Fontana int64_t delta = clock - cur_icount; 267740b1759SClaudio Fontana warp_delta = MIN(warp_delta, delta); 268740b1759SClaudio Fontana } 269740b1759SClaudio Fontana qatomic_set_i64(&timers_state.qemu_icount_bias, 270740b1759SClaudio Fontana timers_state.qemu_icount_bias + warp_delta); 271740b1759SClaudio Fontana } 272740b1759SClaudio Fontana timers_state.vm_clock_warp_start = -1; 273740b1759SClaudio Fontana seqlock_write_unlock(&timers_state.vm_clock_seqlock, 274740b1759SClaudio Fontana &timers_state.vm_clock_lock); 275740b1759SClaudio Fontana 276740b1759SClaudio Fontana if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) { 277740b1759SClaudio Fontana qemu_clock_notify(QEMU_CLOCK_VIRTUAL); 278740b1759SClaudio Fontana } 279740b1759SClaudio Fontana } 280740b1759SClaudio Fontana 281740b1759SClaudio Fontana static void icount_timer_cb(void *opaque) 282740b1759SClaudio Fontana { 283740b1759SClaudio Fontana /* 284740b1759SClaudio Fontana * No need for a checkpoint because the timer already synchronizes 285740b1759SClaudio Fontana * with CHECKPOINT_CLOCK_VIRTUAL_RT. 286740b1759SClaudio Fontana */ 287740b1759SClaudio Fontana icount_warp_rt(); 288740b1759SClaudio Fontana } 289740b1759SClaudio Fontana 2908191d368SClaudio Fontana void icount_start_warp_timer(void) 291740b1759SClaudio Fontana { 292740b1759SClaudio Fontana int64_t clock; 293740b1759SClaudio Fontana int64_t deadline; 294740b1759SClaudio Fontana 295740b1759SClaudio Fontana assert(icount_enabled()); 296740b1759SClaudio Fontana 297740b1759SClaudio Fontana /* 298740b1759SClaudio Fontana * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers 299740b1759SClaudio Fontana * do not fire, so computing the deadline does not make sense. 300740b1759SClaudio Fontana */ 301740b1759SClaudio Fontana if (!runstate_is_running()) { 302740b1759SClaudio Fontana return; 303740b1759SClaudio Fontana } 304740b1759SClaudio Fontana 305740b1759SClaudio Fontana if (replay_mode != REPLAY_MODE_PLAY) { 306740b1759SClaudio Fontana if (!all_cpu_threads_idle()) { 307740b1759SClaudio Fontana return; 308740b1759SClaudio Fontana } 309740b1759SClaudio Fontana 310740b1759SClaudio Fontana if (qtest_enabled()) { 311740b1759SClaudio Fontana /* When testing, qtest commands advance icount. */ 312740b1759SClaudio Fontana return; 313740b1759SClaudio Fontana } 314740b1759SClaudio Fontana 315740b1759SClaudio Fontana replay_checkpoint(CHECKPOINT_CLOCK_WARP_START); 316740b1759SClaudio Fontana } else { 317740b1759SClaudio Fontana /* warp clock deterministically in record/replay mode */ 318740b1759SClaudio Fontana if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) { 319740b1759SClaudio Fontana /* 320740b1759SClaudio Fontana * vCPU is sleeping and warp can't be started. 321740b1759SClaudio Fontana * It is probably a race condition: notification sent 322740b1759SClaudio Fontana * to vCPU was processed in advance and vCPU went to sleep. 323740b1759SClaudio Fontana * Therefore we have to wake it up for doing someting. 324740b1759SClaudio Fontana */ 325*60618e2dSPavel Dovgalyuk if (replay_has_event()) { 326740b1759SClaudio Fontana qemu_clock_notify(QEMU_CLOCK_VIRTUAL); 327740b1759SClaudio Fontana } 328740b1759SClaudio Fontana return; 329740b1759SClaudio Fontana } 330740b1759SClaudio Fontana } 331740b1759SClaudio Fontana 332740b1759SClaudio Fontana /* We want to use the earliest deadline from ALL vm_clocks */ 333740b1759SClaudio Fontana clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT); 334740b1759SClaudio Fontana deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, 335740b1759SClaudio Fontana ~QEMU_TIMER_ATTR_EXTERNAL); 336740b1759SClaudio Fontana if (deadline < 0) { 337740b1759SClaudio Fontana static bool notified; 338740b1759SClaudio Fontana if (!icount_sleep && !notified) { 339740b1759SClaudio Fontana warn_report("icount sleep disabled and no active timers"); 340740b1759SClaudio Fontana notified = true; 341740b1759SClaudio Fontana } 342740b1759SClaudio Fontana return; 343740b1759SClaudio Fontana } 344740b1759SClaudio Fontana 345740b1759SClaudio Fontana if (deadline > 0) { 346740b1759SClaudio Fontana /* 347740b1759SClaudio Fontana * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to 348740b1759SClaudio Fontana * sleep. Otherwise, the CPU might be waiting for a future timer 349740b1759SClaudio Fontana * interrupt to wake it up, but the interrupt never comes because 350740b1759SClaudio Fontana * the vCPU isn't running any insns and thus doesn't advance the 351740b1759SClaudio Fontana * QEMU_CLOCK_VIRTUAL. 352740b1759SClaudio Fontana */ 353740b1759SClaudio Fontana if (!icount_sleep) { 354740b1759SClaudio Fontana /* 355740b1759SClaudio Fontana * We never let VCPUs sleep in no sleep icount mode. 356740b1759SClaudio Fontana * If there is a pending QEMU_CLOCK_VIRTUAL timer we just advance 357740b1759SClaudio Fontana * to the next QEMU_CLOCK_VIRTUAL event and notify it. 358740b1759SClaudio Fontana * It is useful when we want a deterministic execution time, 359740b1759SClaudio Fontana * isolated from host latencies. 360740b1759SClaudio Fontana */ 361740b1759SClaudio Fontana seqlock_write_lock(&timers_state.vm_clock_seqlock, 362740b1759SClaudio Fontana &timers_state.vm_clock_lock); 363740b1759SClaudio Fontana qatomic_set_i64(&timers_state.qemu_icount_bias, 364740b1759SClaudio Fontana timers_state.qemu_icount_bias + deadline); 365740b1759SClaudio Fontana seqlock_write_unlock(&timers_state.vm_clock_seqlock, 366740b1759SClaudio Fontana &timers_state.vm_clock_lock); 367740b1759SClaudio Fontana qemu_clock_notify(QEMU_CLOCK_VIRTUAL); 368740b1759SClaudio Fontana } else { 369740b1759SClaudio Fontana /* 370740b1759SClaudio Fontana * We do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL after some 371740b1759SClaudio Fontana * "real" time, (related to the time left until the next event) has 372740b1759SClaudio Fontana * passed. The QEMU_CLOCK_VIRTUAL_RT clock will do this. 373740b1759SClaudio Fontana * This avoids that the warps are visible externally; for example, 374740b1759SClaudio Fontana * you will not be sending network packets continuously instead of 375740b1759SClaudio Fontana * every 100ms. 376740b1759SClaudio Fontana */ 377740b1759SClaudio Fontana seqlock_write_lock(&timers_state.vm_clock_seqlock, 378740b1759SClaudio Fontana &timers_state.vm_clock_lock); 379740b1759SClaudio Fontana if (timers_state.vm_clock_warp_start == -1 380740b1759SClaudio Fontana || timers_state.vm_clock_warp_start > clock) { 381740b1759SClaudio Fontana timers_state.vm_clock_warp_start = clock; 382740b1759SClaudio Fontana } 383740b1759SClaudio Fontana seqlock_write_unlock(&timers_state.vm_clock_seqlock, 384740b1759SClaudio Fontana &timers_state.vm_clock_lock); 385740b1759SClaudio Fontana timer_mod_anticipate(timers_state.icount_warp_timer, 386740b1759SClaudio Fontana clock + deadline); 387740b1759SClaudio Fontana } 388740b1759SClaudio Fontana } else if (deadline == 0) { 389740b1759SClaudio Fontana qemu_clock_notify(QEMU_CLOCK_VIRTUAL); 390740b1759SClaudio Fontana } 391740b1759SClaudio Fontana } 392740b1759SClaudio Fontana 3938191d368SClaudio Fontana void icount_account_warp_timer(void) 394740b1759SClaudio Fontana { 39545e077d7SClaudio Fontana if (!icount_sleep) { 396740b1759SClaudio Fontana return; 397740b1759SClaudio Fontana } 398740b1759SClaudio Fontana 399740b1759SClaudio Fontana /* 400740b1759SClaudio Fontana * Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers 401740b1759SClaudio Fontana * do not fire, so computing the deadline does not make sense. 402740b1759SClaudio Fontana */ 403740b1759SClaudio Fontana if (!runstate_is_running()) { 404740b1759SClaudio Fontana return; 405740b1759SClaudio Fontana } 406740b1759SClaudio Fontana 407*60618e2dSPavel Dovgalyuk replay_async_events(); 408*60618e2dSPavel Dovgalyuk 409740b1759SClaudio Fontana /* warp clock deterministically in record/replay mode */ 410740b1759SClaudio Fontana if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) { 411740b1759SClaudio Fontana return; 412740b1759SClaudio Fontana } 413740b1759SClaudio Fontana 414740b1759SClaudio Fontana timer_del(timers_state.icount_warp_timer); 415740b1759SClaudio Fontana icount_warp_rt(); 416740b1759SClaudio Fontana } 417740b1759SClaudio Fontana 4188191d368SClaudio Fontana void icount_configure(QemuOpts *opts, Error **errp) 419740b1759SClaudio Fontana { 420740b1759SClaudio Fontana const char *option = qemu_opt_get(opts, "shift"); 421740b1759SClaudio Fontana bool sleep = qemu_opt_get_bool(opts, "sleep", true); 422740b1759SClaudio Fontana bool align = qemu_opt_get_bool(opts, "align", false); 423740b1759SClaudio Fontana long time_shift = -1; 424740b1759SClaudio Fontana 425740b1759SClaudio Fontana if (!option) { 426740b1759SClaudio Fontana if (qemu_opt_get(opts, "align") != NULL) { 427740b1759SClaudio Fontana error_setg(errp, "Please specify shift option when using align"); 428740b1759SClaudio Fontana } 429740b1759SClaudio Fontana return; 430740b1759SClaudio Fontana } 431740b1759SClaudio Fontana 432740b1759SClaudio Fontana if (align && !sleep) { 433740b1759SClaudio Fontana error_setg(errp, "align=on and sleep=off are incompatible"); 434740b1759SClaudio Fontana return; 435740b1759SClaudio Fontana } 436740b1759SClaudio Fontana 437740b1759SClaudio Fontana if (strcmp(option, "auto") != 0) { 438740b1759SClaudio Fontana if (qemu_strtol(option, NULL, 0, &time_shift) < 0 439740b1759SClaudio Fontana || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) { 440740b1759SClaudio Fontana error_setg(errp, "icount: Invalid shift value"); 441740b1759SClaudio Fontana return; 442740b1759SClaudio Fontana } 443740b1759SClaudio Fontana } else if (icount_align_option) { 444740b1759SClaudio Fontana error_setg(errp, "shift=auto and align=on are incompatible"); 445740b1759SClaudio Fontana return; 446740b1759SClaudio Fontana } else if (!icount_sleep) { 447740b1759SClaudio Fontana error_setg(errp, "shift=auto and sleep=off are incompatible"); 448740b1759SClaudio Fontana return; 449740b1759SClaudio Fontana } 450740b1759SClaudio Fontana 451740b1759SClaudio Fontana icount_sleep = sleep; 452740b1759SClaudio Fontana if (icount_sleep) { 453740b1759SClaudio Fontana timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, 454740b1759SClaudio Fontana icount_timer_cb, NULL); 455740b1759SClaudio Fontana } 456740b1759SClaudio Fontana 457740b1759SClaudio Fontana icount_align_option = align; 458740b1759SClaudio Fontana 459740b1759SClaudio Fontana if (time_shift >= 0) { 460740b1759SClaudio Fontana timers_state.icount_time_shift = time_shift; 461740b1759SClaudio Fontana icount_enable_precise(); 462740b1759SClaudio Fontana return; 463740b1759SClaudio Fontana } 464740b1759SClaudio Fontana 465740b1759SClaudio Fontana icount_enable_adaptive(); 466740b1759SClaudio Fontana 467740b1759SClaudio Fontana /* 468740b1759SClaudio Fontana * 125MIPS seems a reasonable initial guess at the guest speed. 469740b1759SClaudio Fontana * It will be corrected fairly quickly anyway. 470740b1759SClaudio Fontana */ 471740b1759SClaudio Fontana timers_state.icount_time_shift = 3; 472740b1759SClaudio Fontana 473740b1759SClaudio Fontana /* 474740b1759SClaudio Fontana * Have both realtime and virtual time triggers for speed adjustment. 475740b1759SClaudio Fontana * The realtime trigger catches emulated time passing too slowly, 476740b1759SClaudio Fontana * the virtual time trigger catches emulated time passing too fast. 477740b1759SClaudio Fontana * Realtime triggers occur even when idle, so use them less frequently 478740b1759SClaudio Fontana * than VM triggers. 479740b1759SClaudio Fontana */ 480740b1759SClaudio Fontana timers_state.vm_clock_warp_start = -1; 481740b1759SClaudio Fontana timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT, 482740b1759SClaudio Fontana icount_adjust_rt, NULL); 483740b1759SClaudio Fontana timer_mod(timers_state.icount_rt_timer, 484740b1759SClaudio Fontana qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000); 485740b1759SClaudio Fontana timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 486740b1759SClaudio Fontana icount_adjust_vm, NULL); 487740b1759SClaudio Fontana timer_mod(timers_state.icount_vm_timer, 488740b1759SClaudio Fontana qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 489740b1759SClaudio Fontana NANOSECONDS_PER_SECOND / 10); 490740b1759SClaudio Fontana } 49175bbe5e5SPavel Dovgalyuk 49275bbe5e5SPavel Dovgalyuk void icount_notify_exit(void) 49375bbe5e5SPavel Dovgalyuk { 49475bbe5e5SPavel Dovgalyuk if (icount_enabled() && current_cpu) { 49575bbe5e5SPavel Dovgalyuk qemu_cpu_kick(current_cpu); 49675bbe5e5SPavel Dovgalyuk qemu_clock_notify(QEMU_CLOCK_VIRTUAL); 49775bbe5e5SPavel Dovgalyuk } 49875bbe5e5SPavel Dovgalyuk } 499