replay: avoid recursive call of checkpoints

This patch adds a flag which denies recursive call of replay_checkpoint
function. Checkpoints may be accompanied by the hardware events. When event
is processed, virtual device may invoke timer modification functions that
also invoke the checkpoint function. This leads to infinite loop.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20180227095305.1060.56463.stgit@pasha-VirtualBox>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
This commit is contained in:
Pavel Dovgalyuk 2018-02-27 12:53:05 +03:00 committed by Paolo Bonzini
parent 6dc0f52963
commit 66eb7825d0
1 changed files with 13 additions and 1 deletions

View File

@ -176,13 +176,24 @@ void replay_shutdown_request(ShutdownCause cause)
bool replay_checkpoint(ReplayCheckpoint checkpoint)
{
bool res = false;
static bool in_checkpoint;
assert(EVENT_CHECKPOINT + checkpoint <= EVENT_CHECKPOINT_LAST);
replay_save_instructions();
if (!replay_file) {
return true;
}
if (in_checkpoint) {
/* If we are already in checkpoint, then there is no need
for additional synchronization.
Recursion occurs when HW event modifies timers.
Timer modification may invoke the checkpoint and
proceed to recursion. */
return true;
}
in_checkpoint = true;
replay_save_instructions();
if (replay_mode == REPLAY_MODE_PLAY) {
g_assert(replay_mutex_locked());
@ -204,6 +215,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
res = true;
}
out:
in_checkpoint = false;
return res;
}