aboutsummaryrefslogtreecommitdiff
path: root/replay/replay-random.c
diff options
context:
space:
mode:
authorPavel Dovgalyuk <pavel.dovgaluk@gmail.com>2019-12-19 15:50:48 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2020-01-07 12:08:39 +0100
commit878ec29b9c1915ea0da951064b8aac3050f2f5b9 (patch)
tree157253fa0974bd1e85f066c9c98b102e5de5cc67 /replay/replay-random.c
parentfc6b2dbac1d57fc24420fb8ee25911eb6f1d1fb5 (diff)
replay: record and replay random number sources
Record/replay feature of icount allows deterministic running of execution scenarios. Some CPUs and peripheral devices read random numbers from external sources making deterministic execution impossible. This patch adds recording and replaying of random read operations into guest-random module, which is used by the virtual hardware. Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> Message-Id: <157675984852.14505.15709141760677102489.stgit@pasha-Precision-3630-Tower> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'replay/replay-random.c')
-rw-r--r--replay/replay-random.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/replay/replay-random.c b/replay/replay-random.c
new file mode 100644
index 0000000000..afc7a0fccc
--- /dev/null
+++ b/replay/replay-random.c
@@ -0,0 +1,44 @@
+/*
+ * replay-random.c
+ *
+ * Copyright (c) 2010-2020 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "sysemu/replay.h"
+#include "replay-internal.h"
+
+void replay_save_random(int ret, void *buf, size_t len)
+{
+ g_assert(replay_mutex_locked());
+
+ replay_save_instructions();
+ replay_put_event(EVENT_RANDOM);
+ replay_put_dword(ret);
+ replay_put_array(buf, len);
+}
+
+int replay_read_random(void *buf, size_t len)
+{
+ int ret = 0;
+ g_assert(replay_mutex_locked());
+
+ replay_account_executed_instructions();
+ if (replay_next_event_is(EVENT_RANDOM)) {
+ size_t buf_size = 0;
+ ret = replay_get_dword();
+ replay_get_array(buf, &buf_size);
+ replay_finish_event();
+ g_assert(buf_size == len);
+ } else {
+ error_report("Missing random event in the replay log");
+ exit(1);
+ }
+ return ret;
+}