qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>, qemu-devel@nongnu.org
Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org,
	igor.rubinov@gmail.com, mark.burton@greensocs.com,
	real@ispras.ru, batuzovk@ispras.ru,
	maria.klimushenkova@ispras.ru, stefanha@redhat.com,
	kwolf@redhat.com, hines@cert.org, alex.bennee@linaro.org,
	fred.konrad@greensocs.com
Subject: Re: [Qemu-devel] [PATCH v5 1/7] replay: character devices
Date: Mon, 14 Mar 2016 15:11:45 +0100	[thread overview]
Message-ID: <56E6C6A1.2000008@redhat.com> (raw)
In-Reply-To: <20160314074436.4980.83856.stgit@PASHA-ISP>



On 14/03/2016 08:44, Pavel Dovgalyuk wrote:
> This patch implements record and replay of character devices.
> It records chardevs communication in replay mode. Recorded information
> include data read from backend and counter of bytes written
> from frontend to backend to preserve frontend internal state.
> If character device was configured through the command line in record mode,
> then in replay mode it should be also added to command line. Backend of
> the character device could be changed in replay mode.
> Replaying of devices that perform ioctl and get_msgfd operations is not
> supported.
> gdbstub which also acts as a backend is not recorded to allow controlling
> the replaying through gdb. Monitor backends are also not recorded.
> 
> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>

Thanks, this looks good.

Paolo

> ---
>  gdbstub.c                |    2 -
>  include/sysemu/char.h    |   26 +++++++
>  include/sysemu/replay.h  |   17 +++++
>  qemu-char.c              |  138 +++++++++++++++++++++++++++++++-------
>  replay/Makefile.objs     |    1 
>  replay/replay-char.c     |  167 ++++++++++++++++++++++++++++++++++++++++++++++
>  replay/replay-events.c   |   17 ++++-
>  replay/replay-internal.h |   18 +++++
>  replay/replay.c          |    2 -
>  9 files changed, 358 insertions(+), 30 deletions(-)
>  create mode 100755 replay/replay-char.c
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index 61c12b1..fdcb0ee 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1752,7 +1752,7 @@ int gdbserver_start(const char *device)
>              sigaction(SIGINT, &act, NULL);
>          }
>  #endif
> -        chr = qemu_chr_new("gdb", device, NULL);
> +        chr = qemu_chr_new_noreplay("gdb", device, NULL);
>          if (!chr)
>              return -1;
>  
> diff --git a/include/sysemu/char.h b/include/sysemu/char.h
> index e46884f..4c2f777 100644
> --- a/include/sysemu/char.h
> +++ b/include/sysemu/char.h
> @@ -86,6 +86,7 @@ struct CharDriverState {
>      int is_mux;
>      guint fd_in_tag;
>      QemuOpts *opts;
> +    bool replay;
>      QTAILQ_ENTRY(CharDriverState) next;
>  };
>  
> @@ -139,6 +140,22 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename,
>                                void (*init)(struct CharDriverState *s));
>  
>  /**
> + * @qemu_chr_new_noreplay:
> + *
> + * Create a new character backend from a URI.
> + * Character device communications are not written
> + * into the replay log.
> + *
> + * @label the name of the backend
> + * @filename the URI
> + * @init not sure..
> + *
> + * Returns: a new character backend
> + */
> +CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
> +                                       void (*init)(struct CharDriverState *s));
> +
> +/**
>   * @qemu_chr_delete:
>   *
>   * Destroy a character backend and remove it from the list of
> @@ -341,6 +358,15 @@ int qemu_chr_be_can_write(CharDriverState *s);
>   */
>  void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
>  
> +/**
> + * @qemu_chr_be_write_impl:
> + *
> + * Implementation of back end writing. Used by replay module.
> + *
> + * @buf a buffer to receive data from the front end
> + * @len the number of bytes to receive from the front end
> + */
> +void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len);
>  
>  /**
>   * @qemu_chr_be_event:
> diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
> index e4108e8..d24d502 100644
> --- a/include/sysemu/replay.h
> +++ b/include/sysemu/replay.h
> @@ -114,4 +114,21 @@ void replay_input_event(QemuConsole *src, InputEvent *evt);
>  /*! Adds input sync event to the queue */
>  void replay_input_sync_event(void);
>  
> +/* Character device */
> +
> +/*! Registers char driver to save it's events */
> +void replay_register_char_driver(struct CharDriverState *chr);
> +/*! Saves write to char device event to the log */
> +void replay_chr_be_write(struct CharDriverState *s, uint8_t *buf, int len);
> +/*! Writes char write return value to the replay log. */
> +void replay_char_write_event_save(int res, int offset);
> +/*! Reads char write return value from the replay log. */
> +void replay_char_write_event_load(int *res, int *offset);
> +/*! Reads information about read_all character event. */
> +int replay_char_read_all_load(uint8_t *buf);
> +/*! Writes character read_all error code into the replay log. */
> +void replay_char_read_all_save_error(int res);
> +/*! Writes character read_all execution result into the replay log. */
> +void replay_char_read_all_save_buf(uint8_t *buf, int offset);
> +
>  #endif
> diff --git a/qemu-char.c b/qemu-char.c
> index e0147f3..b418307 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -37,6 +37,7 @@
>  #include "io/channel-socket.h"
>  #include "io/channel-file.h"
>  #include "io/channel-tls.h"
> +#include "sysemu/replay.h"
>  
>  #include <zlib.h>
>  
> @@ -234,10 +235,46 @@ static void qemu_chr_fe_write_log(CharDriverState *s,
>      }
>  }
>  
> +static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int len, int *offset)
> +{
> +    int res = 0;
> +    *offset = 0;
> +
> +    qemu_mutex_lock(&s->chr_write_lock);
> +    while (*offset < len) {
> +        do {
> +            res = s->chr_write(s, buf + *offset, len - *offset);
> +            if (res == -1 && errno == EAGAIN) {
> +                g_usleep(100);
> +            }
> +        } while (res == -1 && errno == EAGAIN);
> +
> +        if (res <= 0) {
> +            break;
> +        }
> +
> +        *offset += res;
> +    }
> +    if (*offset > 0) {
> +        qemu_chr_fe_write_log(s, buf, *offset);
> +    }
> +    qemu_mutex_unlock(&s->chr_write_lock);
> +
> +    return res;
> +}
> +
>  int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
>  {
>      int ret;
>  
> +    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
> +        int offset;
> +        replay_char_write_event_load(&ret, &offset);
> +        assert(offset <= len);
> +        qemu_chr_fe_write_buffer(s, buf, offset, &offset);
> +        return ret;
> +    }
> +
>      qemu_mutex_lock(&s->chr_write_lock);
>      ret = s->chr_write(s, buf, len);
>  
> @@ -246,34 +283,31 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
>      }
>  
>      qemu_mutex_unlock(&s->chr_write_lock);
> +    
> +    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
> +        replay_char_write_event_save(ret, ret < 0 ? 0 : ret);
> +    }
> +    
>      return ret;
>  }
>  
>  int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len)
>  {
> -    int offset = 0;
> -    int res = 0;
> +    int offset;
> +    int res;
>  
> -    qemu_mutex_lock(&s->chr_write_lock);
> -    while (offset < len) {
> -        do {
> -            res = s->chr_write(s, buf + offset, len - offset);
> -            if (res == -1 && errno == EAGAIN) {
> -                g_usleep(100);
> -            }
> -        } while (res == -1 && errno == EAGAIN);
> +    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
> +        replay_char_write_event_load(&res, &offset);
> +        assert(offset <= len);
> +        qemu_chr_fe_write_buffer(s, buf, offset, &offset);
> +        return res;
> +    }
>  
> -        if (res <= 0) {
> -            break;
> -        }
> +    res = qemu_chr_fe_write_buffer(s, buf, len, &offset);
>  
> -        offset += res;
> +    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
> +        replay_char_write_event_save(res, offset);
>      }
> -    if (offset > 0) {
> -        qemu_chr_fe_write_log(s, buf, offset);
> -    }
> -
> -    qemu_mutex_unlock(&s->chr_write_lock);
>  
>      if (res < 0) {
>          return res;
> @@ -289,6 +323,10 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
>      if (!s->chr_sync_read) {
>          return 0;
>      }
> +    
> +    if (s->replay && replay_mode == REPLAY_MODE_PLAY) {
> +        return replay_char_read_all_load(buf);
> +    }
>  
>      while (offset < len) {
>          do {
> @@ -303,6 +341,9 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
>          }
>  
>          if (res < 0) {
> +            if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
> +                replay_char_read_all_save_error(res);
> +            }
>              return res;
>          }
>  
> @@ -313,14 +354,22 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
>          }
>      }
>  
> +    if (s->replay && replay_mode == REPLAY_MODE_RECORD) {
> +        replay_char_read_all_save_buf(buf, offset);
> +    }
>      return offset;
>  }
>  
>  int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
>  {
> -    if (!s->chr_ioctl)
> -        return -ENOTSUP;
> -    return s->chr_ioctl(s, cmd, arg);
> +    int res;
> +    if (!s->chr_ioctl || s->replay) {
> +        res = -ENOTSUP;
> +    } else {
> +        res = s->chr_ioctl(s, cmd, arg);
> +    }
> +
> +    return res;
>  }
>  
>  int qemu_chr_be_can_write(CharDriverState *s)
> @@ -330,17 +379,35 @@ int qemu_chr_be_can_write(CharDriverState *s)
>      return s->chr_can_read(s->handler_opaque);
>  }
>  
> -void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
> +void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len)
>  {
>      if (s->chr_read) {
>          s->chr_read(s->handler_opaque, buf, len);
>      }
>  }
>  
> +void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
> +{
> +    if (s->replay) {
> +        if (replay_mode == REPLAY_MODE_PLAY) {
> +            return;
> +        }
> +        replay_chr_be_write(s, buf, len);
> +    } else {
> +        qemu_chr_be_write_impl(s, buf, len);
> +    }
> +}
> +
>  int qemu_chr_fe_get_msgfd(CharDriverState *s)
>  {
>      int fd;
> -    return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
> +    int res = (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
> +    if (s->replay) {
> +        fprintf(stderr,
> +                "Replay: get msgfd is not supported for serial devices yet\n");
> +        exit(1);
> +    }
> +    return res;
>  }
>  
>  int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len)
> @@ -3855,7 +3922,8 @@ err:
>      return NULL;
>  }
>  
> -CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
> +CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename,
> +                                       void (*init)(struct CharDriverState *s))
>  {
>      const char *p;
>      CharDriverState *chr;
> @@ -3881,6 +3949,21 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
>      return chr;
>  }
>  
> +CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
> +{
> +    CharDriverState *chr;
> +    chr = qemu_chr_new_noreplay(label, filename, init);
> +    if (chr) {
> +        chr->replay = replay_mode != REPLAY_MODE_NONE;
> +        if (chr->replay && chr->chr_ioctl) {
> +            fprintf(stderr,
> +                    "Replay: ioctl is not supported for serial devices yet\n");
> +        }
> +        replay_register_char_driver(chr);
> +    }
> +    return chr;
> +}
> +
>  void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
>  {
>      if (chr->chr_set_echo) {
> @@ -4475,6 +4558,11 @@ void qmp_chardev_remove(const char *id, Error **errp)
>          error_setg(errp, "Chardev '%s' is busy", id);
>          return;
>      }
> +    if (chr->replay) {
> +        error_setg(errp,
> +            "Chardev '%s' cannot be unplugged in record/replay mode", id);
> +        return;
> +    }
>      qemu_chr_delete(chr);
>  }
>  
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> index 232193a..70e5572 100644
> --- a/replay/Makefile.objs
> +++ b/replay/Makefile.objs
> @@ -3,3 +3,4 @@ common-obj-y += replay-internal.o
>  common-obj-y += replay-events.o
>  common-obj-y += replay-time.o
>  common-obj-y += replay-input.o
> +common-obj-y += replay-char.o
> diff --git a/replay/replay-char.c b/replay/replay-char.c
> new file mode 100755
> index 0000000..bfbaf2e
> --- /dev/null
> +++ b/replay/replay-char.c
> @@ -0,0 +1,167 @@
> +/*
> + * replay-char.c
> + *
> + * Copyright (c) 2010-2016 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 <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "qemu/osdep.h"
> +#include "sysemu/replay.h"
> +#include "replay-internal.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/char.h"
> +
> +/* Char drivers that generate qemu_chr_be_write events
> +   that should be saved into the log. */
> +static CharDriverState **char_drivers;
> +static int drivers_count;
> +
> +/* Char event attributes. */
> +typedef struct CharEvent {
> +    int id;
> +    uint8_t *buf;
> +    size_t len;
> +} CharEvent;
> +
> +static int find_char_driver(CharDriverState *chr)
> +{
> +    int i = 0;
> +    for ( ; i < drivers_count ; ++i) {
> +        if (char_drivers[i] == chr) {
> +            return i;
> +        }
> +    }
> +    return -1;
> +}
> +
> +void replay_register_char_driver(CharDriverState *chr)
> +{
> +    if (replay_mode == REPLAY_MODE_NONE) {
> +        return;
> +    }
> +    char_drivers = g_realloc(char_drivers,
> +                             sizeof(*char_drivers) * (drivers_count + 1));
> +    char_drivers[drivers_count++] = chr;
> +}
> +
> +void replay_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
> +{
> +    CharEvent *event = g_malloc0(sizeof(CharEvent));
> +
> +    event->id = find_char_driver(s);
> +    if (event->id < 0) {
> +        fprintf(stderr, "Replay: cannot find char driver\n");
> +        exit(1);
> +    }
> +    event->buf = g_malloc(len);
> +    memcpy(event->buf, buf, len);
> +    event->len = len;
> +
> +    replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ, event, NULL, 0);
> +}
> +
> +void replay_event_char_read_run(void *opaque)
> +{
> +    CharEvent *event = (CharEvent *)opaque;
> +
> +    qemu_chr_be_write_impl(char_drivers[event->id], event->buf,
> +                           (int)event->len);
> +
> +    g_free(event->buf);
> +    g_free(event);
> +}
> +
> +void replay_event_char_read_save(void *opaque)
> +{
> +    CharEvent *event = (CharEvent *)opaque;
> +
> +    replay_put_byte(event->id);
> +    replay_put_array(event->buf, event->len);
> +}
> +
> +void *replay_event_char_read_load(void)
> +{
> +    CharEvent *event = g_malloc0(sizeof(CharEvent));
> +
> +    event->id = replay_get_byte();
> +    replay_get_array_alloc(&event->buf, &event->len);
> +
> +    return event;
> +}
> +
> +void replay_char_write_event_save(int res, int offset)
> +{
> +    replay_save_instructions();
> +    replay_mutex_lock();
> +    replay_put_event(EVENT_CHAR_WRITE);
> +    replay_put_dword(res);
> +    replay_put_dword(offset);
> +    replay_mutex_unlock();
> +}
> +
> +void replay_char_write_event_load(int *res, int *offset)
> +{
> +    replay_account_executed_instructions();
> +    replay_mutex_lock();
> +    if (replay_next_event_is(EVENT_CHAR_WRITE)) {
> +        *res = replay_get_dword();
> +        *offset = replay_get_dword();
> +        replay_finish_event();
> +        replay_mutex_unlock();
> +    } else {
> +        replay_mutex_unlock();
> +        error_report("Missing character write event in the replay log");
> +        exit(1);
> +    }
> +}
> +
> +int replay_char_read_all_load(uint8_t *buf)
> +{
> +    replay_mutex_lock();
> +    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
> +        size_t size;
> +        int res;
> +        replay_get_array(buf, &size);
> +        replay_finish_event();
> +        replay_mutex_unlock();
> +        res = (int)size;
> +        assert(res >= 0);
> +        return res;
> +    } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) {
> +        int res = replay_get_dword();
> +        replay_finish_event();
> +        replay_mutex_unlock();
> +        return res;
> +    } else {
> +        replay_mutex_unlock();
> +        error_report("Missing character read all event in the replay log");
> +        exit(1);
> +    }
> +}
> +
> +void replay_char_read_all_save_error(int res)
> +{
> +    assert(res < 0);
> +    replay_save_instructions();
> +    replay_mutex_lock();
> +    replay_put_event(EVENT_CHAR_READ_ALL_ERROR);
> +    replay_put_dword(res);
> +    replay_mutex_unlock();
> +}
> +
> +void replay_char_read_all_save_buf(uint8_t *buf, int offset)
> +{
> +    replay_save_instructions();
> +    replay_mutex_lock();
> +    replay_put_event(EVENT_CHAR_READ_ALL);
> +    replay_put_array(buf, offset);
> +    replay_mutex_unlock();
> +}
> diff --git a/replay/replay-events.c b/replay/replay-events.c
> index 2628109..ca940f7 100644
> --- a/replay/replay-events.c
> +++ b/replay/replay-events.c
> @@ -48,6 +48,9 @@ static void replay_run_event(Event *event)
>      case REPLAY_ASYNC_EVENT_INPUT_SYNC:
>          qemu_input_event_sync_impl();
>          break;
> +    case REPLAY_ASYNC_EVENT_CHAR_READ:
> +        replay_event_char_read_run(event->opaque);
> +        break;
>      default:
>          error_report("Replay: invalid async event ID (%d) in the queue",
>                      event->event_kind);
> @@ -102,9 +105,9 @@ void replay_clear_events(void)
>  }
>  
>  /*! Adds specified async event to the queue */
> -static void replay_add_event(ReplayAsyncEventKind event_kind,
> -                             void *opaque,
> -                             void *opaque2, uint64_t id)
> +void replay_add_event(ReplayAsyncEventKind event_kind,
> +                      void *opaque,
> +                      void *opaque2, uint64_t id)
>  {
>      assert(event_kind < REPLAY_ASYNC_COUNT);
>  
> @@ -168,6 +171,9 @@ static void replay_save_event(Event *event, int checkpoint)
>              break;
>          case REPLAY_ASYNC_EVENT_INPUT_SYNC:
>              break;
> +        case REPLAY_ASYNC_EVENT_CHAR_READ:
> +            replay_event_char_read_save(event->opaque);
> +            break;
>          default:
>              error_report("Unknown ID %d of replay event", read_event_kind);
>              exit(1);
> @@ -221,6 +227,11 @@ static Event *replay_read_event(int checkpoint)
>          event->event_kind = read_event_kind;
>          event->opaque = 0;
>          return event;
> +    case REPLAY_ASYNC_EVENT_CHAR_READ:
> +        event = g_malloc0(sizeof(Event));
> +        event->event_kind = read_event_kind;
> +        event->opaque = replay_event_char_read_load();
> +        return event;
>      default:
>          error_report("Unknown ID %d of replay event", read_event_kind);
>          exit(1);
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index 5438ebd..11f9a85 100644
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -24,6 +24,11 @@ enum ReplayEvents {
>      EVENT_ASYNC,
>      /* for shutdown request */
>      EVENT_SHUTDOWN,
> +    /* for character device write event */
> +    EVENT_CHAR_WRITE,
> +    /* for character device read all event */
> +    EVENT_CHAR_READ_ALL,
> +    EVENT_CHAR_READ_ALL_ERROR,
>      /* for clock read/writes */
>      /* some of greater codes are reserved for clocks */
>      EVENT_CLOCK,
> @@ -43,6 +48,7 @@ enum ReplayAsyncEventKind {
>      REPLAY_ASYNC_EVENT_BH,
>      REPLAY_ASYNC_EVENT_INPUT,
>      REPLAY_ASYNC_EVENT_INPUT_SYNC,
> +    REPLAY_ASYNC_EVENT_CHAR_READ,
>      REPLAY_ASYNC_COUNT
>  };
>  
> @@ -124,6 +130,9 @@ bool replay_has_events(void);
>  void replay_save_events(int checkpoint);
>  /*! Read events from the file into the input queue */
>  void replay_read_events(int checkpoint);
> +/*! Adds specified async event to the queue */
> +void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque,
> +                      void *opaque2, uint64_t id);
>  
>  /* Input events */
>  
> @@ -136,4 +145,13 @@ void replay_add_input_event(struct InputEvent *event);
>  /*! Adds input sync event to the queue */
>  void replay_add_input_sync_event(void);
>  
> +/* Character devices */
> +
> +/*! Called to run char device read event. */
> +void replay_event_char_read_run(void *opaque);
> +/*! Writes char read event to the file. */
> +void replay_event_char_read_save(void *opaque);
> +/*! Reads char event read from the file. */
> +void *replay_event_char_read_load(void);
> +
>  #endif
> diff --git a/replay/replay.c b/replay/replay.c
> index f8739c2..fcfde4f 100644
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -20,7 +20,7 @@
>  
>  /* Current version of the replay mechanism.
>     Increase it when file format changes. */
> -#define REPLAY_VERSION              0xe02002
> +#define REPLAY_VERSION              0xe02003
>  /* Size of replay log header */
>  #define HEADER_SIZE                 (sizeof(uint32_t) + sizeof(uint64_t))
>  
> 

  reply	other threads:[~2016-03-14 14:12 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-14  7:44 [Qemu-devel] [PATCH v5 0/7] Deterministic replay extensions Pavel Dovgalyuk
2016-03-14  7:44 ` [Qemu-devel] [PATCH v5 1/7] replay: character devices Pavel Dovgalyuk
2016-03-14 14:11   ` Paolo Bonzini [this message]
2016-03-23 15:45   ` Kevin Wolf
2016-03-23 16:54     ` Paolo Bonzini
2016-03-14  7:44 ` [Qemu-devel] [PATCH v5 2/7] icount: remove obsolete warp call Pavel Dovgalyuk
2016-03-14  7:44 ` [Qemu-devel] [PATCH v5 3/7] icount: decouple warp calls Pavel Dovgalyuk
2016-03-14  7:44 ` [Qemu-devel] [PATCH v5 4/7] block: add flush callback Pavel Dovgalyuk
2016-03-23 15:46   ` Kevin Wolf
2016-03-14  7:44 ` [Qemu-devel] [PATCH v5 5/7] replay: bh scheduling fix Pavel Dovgalyuk
2016-03-14  7:45 ` [Qemu-devel] [PATCH v5 6/7] replay: fix error message Pavel Dovgalyuk
2016-03-24 11:56   ` Kevin Wolf
2016-03-14  7:45 ` [Qemu-devel] [PATCH v5 7/7] replay: introduce block devices record/replay Pavel Dovgalyuk
2016-03-23 15:52   ` Kevin Wolf
2016-03-15 20:04 ` [Qemu-devel] [PATCH v5 0/7] Deterministic replay extensions Igor R
2016-03-17  8:06   ` Pavel Dovgalyuk
2016-03-24 11:59 ` Kevin Wolf
2016-03-24 19:24   ` Pavel Dovgalyuk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56E6C6A1.2000008@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=Pavel.Dovgaluk@ispras.ru \
    --cc=alex.bennee@linaro.org \
    --cc=batuzovk@ispras.ru \
    --cc=edgar.iglesias@xilinx.com \
    --cc=fred.konrad@greensocs.com \
    --cc=hines@cert.org \
    --cc=igor.rubinov@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=maria.klimushenkova@ispras.ru \
    --cc=mark.burton@greensocs.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=real@ispras.ru \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).