Browse Source

cpus: Initialize pseudo-random seeds for all guest cpus

When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode.  Pass derived seeds
to each cpu created; which is a no-op unless the subsystem is in
deterministic mode.

Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
master
Richard Henderson 3 months ago
parent
commit
9c09a2518e
4 changed files with 24 additions and 0 deletions
  1. 9
    0
      cpus.c
  2. 1
    0
      include/qom/cpu.h
  3. 10
    0
      qemu-options.hx
  4. 4
    0
      vl.c

+ 9
- 0
cpus.c View File

@@ -50,6 +50,7 @@
50 50
 #include "qemu/option.h"
51 51
 #include "qemu/bitmap.h"
52 52
 #include "qemu/seqlock.h"
53
+#include "qemu/guest-random.h"
53 54
 #include "tcg.h"
54 55
 #include "hw/nmi.h"
55 56
 #include "sysemu/replay.h"
@@ -1276,6 +1277,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
1276 1277
     /* signal CPU creation */
1277 1278
     cpu->created = true;
1278 1279
     qemu_cond_signal(&qemu_cpu_cond);
1280
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1279 1281
 
1280 1282
     do {
1281 1283
         if (cpu_can_run(cpu)) {
@@ -1319,6 +1321,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
1319 1321
     /* signal CPU creation */
1320 1322
     cpu->created = true;
1321 1323
     qemu_cond_signal(&qemu_cpu_cond);
1324
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1322 1325
 
1323 1326
     do {
1324 1327
         qemu_mutex_unlock_iothread();
@@ -1478,6 +1481,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
1478 1481
     cpu->created = true;
1479 1482
     cpu->can_do_io = 1;
1480 1483
     qemu_cond_signal(&qemu_cpu_cond);
1484
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1481 1485
 
1482 1486
     /* wait for initial kick-off after machine start */
1483 1487
     while (first_cpu->stopped) {
@@ -1592,6 +1596,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
1592 1596
 
1593 1597
     hax_init_vcpu(cpu);
1594 1598
     qemu_cond_signal(&qemu_cpu_cond);
1599
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1595 1600
 
1596 1601
     do {
1597 1602
         if (cpu_can_run(cpu)) {
@@ -1631,6 +1636,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
1631 1636
     /* signal CPU creation */
1632 1637
     cpu->created = true;
1633 1638
     qemu_cond_signal(&qemu_cpu_cond);
1639
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1634 1640
 
1635 1641
     do {
1636 1642
         if (cpu_can_run(cpu)) {
@@ -1671,6 +1677,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg)
1671 1677
     /* signal CPU creation */
1672 1678
     cpu->created = true;
1673 1679
     qemu_cond_signal(&qemu_cpu_cond);
1680
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1674 1681
 
1675 1682
     do {
1676 1683
         if (cpu_can_run(cpu)) {
@@ -1724,6 +1731,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
1724 1731
     cpu->can_do_io = 1;
1725 1732
     current_cpu = cpu;
1726 1733
     qemu_cond_signal(&qemu_cpu_cond);
1734
+    qemu_guest_random_seed_thread_part2(cpu->random_seed);
1727 1735
 
1728 1736
     /* process any pending work */
1729 1737
     cpu->exit_request = 1;
@@ -2071,6 +2079,7 @@ void qemu_init_vcpu(CPUState *cpu)
2071 2079
     cpu->nr_cores = smp_cores;
2072 2080
     cpu->nr_threads = smp_threads;
2073 2081
     cpu->stopped = true;
2082
+    cpu->random_seed = qemu_guest_random_seed_thread_part1();
2074 2083
 
2075 2084
     if (!cpu->as) {
2076 2085
         /* If the target cpu hasn't set up any address spaces itself,

+ 1
- 0
include/qom/cpu.h View File

@@ -375,6 +375,7 @@ struct CPUState {
375 375
     int singlestep_enabled;
376 376
     int64_t icount_budget;
377 377
     int64_t icount_extra;
378
+    uint64_t random_seed;
378 379
     sigjmp_buf jmp_env;
379 380
 
380 381
     QemuMutex work_mutex;

+ 10
- 0
qemu-options.hx View File

@@ -3641,6 +3641,16 @@ the 0x200 sized block starting at 0xffffffc000080000 and another 0x1000 sized
3641 3641
 block starting at 0xffffffc00005f000.
3642 3642
 ETEXI
3643 3643
 
3644
+DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
3645
+    "-seed number       seed the pseudo-random number generator\n",
3646
+    QEMU_ARCH_ALL)
3647
+STEXI
3648
+@item -seed @var{number}
3649
+@findex -seed
3650
+Force the guest to use a deterministic pseudo-random number generator, seeded
3651
+with @var{number}.  This does not affect crypto routines within the host.
3652
+ETEXI
3653
+
3644 3654
 DEF("L", HAS_ARG, QEMU_OPTION_L, \
3645 3655
     "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n",
3646 3656
     QEMU_ARCH_ALL)

+ 4
- 0
vl.c View File

@@ -128,6 +128,7 @@ int main(int argc, char **argv)
128 128
 #include "qapi/qapi-commands-ui.h"
129 129
 #include "qapi/qmp/qerror.h"
130 130
 #include "sysemu/iothread.h"
131
+#include "qemu/guest-random.h"
131 132
 
132 133
 #define MAX_VIRTIO_CONSOLES 1
133 134
 
@@ -3349,6 +3350,9 @@ int main(int argc, char **argv, char **envp)
3349 3350
             case QEMU_OPTION_DFILTER:
3350 3351
                 qemu_set_dfilter_ranges(optarg, &error_fatal);
3351 3352
                 break;
3353
+            case QEMU_OPTION_seed:
3354
+                qemu_guest_random_seed_main(optarg, &error_fatal);
3355
+                break;
3352 3356
             case QEMU_OPTION_s:
3353 3357
                 add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
3354 3358
                 break;

Loading…
Cancel
Save