]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
replay: avoid recursive call of checkpoints
authorPavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Tue, 27 Feb 2018 09:53:05 +0000 (12:53 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 12 Mar 2018 16:10:38 +0000 (17:10 +0100)
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>
replay/replay.c

index 90f98b749024b583813d415498812628cbc1a37a..eae8daf18ab8e9c2eb10b82441f27b5aedd58e69 100644 (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;
 }