@@ -375,6 +375,7 @@ struct CPUState {
int singlestep_enabled;
int64_t icount_budget;
int64_t icount_extra;
+ uint64_t random_seed;
sigjmp_buf jmp_env;
QemuMutex work_mutex;
@@ -50,6 +50,7 @@
#include "qemu/option.h"
#include "qemu/bitmap.h"
#include "qemu/seqlock.h"
+#include "qemu/guest-random.h"
#include "tcg.h"
#include "hw/nmi.h"
#include "sysemu/replay.h"
@@ -1276,6 +1277,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1319,6 +1321,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
qemu_mutex_unlock_iothread();
@@ -1478,6 +1481,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
cpu->created = true;
cpu->can_do_io = 1;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
/* wait for initial kick-off after machine start */
while (first_cpu->stopped) {
@@ -1592,6 +1596,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
hax_init_vcpu(cpu);
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1631,6 +1636,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1671,6 +1677,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg)
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
@@ -1724,6 +1731,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
cpu->can_do_io = 1;
current_cpu = cpu;
qemu_cond_signal(&qemu_cpu_cond);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
/* process any pending work */
cpu->exit_request = 1;
@@ -2071,6 +2079,7 @@ void qemu_init_vcpu(CPUState *cpu)
cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads;
cpu->stopped = true;
+ cpu->random_seed = qemu_guest_random_seed_thread_part1();
if (!cpu->as) {
/* If the target cpu hasn't set up any address spaces itself,
@@ -128,6 +128,7 @@ int main(int argc, char **argv)
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
+#include "qemu/guest-random.h"
#define MAX_VIRTIO_CONSOLES 1
@@ -3349,6 +3350,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_DFILTER:
qemu_set_dfilter_ranges(optarg, &error_fatal);
break;
+ case QEMU_OPTION_seed:
+ qemu_guest_random_seed_main(optarg, &error_fatal);
+ break;
case QEMU_OPTION_s:
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
break;
@@ -3641,6 +3641,16 @@ the 0x200 sized block starting at 0xffffffc000080000 and another 0x1000 sized
block starting at 0xffffffc00005f000.
ETEXI
+DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
+ "-seed number seed the pseudo-random number generator\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -seed @var{number}
+@findex -seed
+Force the guest to use a deterministic pseudo-random number generator, seeded
+with @var{number}. This does not affect crypto routines within the host.
+ETEXI
+
DEF("L", HAS_ARG, QEMU_OPTION_L, \
"-L path set the directory for the BIOS, VGA BIOS and keymaps\n",
QEMU_ARCH_ALL)