qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] replay: record and replay random number sources


From: Paolo Bonzini
Subject: Re: [PATCH] replay: record and replay random number sources
Date: Fri, 20 Dec 2019 14:14:10 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1

On 19/12/19 13:50, Pavel Dovgalyuk wrote:
> 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 <address@hidden>
> ---
>  docs/replay.txt          |    1 +
>  include/sysemu/replay.h  |    7 +++++++
>  replay/Makefile.objs     |    3 ++-
>  replay/replay-internal.h |    2 ++
>  replay/replay-random.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
>  replay/replay.c          |    2 +-
>  stubs/replay.c           |    9 +++++++++
>  util/guest-random.c      |   13 +++++++++++--
>  8 files changed, 77 insertions(+), 4 deletions(-)
>  create mode 100644 replay/replay-random.c
> 
> diff --git a/docs/replay.txt b/docs/replay.txt
> index ce97c3f72f..f4619a62a3 100644
> --- a/docs/replay.txt
> +++ b/docs/replay.txt
> @@ -67,6 +67,7 @@ Modifications of qemu include:
>   * network filter for recording and replaying the packets
>   * block driver for making block layer deterministic
>   * serial port input record and replay
> + * recording of random numbers obtained from the external sources
>  
>  Locking and thread synchronisation
>  ----------------------------------
> diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
> index 8df517298c..5471bb514d 100644
> --- a/include/sysemu/replay.h
> +++ b/include/sysemu/replay.h
> @@ -117,6 +117,13 @@ int64_t replay_read_clock(ReplayClockKind kind);
>              ? replay_save_clock((clock), (value), 
> cpu_get_icount_raw_locked()) \
>          : (value))
>  
> +/* Processing data from random generators */
> +
> +/* Saves the values from the random number generator */
> +void replay_save_random(int ret, void *buf, size_t len);
> +/* Loads the saved values for the random number generator */
> +int replay_read_random(void *buf, size_t len);
> +
>  /* Events */
>  
>  /*! Called when qemu shutdown is requested. */
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> index cee6539a23..939be964a9 100644
> --- a/replay/Makefile.objs
> +++ b/replay/Makefile.objs
> @@ -6,4 +6,5 @@ common-obj-y += replay-input.o
>  common-obj-y += replay-char.o
>  common-obj-y += replay-snapshot.o
>  common-obj-y += replay-net.o
> -common-obj-y += replay-audio.o
> \ No newline at end of file
> +common-obj-y += replay-audio.o
> +common-obj-y += replay-random.o
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index 55fca1ac6b..33ac551e78 100644
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -34,6 +34,8 @@ enum ReplayEvents {
>      EVENT_AUDIO_OUT,
>      /* for audio in event */
>      EVENT_AUDIO_IN,
> +    /* for random number generator */
> +    EVENT_RANDOM,
>      /* for clock read/writes */
>      /* some of greater codes are reserved for clocks */
>      EVENT_CLOCK,
> 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;
> +}
> diff --git a/replay/replay.c b/replay/replay.c
> index 5cc25bd2f8..706c7b4f4b 100644
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -22,7 +22,7 @@
>  
>  /* Current version of the replay mechanism.
>     Increase it when file format changes. */
> -#define REPLAY_VERSION              0xe02008
> +#define REPLAY_VERSION              0xe02009
>  /* Size of replay log header */
>  #define HEADER_SIZE                 (sizeof(uint32_t) + sizeof(uint64_t))
>  
> diff --git a/stubs/replay.c b/stubs/replay.c
> index 10b3925e2f..5974ec1f50 100644
> --- a/stubs/replay.c
> +++ b/stubs/replay.c
> @@ -79,3 +79,12 @@ void replay_mutex_lock(void)
>  void replay_mutex_unlock(void)
>  {
>  }
> +
> +void replay_save_random(int ret, void *buf, size_t len)
> +{
> +}
> +
> +int replay_read_random(void *buf, size_t len)
> +{
> +    return 0;
> +}
> diff --git a/util/guest-random.c b/util/guest-random.c
> index 9453968bd7..086115bd67 100644
> --- a/util/guest-random.c
> +++ b/util/guest-random.c
> @@ -14,6 +14,7 @@
>  #include "qapi/error.h"
>  #include "qemu/guest-random.h"
>  #include "crypto/random.h"
> +#include "sysemu/replay.h"
>  
>  
>  static __thread GRand *thread_rand;
> @@ -44,13 +45,21 @@ static int glib_random_bytes(void *buf, size_t len)
>  
>  int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
>  {
> +    int ret;
> +    if (replay_mode == REPLAY_MODE_PLAY) {
> +        return replay_read_random(buf, len);
> +    }
>      if (unlikely(deterministic)) {
>          /* Deterministic implementation using Glib's Mersenne Twister.  */
> -        return glib_random_bytes(buf, len);
> +        ret = glib_random_bytes(buf, len);
>      } else {
>          /* Non-deterministic implementation using crypto routines.  */
> -        return qcrypto_random_bytes(buf, len, errp);
> +        ret = qcrypto_random_bytes(buf, len, errp);
> +    }
> +    if (replay_mode == REPLAY_MODE_RECORD) {
> +        replay_save_random(ret, buf, len);
>      }
> +    return ret;
>  }
>  
>  void qemu_guest_getrandom_nofail(void *buf, size_t len)
> 

Queued, thanks.

Paolo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]