@@ -519,6 +519,7 @@ void configure_icount(QemuOpts *opts, Error **errp)
{
const char *option;
char *rem_str = NULL;
+ bool enable_rexec;
seqlock_init(&timers_state.vm_clock_seqlock, NULL);
vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
@@ -532,6 +533,9 @@ void configure_icount(QemuOpts *opts, Error **errp)
icount_align_option = qemu_opt_get_bool(opts, "align", false);
icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
icount_warp_rt, NULL);
+
+ enable_rexec = qemu_opt_get_bool(opts, "rexec", false);
+
if (strcmp(option, "auto") != 0) {
errno = 0;
icount_time_shift = strtol(option, &rem_str, 0);
@@ -539,11 +543,22 @@ void configure_icount(QemuOpts *opts, Error **errp)
error_setg(errp, "icount: Invalid shift value");
}
use_icount = 1;
+
+ if (enable_rexec) {
+ rexec_setup();
+ }
return;
} else if (icount_align_option) {
error_setg(errp, "shift=auto and align=on are incompatible");
}
+ /*
+ * We don't allow to run reverse execution with use_icount != 1.
+ */
+ if (enable_rexec) {
+ error_setg(errp, "Reverse execution requires icount in fixed mode.");
+ }
+
use_icount = 2;
/* 125MIPS seems a reasonable initial guess at the guest speed.
@@ -3026,7 +3026,7 @@ re-inject them.
ETEXI
DEF("icount", HAS_ARG, QEMU_OPTION_icount, \
- "-icount [shift=N|auto][,align=on|off]\n" \
+ "-icount [shift=N|auto][,align=on|off][,rexec=on,|off]\n" \
" enable virtual instruction counter with 2^N clock ticks per\n" \
" instruction and enable aligning the host and virtual clocks\n", QEMU_ARCH_ALL)
STEXI
@@ -3052,6 +3052,9 @@ Currently this option does not work when @option{shift} is @code{auto}.
Note: The sync algorithm will work for those shift values for which
the guest clock runs ahead of the host clock. Typically this happens
when the shift value is high (how high depends on the host machine).
+@option{rexec=on} will enable reverse execution. A snapshot is taken regularly
+and will allow to replay the execution when gdb reverse-step or reverse-cont
+command are used. This requires shift!=auto.
ETEXI
DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
@@ -556,8 +556,10 @@ static QemuOptsList qemu_icount_opts = {
}, {
.name = "align",
.type = QEMU_OPT_BOOL,
- },
- { /* end of list */ }
+ }, {
+ .name = "rexec",
+ .type = QEMU_OPT_BOOL,
+ }, { /* end of list */ }
},
};
@@ -4582,5 +4584,8 @@ int main(int argc, char **argv, char **envp)
tpm_cleanup();
#endif
+ if (rexec_is_enabled()) {
+ rexec_cleanup();
+ }
return 0;
}