All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, peter.crosthwaite@xilinx.com,
	alex.bennee@linaro.org, mark.burton@greensocs.com,
	real@ispras.ru, batuzovk@ispras.ru,
	maria.klimushenkova@ispras.ru, pavel.dovgaluk@ispras.ru,
	pbonzini@redhat.com, afaerber@suse.de, fred.konrad@greensocs.com
Subject: [Qemu-devel] [RFC PATCH v5 31/31] replay: recording of the user input
Date: Wed, 26 Nov 2014 13:41:41 +0300	[thread overview]
Message-ID: <20141126104140.7772.71216.stgit@PASHA-ISP> (raw)
In-Reply-To: <20141126103841.7772.11864.stgit@PASHA-ISP>

This records user input (keyboard and mouse events) in record mode and replays
these input events in replay mode.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 include/ui/input.h       |    2 +
 replay/Makefile.objs     |    1 
 replay/replay-events.c   |   48 ++++++++++++++++++++
 replay/replay-input.c    |  108 ++++++++++++++++++++++++++++++++++++++++++++++
 replay/replay-internal.h |   11 ++++-
 replay/replay.h          |    5 ++
 ui/input.c               |   80 ++++++++++++++++++++++++++--------
 7 files changed, 235 insertions(+), 20 deletions(-)
 create mode 100755 replay/replay-input.c

diff --git a/include/ui/input.h b/include/ui/input.h
index 5d5ac00..d06a12d 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -33,7 +33,9 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
                              const char *device_id, int head,
                              Error **errp);
 void qemu_input_event_send(QemuConsole *src, InputEvent *evt);
+void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt);
 void qemu_input_event_sync(void);
+void qemu_input_event_sync_impl(void);
 
 InputEvent *qemu_input_event_new_key(KeyValue *key, bool down);
 void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down);
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 257c320..3936296 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -2,3 +2,4 @@ obj-y += replay.o
 obj-y += replay-internal.o
 obj-y += replay-events.o
 obj-y += replay-time.o
+obj-y += replay-input.o
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 4da5de0..308186b 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -13,6 +13,7 @@
 #include "replay.h"
 #include "replay-internal.h"
 #include "block/thread-pool.h"
+#include "ui/input.h"
 
 typedef struct Event {
     int event_kind;
@@ -43,6 +44,16 @@ static void replay_run_event(Event *event)
     case REPLAY_ASYNC_EVENT_THREAD:
         thread_pool_work((ThreadPool *)event->opaque, event->opaque2);
         break;
+    case REPLAY_ASYNC_EVENT_INPUT:
+        qemu_input_event_send_impl(NULL, (InputEvent *)event->opaque);
+        /* Using local variables, when replaying. Do not free them. */
+        if (replay_mode == REPLAY_MODE_RECORD) {
+            qapi_free_InputEvent((InputEvent *)event->opaque);
+        }
+        break;
+    case REPLAY_ASYNC_EVENT_INPUT_SYNC:
+        qemu_input_event_sync_impl();
+        break;
     default:
         fprintf(stderr, "Replay: invalid async event ID (%d) in the queue\n",
                 event->event_kind);
@@ -136,6 +147,16 @@ void replay_add_thread_event(void *opaque, void *opaque2, uint64_t id)
     replay_add_event_internal(REPLAY_ASYNC_EVENT_THREAD, opaque, opaque2, id);
 }
 
+void replay_add_input_event(struct InputEvent *event)
+{
+    replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT, event, NULL, 0);
+}
+
+void replay_add_input_sync_event(void)
+{
+    replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT_SYNC, NULL, NULL, 0);
+}
+
 void replay_save_events(int opt)
 {
     qemu_mutex_lock(&lock);
@@ -153,6 +174,9 @@ void replay_save_events(int opt)
             case REPLAY_ASYNC_EVENT_THREAD:
                 replay_put_qword(event->id);
                 break;
+            case REPLAY_ASYNC_EVENT_INPUT:
+                replay_save_input_event(event->opaque);
+                break;
             }
         }
 
@@ -178,6 +202,7 @@ void replay_read_events(int opt)
             break;
         }
         /* Execute some events without searching them in the queue */
+        Event e;
         switch (read_event_kind) {
         case REPLAY_ASYNC_EVENT_BH:
         case REPLAY_ASYNC_EVENT_THREAD:
@@ -185,6 +210,29 @@ void replay_read_events(int opt)
                 read_id = replay_get_qword();
             }
             break;
+        case REPLAY_ASYNC_EVENT_INPUT:
+            e.event_kind = read_event_kind;
+            e.opaque = replay_read_input_event();
+
+            replay_run_event(&e);
+
+            replay_has_unread_data = 0;
+            read_event_kind = -1;
+            read_opt = -1;
+            replay_fetch_data_kind();
+            /* continue with the next event */
+            continue;
+        case REPLAY_ASYNC_EVENT_INPUT_SYNC:
+            e.event_kind = read_event_kind;
+            e.opaque = 0;
+            replay_run_event(&e);
+
+            replay_has_unread_data = 0;
+            read_event_kind = -1;
+            read_opt = -1;
+            replay_fetch_data_kind();
+            /* continue with the next event */
+            continue;
         default:
             fprintf(stderr, "Unknown ID %d of replay event\n", read_event_kind);
             exit(1);
diff --git a/replay/replay-input.c b/replay/replay-input.c
new file mode 100755
index 0000000..f5d1482
--- /dev/null
+++ b/replay/replay-input.c
@@ -0,0 +1,108 @@
+/*
+ * replay-input.c
+ *
+ * Copyright (c) 2010-2014 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-common.h"
+#include "replay.h"
+#include "replay-internal.h"
+#include "ui/input.h"
+
+void replay_save_input_event(InputEvent *evt)
+{
+    replay_put_dword(evt->kind);
+
+    switch (evt->kind) {
+    case INPUT_EVENT_KIND_KEY:
+        replay_put_dword(evt->key->key->kind);
+
+        switch (evt->key->key->kind) {
+        case KEY_VALUE_KIND_NUMBER:
+            replay_put_qword(evt->key->key->number);
+            replay_put_byte(evt->key->down);
+            break;
+        case KEY_VALUE_KIND_QCODE:
+            replay_put_dword(evt->key->key->qcode);
+            replay_put_byte(evt->key->down);
+            break;
+        case KEY_VALUE_KIND_MAX:
+            /* keep gcc happy */
+            break;
+        }
+        break;
+    case INPUT_EVENT_KIND_BTN:
+        replay_put_dword(evt->btn->button);
+        replay_put_byte(evt->btn->down);
+        break;
+    case INPUT_EVENT_KIND_REL:
+        replay_put_dword(evt->rel->axis);
+        replay_put_qword(evt->rel->value);
+        break;
+    case INPUT_EVENT_KIND_ABS:
+        replay_put_dword(evt->abs->axis);
+        replay_put_qword(evt->abs->value);
+        break;
+    case INPUT_EVENT_KIND_MAX:
+        /* keep gcc happy */
+        break;
+    }
+}
+
+InputEvent *replay_read_input_event(void)
+{
+    static InputEvent evt;
+    static KeyValue keyValue;
+    static InputKeyEvent key;
+    key.key = &keyValue;
+    static InputBtnEvent btn;
+    static InputMoveEvent rel;
+    static InputMoveEvent abs;
+
+    evt.kind = replay_get_dword();
+    switch (evt.kind) {
+    case INPUT_EVENT_KIND_KEY:
+        evt.key = &key;
+        evt.key->key->kind = replay_get_dword();
+
+        switch (evt.key->key->kind) {
+        case KEY_VALUE_KIND_NUMBER:
+            evt.key->key->number = replay_get_qword();
+            evt.key->down = replay_get_byte();
+            break;
+        case KEY_VALUE_KIND_QCODE:
+            evt.key->key->qcode = (QKeyCode)replay_get_dword();
+            evt.key->down = replay_get_byte();
+            break;
+        case KEY_VALUE_KIND_MAX:
+            /* keep gcc happy */
+            break;
+        }
+        break;
+    case INPUT_EVENT_KIND_BTN:
+        evt.btn = &btn;
+        evt.btn->button = (InputButton)replay_get_dword();
+        evt.btn->down = replay_get_byte();
+        break;
+    case INPUT_EVENT_KIND_REL:
+        evt.rel = &rel;
+        evt.rel->axis = (InputAxis)replay_get_dword();
+        evt.rel->value = replay_get_qword();
+        break;
+    case INPUT_EVENT_KIND_ABS:
+        evt.abs = &abs;
+        evt.abs->axis = (InputAxis)replay_get_dword();
+        evt.abs->value = replay_get_qword();
+        break;
+    case INPUT_EVENT_KIND_MAX:
+        /* keep gcc happy */
+        break;
+    }
+
+    return &evt;
+}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 142e09a..ac3ba82 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -41,7 +41,9 @@
 
 #define REPLAY_ASYNC_EVENT_BH          0
 #define REPLAY_ASYNC_EVENT_THREAD      1
-#define REPLAY_ASYNC_COUNT             2
+#define REPLAY_ASYNC_EVENT_INPUT       2
+#define REPLAY_ASYNC_EVENT_INPUT_SYNC  3
+#define REPLAY_ASYNC_COUNT             4
 
 typedef struct ReplayState {
     /*! Cached clock values. */
@@ -120,4 +122,11 @@ void replay_read_events(int opt);
 /*! Adds specified async event to the queue */
 void replay_add_event(int event_id, void *opaque);
 
+/* Input events */
+
+/*! Saves input event to the log */
+void replay_save_input_event(InputEvent *evt);
+/*! Reads input event from the log */
+InputEvent *replay_read_input_event(void);
+
 #endif
diff --git a/replay/replay.h b/replay/replay.h
index 9c40648..f8bf4c7 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -18,6 +18,7 @@
 #include "qapi-types.h"
 
 struct QemuOpts;
+struct InputEvent;
 
 /* replay clock kinds */
 /* rdtsc */
@@ -110,5 +111,9 @@ void replay_disable_events(void);
 void replay_add_bh_event(void *bh, uint64_t id);
 /*! Adds thread event to the queue */
 void replay_add_thread_event(void *pool, void *req, uint64_t id);
+/*! Adds input event to the queue */
+void replay_add_input_event(struct InputEvent *event);
+/*! Adds input sync event to the queue */
+void replay_add_input_sync_event(void);
 
 #endif
diff --git a/ui/input.c b/ui/input.c
index 002831e..4e49fe5 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -5,6 +5,7 @@
 #include "trace.h"
 #include "ui/input.h"
 #include "ui/console.h"
+#include "replay/replay.h"
 
 struct QemuInputHandlerState {
     DeviceState       *dev;
@@ -295,14 +296,10 @@ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
     QTAILQ_INSERT_TAIL(queue, item, node);
 }
 
-void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
+void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt)
 {
     QemuInputHandlerState *s;
 
-    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
-        return;
-    }
-
     qemu_input_event_trace(src, evt);
 
     /* pre processing */
@@ -319,14 +316,25 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
     s->events++;
 }
 
-void qemu_input_event_sync(void)
+void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
 {
-    QemuInputHandlerState *s;
-
     if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
 
+    if (replay_mode == REPLAY_MODE_PLAY) {
+        /* Nothing */
+    } else if (replay_mode == REPLAY_MODE_RECORD) {
+        replay_add_input_event(evt);
+    } else {
+        qemu_input_event_send_impl(src, evt);
+    }
+}
+
+void qemu_input_event_sync_impl(void)
+{
+    QemuInputHandlerState *s;
+
     trace_input_event_sync();
 
     QTAILQ_FOREACH(s, &handlers, node) {
@@ -340,6 +348,21 @@ void qemu_input_event_sync(void)
     }
 }
 
+void qemu_input_event_sync(void)
+{
+    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
+        return;
+    }
+
+    if (replay_mode == REPLAY_MODE_PLAY) {
+        /* Nothing */
+    } else if (replay_mode == REPLAY_MODE_RECORD) {
+        replay_add_input_sync_event();
+    } else {
+        qemu_input_event_sync_impl();
+    }
+}
+
 InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
 {
     InputEvent *evt = g_new0(InputEvent, 1);
@@ -353,14 +376,23 @@ InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
 void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
 {
     InputEvent *evt;
-    evt = qemu_input_event_new_key(key, down);
-    if (QTAILQ_EMPTY(&kbd_queue)) {
-        qemu_input_event_send(src, evt);
-        qemu_input_event_sync();
-        qapi_free_InputEvent(evt);
-    } else {
-        qemu_input_queue_event(&kbd_queue, src, evt);
-        qemu_input_queue_sync(&kbd_queue);
+    if (replay_mode != REPLAY_MODE_PLAY) {
+        evt = qemu_input_event_new_key(key, down);
+        if (QTAILQ_EMPTY(&kbd_queue)) {
+            qemu_input_event_send(src, evt);
+            qemu_input_event_sync();
+            if (replay_mode != REPLAY_MODE_RECORD) {
+                qapi_free_InputEvent(evt);
+            }
+        } else {
+            if (replay_mode != REPLAY_MODE_NONE) {
+                fprintf(stderr, "Input queue is not supported "
+                                "in record/replay mode\n");
+                exit(1);
+            }
+            qemu_input_queue_event(&kbd_queue, src, evt);
+            qemu_input_queue_sync(&kbd_queue);
+        }
     }
 }
 
@@ -386,6 +418,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
         kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
                                  &kbd_queue);
     }
+    if (replay_mode != REPLAY_MODE_NONE) {
+        fprintf(stderr, "Input queue is not supported in record/replay mode\n");
+        exit(1);
+    }
     qemu_input_queue_delay(&kbd_queue, kbd_timer,
                            delay_ms ? delay_ms : kbd_default_delay_ms);
 }
@@ -405,7 +441,9 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down)
     InputEvent *evt;
     evt = qemu_input_event_new_btn(btn, down);
     qemu_input_event_send(src, evt);
-    qapi_free_InputEvent(evt);
+    if (replay_mode != REPLAY_MODE_RECORD) {
+        qapi_free_InputEvent(evt);
+    }
 }
 
 void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
@@ -458,7 +496,9 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
     InputEvent *evt;
     evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value);
     qemu_input_event_send(src, evt);
-    qapi_free_InputEvent(evt);
+    if (replay_mode != REPLAY_MODE_RECORD) {
+        qapi_free_InputEvent(evt);
+    }
 }
 
 void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
@@ -467,7 +507,9 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
     int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
     evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
     qemu_input_event_send(src, evt);
-    qapi_free_InputEvent(evt);
+    if (replay_mode != REPLAY_MODE_RECORD) {
+        qapi_free_InputEvent(evt);
+    }
 }
 
 void qemu_input_check_mode_change(void)

  parent reply	other threads:[~2014-11-26 10:41 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-26 10:38 [Qemu-devel] [RFC PATCH v5 00/31] Deterministic replay and reverse execution Pavel Dovgalyuk
2014-11-26 10:38 ` [Qemu-devel] [RFC PATCH v5 01/31] cpu-exec: fix cpu_exec_nocache Pavel Dovgalyuk
2014-11-26 10:38 ` [Qemu-devel] [RFC PATCH v5 02/31] acpi: accurate overflow check Pavel Dovgalyuk
2014-11-26 13:15   ` Paolo Bonzini
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 03/31] replay: global variables and function stubs Pavel Dovgalyuk
2014-11-26 15:32   ` Eric Blake
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 04/31] sysemu: system functions for replay Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 05/31] replay: internal functions for replay log Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 06/31] cpu-exec: reset exception_index correctly Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 07/31] icount: implement icount requesting Pavel Dovgalyuk
2014-12-03 10:17   ` Paolo Bonzini
2014-12-04 11:02     ` Pavel Dovgaluk
2014-12-04 15:50       ` Paolo Bonzini
2014-12-05  5:34         ` Pavel Dovgaluk
2014-12-05 10:36           ` Paolo Bonzini
2014-12-05 10:55             ` Pavel Dovgaluk
2014-12-05 11:43               ` Paolo Bonzini
2014-12-05 12:59                 ` Pavel Dovgaluk
     [not found]                 ` <12880.8243353435$1417784373@news.gmane.org>
2014-12-05 15:13                   ` Paolo Bonzini
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 08/31] icount: improve enable/disable ticks Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 09/31] replay: introduce icount event Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 10/31] i386: do not cross the pages boundaries in replay mode Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 11/31] From 7abf2f72777958d395cfd01d97fe707cc06152b5 Mon Sep 17 00:00:00 2001 Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 12/31] From 185a3a47d08857a66332ae862b372a153ce92bb9 " Pavel Dovgalyuk
2014-11-26 10:39 ` [Qemu-devel] [RFC PATCH v5 13/31] From a0cb9e80ba0de409b5ad556109a1c71ce4d8ce19 " Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 14/31] From 04bbd21134dd2c6b7309a7f5f2b780aae2757003 " Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 15/31] cpu-exec: allow temporary disabling icount Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 16/31] cpu-exec: invalidate nocache translation if they are interrupted Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 17/31] replay: interrupts and exceptions Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 18/31] replay: asynchronous events infrastructure Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 19/31] cpu: replay instructions sequence Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 20/31] replay: recording and replaying clock ticks Pavel Dovgalyuk
2014-11-26 10:52   ` Paolo Bonzini
2014-11-26 12:22     ` Pavel Dovgaluk
2014-11-26 12:51       ` Paolo Bonzini
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 21/31] replay: recording and replaying different timers Pavel Dovgalyuk
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 22/31] timer: introduce new QEMU_CLOCK_VIRTUAL_RT clock Pavel Dovgalyuk
2014-11-26 11:04   ` Paolo Bonzini
2014-11-26 12:27     ` Pavel Dovgaluk
2014-11-27  9:11     ` Pavel Dovgaluk
2014-11-27 16:53       ` Paolo Bonzini
2014-11-28  7:52         ` Pavel Dovgaluk
2014-11-28 11:28     ` Pavel Dovgaluk
2014-11-28 12:40       ` Paolo Bonzini
2014-11-26 10:40 ` [Qemu-devel] [RFC PATCH v5 23/31] cpus: make icount warp deterministic in replay mode Pavel Dovgalyuk
2014-11-26 11:26   ` Paolo Bonzini
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 24/31] replay: shutdown event Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 25/31] replay: checkpoints Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 26/31] replay: bottom halves Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 27/31] replay: replay aio requests Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 28/31] replay: thread pool Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 29/31] replay: initialization and deinitialization Pavel Dovgalyuk
2014-11-26 10:41 ` [Qemu-devel] [RFC PATCH v5 30/31] replay: command line options Pavel Dovgalyuk
2014-11-26 10:41 ` Pavel Dovgalyuk [this message]
2014-11-26 10:47 ` [Qemu-devel] [RFC PATCH v5 00/31] Deterministic replay and reverse execution Pavel Dovgaluk
2014-11-26 13:26 ` Paolo Bonzini
     [not found] ` <5475b20f.841f8c0a.8e72.ffffa4f6SMTPIN_ADDED_BROKEN@mx.google.com>
2014-11-27  9:53   ` Artyom Tarasenko
2014-11-27 17:45     ` Paolo Bonzini
2014-11-28  9:39       ` Artyom Tarasenko
2014-11-28  7:51     ` Pavel Dovgaluk

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=20141126104140.7772.71216.stgit@PASHA-ISP \
    --to=pavel.dovgaluk@ispras.ru \
    --cc=afaerber@suse.de \
    --cc=alex.bennee@linaro.org \
    --cc=batuzovk@ispras.ru \
    --cc=fred.konrad@greensocs.com \
    --cc=maria.klimushenkova@ispras.ru \
    --cc=mark.burton@greensocs.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=real@ispras.ru \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.