All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes
@ 2019-07-25  8:44 Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 1/8] replay: add missing fix for internal function Pavel Dovgalyuk
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

The set of patches include the latest fixes for record/replay icount function:
 - fix for icount for the case when translation blocks are chained
 - development documentation update
 - some refactoring

v2 changes (suggested by Paolo Bonzini):
 - allow fixed qemu_clock_deadline_ns_all to be used with any timers
 - clean up can_do_io at the start of every TB
 - remove unnecessary gen_io_end calls due to the previous change

---

Pavel Dovgalyuk (7):
      replay: document development rules
      util/qemu-timer: refactor deadline calculation for external timers
      replay: fix replay shutdown
      replay: refine replay-time module
      replay: rename step-related variables and functions
      icount: clean up cpu_can_io at the entry to the block
      icount: remove unnecessary gen_io_end calls

pbonzini@redhat.com (1):
      replay: add missing fix for internal function


 accel/tcg/cpu-exec.c                    |    1 -
 accel/tcg/translator.c                  |    2 +
 cpus.c                                  |   17 ++++++++---
 docs/devel/replay.txt                   |   46 +++++++++++++++++++++++++++++++
 include/exec/gen-icount.h               |   38 +++++++++++++-------------
 include/qemu/timer.h                    |    8 ++++-
 include/sysemu/replay.h                 |    2 +
 qtest.c                                 |    3 +-
 replay/replay-events.c                  |    2 +
 replay/replay-internal.c                |   10 +++----
 replay/replay-internal.h                |   10 +++----
 replay/replay-snapshot.c                |    6 ++--
 replay/replay-time.c                    |   36 +++++++++++-------------
 replay/replay.c                         |   30 ++++++++++----------
 target/alpha/translate.c                |    4 +--
 target/arm/translate-a64.c              |    6 +---
 target/arm/translate.c                  |   10 ++-----
 target/cris/translate.c                 |    4 +--
 target/hppa/translate.c                 |    2 +
 target/i386/translate.c                 |   18 +++++-------
 target/lm32/translate.c                 |   12 ++------
 target/microblaze/translate.c           |    4 +--
 target/mips/translate.c                 |   16 +++--------
 target/nios2/translate.c                |    4 +--
 target/ppc/translate.c                  |   18 +++---------
 target/ppc/translate_init.inc.c         |    4 +--
 target/riscv/insn_trans/trans_rvi.inc.c |    2 +
 target/sparc/translate.c                |   32 +++++++++++-----------
 target/unicore32/translate.c            |    2 +
 target/xtensa/translate.c               |   20 +++----------
 tests/ptimer-test-stubs.c               |    4 +--
 tests/ptimer-test.c                     |    6 +++-
 util/qemu-timer.c                       |   30 ++++++++++++++++++--
 33 files changed, 225 insertions(+), 184 deletions(-)
 create mode 100644 docs/devel/replay.txt

-- 
Pavel Dovgalyuk


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 1/8] replay: add missing fix for internal function
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 2/8] replay: document development rules Pavel Dovgalyuk
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: pbonzini@redhat.com <pbonzini@redhat.com>

This is a fix which was missed by patch
74c0b816adfc6aa1b01b4426fdf385e32e35cbac, which added current_step
parameter to the replay_advance_current_step function.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
 replay/replay-internal.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 9e41ed1dcf..979f3a0b39 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -228,7 +228,7 @@ void replay_mutex_unlock(void)
 
 void replay_advance_current_step(uint64_t current_step)
 {
-    int diff = (int)(replay_get_current_step() - replay_state.current_step);
+    int diff = (int)(current_step - replay_state.current_step);
 
     /* Time can only go forward */
     assert(diff >= 0);



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 2/8] replay: document development rules
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 1/8] replay: add missing fix for internal function Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 3/8] util/qemu-timer: refactor deadline calculation for external timers Pavel Dovgalyuk
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

This patch introduces docs/devel/replay.txt which describes the rules
that should be followed to make virtual devices usable in record/replay mode.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgauk@ispras.ru>

--

v9: fixed external virtual clock description (reported by Artem Pisarenko)
---
 docs/devel/replay.txt |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 docs/devel/replay.txt

diff --git a/docs/devel/replay.txt b/docs/devel/replay.txt
new file mode 100644
index 0000000000..e641c35add
--- /dev/null
+++ b/docs/devel/replay.txt
@@ -0,0 +1,46 @@
+Record/replay mechanism, that could be enabled through icount mode, expects
+the virtual devices to satisfy the following requirements.
+
+The main idea behind this document is that everything that affects
+the guest state during execution in icount mode should be deterministic.
+
+Timers
+======
+
+All virtual devices should use virtual clock for timers that change the guest
+state. Virtual clock is deterministic, therefore such timers are deterministic
+too.
+
+Virtual devices can also use realtime clock for the events that do not change
+the guest state directly. When the clock ticking should depend on VM execution
+speed, use virtual clock with EXTERNAL attribute. It is not deterministic,
+but its speed depends on the guest execution. This clock is used by
+the virtual devices (e.g., slirp routing device) that lie outside the
+replayed guest.
+
+Bottom halves
+=============
+
+Bottom half callbacks, that affect the guest state, should be invoked through
+replay_bh_schedule_event or replay_bh_schedule_oneshot_event functions.
+Their invocations are saved in record mode and synchronized with the existing
+log in replay mode.
+
+Saving/restoring the VM state
+=============================
+
+All fields in the device state structure (including virtual timers)
+should be restored by loadvm to the same values they had before savevm.
+
+Avoid accessing other devices' state, because the order of saving/restoring
+is not defined. It means that you should not call functions like
+'update_irq' in post_load callback. Save everything explicitly to avoid
+the dependencies that may make restoring the VM state non-deterministic.
+
+Stopping the VM
+===============
+
+Stopping the guest should not interfere with its state (with the exception
+of the network connections, that could be broken by the remote timeouts).
+VM can be stopped at any moment of replay by the user. Restarting the VM
+after that stop should not break the replay by the unneeded guest state change.



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 3/8] util/qemu-timer: refactor deadline calculation for external timers
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 1/8] replay: add missing fix for internal function Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 2/8] replay: document development rules Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 4/8] replay: fix replay shutdown Pavel Dovgalyuk
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

icount-based record/replay uses qemu_clock_deadline_ns_all to measure
the period until vCPU may be interrupted.
This function takes in account the virtual timers, because they belong
to the virtual devices that may generate interrupt request or affect
the virtual machine state.
However, there are a subset of virtual timers, that are marked with
'external' flag. These do not change the virtual machine state and
only based on virtual clock. Calculating the deadling using the external
timers breaks the determinism, because they do not belong to the replayed
part of the virtual machine.
This patch fixes the deadline calculation for this case by adding
new parameter for skipping the external timers when it is needed.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

--

v2 changes:
 - added new parameter for timer attribute mask
---
 cpus.c                    |   17 ++++++++++++-----
 include/qemu/timer.h      |    8 ++++++--
 qtest.c                   |    3 ++-
 tests/ptimer-test-stubs.c |    4 ++--
 tests/ptimer-test.c       |    6 ++++--
 util/qemu-timer.c         |   30 +++++++++++++++++++++++++++---
 6 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/cpus.c b/cpus.c
index 927a00aa90..a7120ffbd5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -553,7 +553,8 @@ void qtest_clock_warp(int64_t dest)
     assert(qtest_enabled());
     aio_context = qemu_get_aio_context();
     while (clock < dest) {
-        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                                      QEMU_TIMER_ATTR_ALL);
         int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
 
         seqlock_write_lock(&timers_state.vm_clock_seqlock,
@@ -613,7 +614,8 @@ void qemu_start_warp_timer(void)
 
     /* We want to use the earliest deadline from ALL vm_clocks */
     clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
-    deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+    deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                          ~QEMU_TIMER_ATTR_EXTERNAL);
     if (deadline < 0) {
         static bool notified;
         if (!icount_sleep && !notified) {
@@ -1349,7 +1351,12 @@ static int64_t tcg_get_icount_limit(void)
     int64_t deadline;
 
     if (replay_mode != REPLAY_MODE_PLAY) {
-        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+        /*
+         * Include all the timers, because they may need an attention.
+         * Too long CPU execution may create unnecessary delay in UI.
+         */
+        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                              QEMU_TIMER_ATTR_ALL);
 
         /* Maintain prior (possibly buggy) behaviour where if no deadline
          * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
@@ -1370,8 +1377,8 @@ static void handle_icount_deadline(void)
 {
     assert(qemu_in_vcpu_thread());
     if (use_icount) {
-        int64_t deadline =
-            qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                                      QEMU_TIMER_ATTR_ALL);
 
         if (deadline == 0) {
             /* Wake up other AioContexts.  */
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 5d978e1634..d7e378c8af 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -62,13 +62,15 @@ typedef enum {
  * The following attributes are available:
  *
  * QEMU_TIMER_ATTR_EXTERNAL: drives external subsystem
+ * QEMU_TIMER_ATTR_ALL: mask for all existing attributes
  *
  * Timers with this attribute do not recorded in rr mode, therefore it could be
  * used for the subsystems that operate outside the guest core. Applicable only
  * with virtual clock type.
  */
 
-#define QEMU_TIMER_ATTR_EXTERNAL BIT(0)
+#define QEMU_TIMER_ATTR_EXTERNAL ((int)BIT(0))
+#define QEMU_TIMER_ATTR_ALL      0xffffffff
 
 typedef struct QEMUTimerList QEMUTimerList;
 
@@ -177,6 +179,8 @@ bool qemu_clock_use_for_deadline(QEMUClockType type);
 /**
  * qemu_clock_deadline_ns_all:
  * @type: the clock type
+ * @attr_mask: mask for the timer attributes that are included
+ *             in deadline calculation
  *
  * Calculate the deadline across all timer lists associated
  * with a clock (as opposed to just the default one)
@@ -184,7 +188,7 @@ bool qemu_clock_use_for_deadline(QEMUClockType type);
  *
  * Returns: time until expiry in nanoseconds or -1
  */
-int64_t qemu_clock_deadline_ns_all(QEMUClockType type);
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask);
 
 /**
  * qemu_clock_get_main_loop_timerlist:
diff --git a/qtest.c b/qtest.c
index 15e27e911f..4e208562ac 100644
--- a/qtest.c
+++ b/qtest.c
@@ -655,7 +655,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
             int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
             g_assert(ret == 0);
         } else {
-            ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+            ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                            QEMU_TIMER_ATTR_ALL);
         }
         qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
         qtest_send_prefix(chr);
diff --git a/tests/ptimer-test-stubs.c b/tests/ptimer-test-stubs.c
index 54b3fd26f6..ed393d9082 100644
--- a/tests/ptimer-test-stubs.c
+++ b/tests/ptimer-test-stubs.c
@@ -88,9 +88,9 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
     return ptimer_test_time_ns;
 }
 
-int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
 {
-    QEMUTimerList *timer_list = main_loop_tlg.tl[type];
+    QEMUTimerList *timer_list = main_loop_tlg.tl[QEMU_CLOCK_VIRTUAL];
     QEMUTimer *t = timer_list->active_timers.next;
     int64_t deadline = -1;
 
diff --git a/tests/ptimer-test.c b/tests/ptimer-test.c
index b30aad0737..5b20e91599 100644
--- a/tests/ptimer-test.c
+++ b/tests/ptimer-test.c
@@ -50,13 +50,15 @@ static void ptimer_test_set_qemu_time_ns(int64_t ns)
 
 static void qemu_clock_step(uint64_t ns)
 {
-    int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+    int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                                  QEMU_TIMER_ATTR_ALL);
     int64_t advanced_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns;
 
     while (deadline != -1 && deadline <= advanced_time) {
         ptimer_test_set_qemu_time_ns(deadline);
         ptimer_test_expire_qemu_timers(deadline, QEMU_CLOCK_VIRTUAL);
-        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+                                              QEMU_TIMER_ATTR_ALL);
     }
 
     ptimer_test_set_qemu_time_ns(advanced_time);
diff --git a/util/qemu-timer.c b/util/qemu-timer.c
index 1cc1b2f2c3..4b16ea3517 100644
--- a/util/qemu-timer.c
+++ b/util/qemu-timer.c
@@ -253,14 +253,38 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
  * ignore whether or not the clock should be used in deadline
  * calculations.
  */
-int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
 {
     int64_t deadline = -1;
+    int64_t delta;
+    int64_t expire_time;
+    QEMUTimer *ts;
     QEMUTimerList *timer_list;
     QEMUClock *clock = qemu_clock_ptr(type);
+
+    if (!clock->enabled) {
+        return -1;
+    }
+
     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
-        deadline = qemu_soonest_timeout(deadline,
-                                        timerlist_deadline_ns(timer_list));
+        qemu_mutex_lock(&timer_list->active_timers_lock);
+        ts = timer_list->active_timers;
+        /* Skip all external timers */
+        while (ts && (ts->attributes & ~attr_mask)) {
+            ts = ts->next;
+        }
+        if (!ts) {
+            qemu_mutex_unlock(&timer_list->active_timers_lock);
+            continue;
+        }
+        expire_time = ts->expire_time;
+        qemu_mutex_unlock(&timer_list->active_timers_lock);
+
+        delta = expire_time - qemu_clock_get_ns(type);
+        if (delta <= 0) {
+            delta = 0;
+        }
+        deadline = qemu_soonest_timeout(deadline, delta);
     }
     return deadline;
 }



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 4/8] replay: fix replay shutdown
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
                   ` (2 preceding siblings ...)
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 3/8] util/qemu-timer: refactor deadline calculation for external timers Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 5/8] replay: refine replay-time module Pavel Dovgalyuk
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

This patch fixes shutdown of the replay process, which is terminated with
the assert when shutdown event is read from the log.
replay_finish_event reads new data_kind and therefore the value of data_kind
should be preserved to be valid at qemu_system_shutdown_request call.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
 replay/replay.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/replay/replay.c b/replay/replay.c
index 8b172b2d1b..8d77a4ca4c 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -45,14 +45,14 @@ bool replay_next_event_is(int event)
     }
 
     while (true) {
-        if (event == replay_state.data_kind) {
+        unsigned int data_kind = replay_state.data_kind;
+        if (event == data_kind) {
             res = true;
         }
-        switch (replay_state.data_kind) {
+        switch (data_kind) {
         case EVENT_SHUTDOWN ... EVENT_SHUTDOWN_LAST:
             replay_finish_event();
-            qemu_system_shutdown_request(replay_state.data_kind -
-                                         EVENT_SHUTDOWN);
+            qemu_system_shutdown_request(data_kind - EVENT_SHUTDOWN);
             break;
         default:
             /* clock, time_t, checkpoint and other events */



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 5/8] replay: refine replay-time module
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
                   ` (3 preceding siblings ...)
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 4/8] replay: fix replay shutdown Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 6/8] replay: rename step-related variables and functions Pavel Dovgalyuk
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

This patch removes refactoring artifacts from the replay/replay-time.c

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
 replay/replay-time.c |   36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/replay/replay-time.c b/replay/replay-time.c
index 5154cb0ce9..49c9e5d8b2 100644
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -14,18 +14,19 @@
 #include "replay-internal.h"
 #include "qemu/error-report.h"
 
-int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, int64_t raw_icount)
+int64_t replay_save_clock(ReplayClockKind kind, int64_t clock,
+                          int64_t raw_icount)
 {
-    if (replay_file) {
-        g_assert(replay_mutex_locked());
+    g_assert(replay_file);
+    g_assert(replay_mutex_locked());
 
-        /* Due to the caller's locking requirements we get the icount from it
-         * instead of using replay_save_instructions().
-         */
-        replay_advance_current_step(raw_icount);
-        replay_put_event(EVENT_CLOCK + kind);
-        replay_put_qword(clock);
-    }
+    /*
+     * Due to the caller's locking requirements we get the icount from it
+     * instead of using replay_save_instructions().
+     */
+    replay_advance_current_step(raw_icount);
+    replay_put_event(EVENT_CLOCK + kind);
+    replay_put_qword(clock);
 
     return clock;
 }
@@ -47,20 +48,15 @@ void replay_read_next_clock(ReplayClockKind kind)
 /*! Reads next clock event from the input. */
 int64_t replay_read_clock(ReplayClockKind kind)
 {
+    int64_t ret;
     g_assert(replay_file && replay_mutex_locked());
 
     replay_account_executed_instructions();
 
-    if (replay_file) {
-        int64_t ret;
-        if (replay_next_event_is(EVENT_CLOCK + kind)) {
-            replay_read_next_clock(kind);
-        }
-        ret = replay_state.cached_clock[kind];
-
-        return ret;
+    if (replay_next_event_is(EVENT_CLOCK + kind)) {
+        replay_read_next_clock(kind);
     }
+    ret = replay_state.cached_clock[kind];
 
-    error_report("REPLAY INTERNAL ERROR %d", __LINE__);
-    exit(1);
+    return ret;
 }



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 6/8] replay: rename step-related variables and functions
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
                   ` (4 preceding siblings ...)
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 5/8] replay: refine replay-time module Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 7/8] icount: clean up cpu_can_io at the entry to the block Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls Pavel Dovgalyuk
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

This patch renames replay_get_current_step() and related variables
to make these names consistent with existing 'icount' command line
option and future record/replay hmp/qmp commands.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
 include/sysemu/replay.h  |    2 +-
 replay/replay-events.c   |    2 +-
 replay/replay-internal.c |   10 +++++-----
 replay/replay-internal.h |   10 +++++-----
 replay/replay-snapshot.c |    6 +++---
 replay/replay-time.c     |    2 +-
 replay/replay.c          |   22 +++++++++++-----------
 7 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 3a7c58e423..28ce19e919 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -75,7 +75,7 @@ void replay_add_blocker(Error *reason);
 /* Processing the instructions */
 
 /*! Returns number of executed instructions. */
-uint64_t replay_get_current_step(void);
+uint64_t replay_get_current_icount(void);
 /*! Returns number of instructions to execute in replay mode. */
 int replay_get_instructions(void);
 /*! Updates instructions counter in replay mode. */
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 60d17f6edb..008e80f636 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -124,7 +124,7 @@ void replay_add_event(ReplayAsyncEventKind event_kind,
 void replay_bh_schedule_event(QEMUBH *bh)
 {
     if (events_enabled) {
-        uint64_t id = replay_get_current_step();
+        uint64_t id = replay_get_current_icount();
         replay_add_event(REPLAY_ASYNC_EVENT_BH, bh, NULL, id);
     } else {
         qemu_bh_schedule(bh);
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 979f3a0b39..ac6c9017fc 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -172,7 +172,7 @@ void replay_fetch_data_kind(void)
         if (!replay_state.has_unread_data) {
             replay_state.data_kind = replay_get_byte();
             if (replay_state.data_kind == EVENT_INSTRUCTION) {
-                replay_state.instructions_count = replay_get_dword();
+                replay_state.instruction_count = replay_get_dword();
             }
             replay_check_error();
             replay_state.has_unread_data = 1;
@@ -226,9 +226,9 @@ void replay_mutex_unlock(void)
     }
 }
 
-void replay_advance_current_step(uint64_t current_step)
+void replay_advance_current_icount(uint64_t current_icount)
 {
-    int diff = (int)(current_step - replay_state.current_step);
+    int diff = (int)(current_icount - replay_state.current_icount);
 
     /* Time can only go forward */
     assert(diff >= 0);
@@ -236,7 +236,7 @@ void replay_advance_current_step(uint64_t current_step)
     if (diff > 0) {
         replay_put_event(EVENT_INSTRUCTION);
         replay_put_dword(diff);
-        replay_state.current_step += diff;
+        replay_state.current_icount += diff;
     }
 }
 
@@ -245,6 +245,6 @@ void replay_save_instructions(void)
 {
     if (replay_file && replay_mode == REPLAY_MODE_RECORD) {
         g_assert(replay_mutex_locked());
-        replay_advance_current_step(replay_get_current_step());
+        replay_advance_current_icount(replay_get_current_icount());
     }
 }
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index af6f4d55d4..afba9a3e0c 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -64,10 +64,10 @@ typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;
 typedef struct ReplayState {
     /*! Cached clock values. */
     int64_t cached_clock[REPLAY_CLOCK_COUNT];
-    /*! Current step - number of processed instructions and timer events. */
-    uint64_t current_step;
+    /*! Current icount - number of processed instructions. */
+    uint64_t current_icount;
     /*! Number of instructions to be executed before other events happen. */
-    int instructions_count;
+    int instruction_count;
     /*! Type of the currently executed event. */
     unsigned int data_kind;
     /*! Flag which indicates that event is not processed yet. */
@@ -122,8 +122,8 @@ void replay_finish_event(void);
     data_kind variable. */
 void replay_fetch_data_kind(void);
 
-/*! Advance replay_state.current_step to the specified value. */
-void replay_advance_current_step(uint64_t current_step);
+/*! Advance replay_state.current_icount to the specified value. */
+void replay_advance_current_icount(uint64_t current_icount);
 /*! Saves queued events (like instructions and sound). */
 void replay_save_instructions(void);
 
diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
index 756f48bc02..97d026af30 100644
--- a/replay/replay-snapshot.c
+++ b/replay/replay-snapshot.c
@@ -41,7 +41,7 @@ static int replay_post_load(void *opaque, int version_id)
     } else if (replay_mode == REPLAY_MODE_RECORD) {
         /* This is only useful for loading the initial state.
            Therefore reset all the counters. */
-        state->instructions_count = 0;
+        state->instruction_count = 0;
         state->block_request_id = 0;
     }
 
@@ -56,8 +56,8 @@ static const VMStateDescription vmstate_replay = {
     .post_load = replay_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_INT64_ARRAY(cached_clock, ReplayState, REPLAY_CLOCK_COUNT),
-        VMSTATE_UINT64(current_step, ReplayState),
-        VMSTATE_INT32(instructions_count, ReplayState),
+        VMSTATE_UINT64(current_icount, ReplayState),
+        VMSTATE_INT32(instruction_count, ReplayState),
         VMSTATE_UINT32(data_kind, ReplayState),
         VMSTATE_UINT32(has_unread_data, ReplayState),
         VMSTATE_UINT64(file_offset, ReplayState),
diff --git a/replay/replay-time.c b/replay/replay-time.c
index 49c9e5d8b2..43357c9f24 100644
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -24,7 +24,7 @@ int64_t replay_save_clock(ReplayClockKind kind, int64_t clock,
      * Due to the caller's locking requirements we get the icount from it
      * instead of using replay_save_instructions().
      */
-    replay_advance_current_step(raw_icount);
+    replay_advance_current_icount(raw_icount);
     replay_put_event(EVENT_CLOCK + kind);
     replay_put_qword(clock);
 
diff --git a/replay/replay.c b/replay/replay.c
index 8d77a4ca4c..6a62ec3811 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -39,7 +39,7 @@ bool replay_next_event_is(int event)
     bool res = false;
 
     /* nothing to skip - not all instructions used */
-    if (replay_state.instructions_count != 0) {
+    if (replay_state.instruction_count != 0) {
         assert(replay_state.data_kind == EVENT_INSTRUCTION);
         return event == EVENT_INSTRUCTION;
     }
@@ -62,7 +62,7 @@ bool replay_next_event_is(int event)
     return res;
 }
 
-uint64_t replay_get_current_step(void)
+uint64_t replay_get_current_icount(void)
 {
     return cpu_get_icount_raw();
 }
@@ -72,7 +72,7 @@ int replay_get_instructions(void)
     int res = 0;
     replay_mutex_lock();
     if (replay_next_event_is(EVENT_INSTRUCTION)) {
-        res = replay_state.instructions_count;
+        res = replay_state.instruction_count;
     }
     replay_mutex_unlock();
     return res;
@@ -82,16 +82,16 @@ void replay_account_executed_instructions(void)
 {
     if (replay_mode == REPLAY_MODE_PLAY) {
         g_assert(replay_mutex_locked());
-        if (replay_state.instructions_count > 0) {
-            int count = (int)(replay_get_current_step()
-                              - replay_state.current_step);
+        if (replay_state.instruction_count > 0) {
+            int count = (int)(replay_get_current_icount()
+                              - replay_state.current_icount);
 
             /* Time can only go forward */
             assert(count >= 0);
 
-            replay_state.instructions_count -= count;
-            replay_state.current_step += count;
-            if (replay_state.instructions_count == 0) {
+            replay_state.instruction_count -= count;
+            replay_state.current_icount += count;
+            if (replay_state.instruction_count == 0) {
                 assert(replay_state.data_kind == EVENT_INSTRUCTION);
                 replay_finish_event();
                 /* Wake up iothread. This is required because
@@ -273,8 +273,8 @@ static void replay_enable(const char *fname, int mode)
     replay_mutex_init();
 
     replay_state.data_kind = -1;
-    replay_state.instructions_count = 0;
-    replay_state.current_step = 0;
+    replay_state.instruction_count = 0;
+    replay_state.current_icount = 0;
     replay_state.has_unread_data = 0;
 
     /* skip file header for RECORD and check it for PLAY */



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 7/8] icount: clean up cpu_can_io at the entry to the block
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
                   ` (5 preceding siblings ...)
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 6/8] replay: rename step-related variables and functions Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls Pavel Dovgalyuk
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

Most of IO instructions can be executed only at the end of the block in
icount mode. Therefore translator can set cpu_can_io flag when translating
the last instruction.
But when the blocks are chained, then this flag is not reset and may
remain set at the beginning of the next block.
This patch resets the flag at the entry of any translation block,
making I/O operations impossible by default.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

--

v2 changes:
 - reset can_do_io at the start of every TB (suggested by Paolo Bonzini)
---
 accel/tcg/cpu-exec.c      |    1 -
 include/exec/gen-icount.h |   38 ++++++++++++++++++++------------------
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 6c85c3ee1e..48272c781b 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -169,7 +169,6 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
     }
 #endif /* DEBUG_DISAS */
 
-    cpu->can_do_io = !use_icount;
     ret = tcg_qemu_tb_exec(env, tb_ptr);
     cpu->can_do_io = 1;
     last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK);
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index f7669b6841..4004e6c9d0 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -7,6 +7,24 @@
 
 static TCGOp *icount_start_insn;
 
+static inline void gen_io_start(void)
+{
+    TCGv_i32 tmp = tcg_const_i32(1);
+    tcg_gen_st_i32(tmp, cpu_env,
+                   offsetof(ArchCPU, parent_obj.can_do_io) -
+                   offsetof(ArchCPU, env));
+    tcg_temp_free_i32(tmp);
+}
+
+static inline void gen_io_end(void)
+{
+    TCGv_i32 tmp = tcg_const_i32(0);
+    tcg_gen_st_i32(tmp, cpu_env,
+                   offsetof(ArchCPU, parent_obj.can_do_io) -
+                   offsetof(ArchCPU, env));
+    tcg_temp_free_i32(tmp);
+}
+
 static inline void gen_tb_start(TranslationBlock *tb)
 {
     TCGv_i32 count, imm;
@@ -40,6 +58,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
         tcg_gen_st16_i32(count, cpu_env,
                          offsetof(ArchCPU, neg.icount_decr.u16.low) -
                          offsetof(ArchCPU, env));
+        /* Disable I/O by default */
+        gen_io_end();
     }
 
     tcg_temp_free_i32(count);
@@ -57,22 +77,4 @@ static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
     tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
 }
 
-static inline void gen_io_start(void)
-{
-    TCGv_i32 tmp = tcg_const_i32(1);
-    tcg_gen_st_i32(tmp, cpu_env,
-                   offsetof(ArchCPU, parent_obj.can_do_io) -
-                   offsetof(ArchCPU, env));
-    tcg_temp_free_i32(tmp);
-}
-
-static inline void gen_io_end(void)
-{
-    TCGv_i32 tmp = tcg_const_i32(0);
-    tcg_gen_st_i32(tmp, cpu_env,
-                   offsetof(ArchCPU, parent_obj.can_do_io) -
-                   offsetof(ArchCPU, env));
-    tcg_temp_free_i32(tmp);
-}
-
 #endif



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls
  2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
                   ` (6 preceding siblings ...)
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 7/8] icount: clean up cpu_can_io at the entry to the block Pavel Dovgalyuk
@ 2019-07-25  8:44 ` Pavel Dovgalyuk
  2019-07-25 11:29   ` Paolo Bonzini
  7 siblings, 1 reply; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25  8:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, pbonzini, quintela,
	ciro.santilli, jasowang, crosthwaite.peter, armbru, mreitz,
	alex.bennee, maria.klimushenkova, mst, kraxel, boost.lists,
	thomas.dullien, dovgaluk, artem.k.pisarenko, dgilbert, rth

Prior patch resets can_do_io flag at the TB entry. Therefore there is no
need in resetting this flag at the end of the block.
This patch removes redundant gen_io_end calls.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
---
 accel/tcg/translator.c                  |    2 +-
 target/alpha/translate.c                |    4 ++--
 target/arm/translate-a64.c              |    6 ++----
 target/arm/translate.c                  |   10 +++-------
 target/cris/translate.c                 |    4 ++--
 target/hppa/translate.c                 |    2 +-
 target/i386/translate.c                 |   18 ++++++++---------
 target/lm32/translate.c                 |   12 +++---------
 target/microblaze/translate.c           |    4 ++--
 target/mips/translate.c                 |   16 +++++-----------
 target/nios2/translate.c                |    4 +---
 target/ppc/translate.c                  |   18 +++++------------
 target/ppc/translate_init.inc.c         |    4 ++--
 target/riscv/insn_trans/trans_rvi.inc.c |    2 +-
 target/sparc/translate.c                |   32 ++++++++++++++++---------------
 target/unicore32/translate.c            |    2 +-
 target/xtensa/translate.c               |   20 +++++--------------
 17 files changed, 60 insertions(+), 100 deletions(-)

diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 9226a348a3..5849cd250c 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -90,7 +90,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
             /* Accept I/O on the last instruction.  */
             gen_io_start();
             ops->translate_insn(db, cpu);
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
         } else {
             ops->translate_insn(db, cpu);
         }
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 2c9cccf6c1..97e7d55b4d 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -1332,7 +1332,7 @@ static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
         if (use_icount) {
             gen_io_start();
             helper(va);
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             return DISAS_PC_STALE;
         } else {
             helper(va);
@@ -2398,7 +2398,7 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
                 gen_io_start();
                 gen_helper_load_pcc(va, cpu_env);
-                gen_io_end();
+                /* No need for gen_io_end at the end of the block */
                 ret = DISAS_PC_STALE;
             } else {
                 gen_helper_load_pcc(va, cpu_env);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d3231477a2..20e4638d5f 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1797,7 +1797,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
 
     if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
         /* I/O operations must end the TB here (whether read or write) */
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
         s->base.is_jmp = DISAS_UPDATE;
     } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
         /* We default to ending the TB on a coprocessor register write,
@@ -2104,9 +2104,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
 
         gen_helper_exception_return(cpu_env, dst);
         tcg_temp_free_i64(dst);
-        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
         /* Must exit loop to check un-masked IRQs */
         s->base.is_jmp = DISAS_EXIT;
         return;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 7853462b21..c17e5a8c04 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3245,9 +3245,7 @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
         gen_io_start();
     }
     gen_helper_cpsr_write_eret(cpu_env, cpsr);
-    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
     tcg_temp_free_i32(cpsr);
     /* Must exit loop to check un-masked IRQs */
     s->base.is_jmp = DISAS_EXIT;
@@ -7338,7 +7336,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
 
         if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
             /* I/O operations must end the TB here (whether read or write) */
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_lookup_tb(s);
         } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
             /* We default to ending the TB on a coprocessor register write,
@@ -9207,9 +9205,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                         gen_io_start();
                     }
                     gen_helper_cpsr_write_eret(cpu_env, tmp);
-                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_io_end();
-                    }
+                    /* No need for gen_io_end at the end of the block */
                     tcg_temp_free_i32(tmp);
                     /* Must exit loop to check un-masked IRQs */
                     s->base.is_jmp = DISAS_EXIT;
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 3429a3b768..eeba534b29 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3225,8 +3225,8 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
 
     npc = dc->pc;
 
-        if (tb_cflags(tb) & CF_LAST_IO)
-            gen_io_end();
+    /* No need for gen_io_end at the end of the block */
+
     /* Force an update if the per-tb cpu state has changed.  */
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || !dc->flagx_known
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 188fe688cb..695a1fdfb0 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2161,7 +2161,7 @@ static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
             gen_helper_read_interval_timer(tmp);
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             ctx->base.is_jmp = DISAS_IAQ_N_STALE;
         } else {
             gen_helper_read_interval_timer(tmp);
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 03150a86e2..b5469142cf 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5381,7 +5381,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_op_mov_reg_v(s, dflag, rm, s->T0);
             set_cc_op(s, CC_OP_EFLAGS);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                gen_io_end();
+                /* No need for gen_io_end at the end of the block */
                 gen_jmp(s, s->pc - s->cs_base);
             }
             break;
@@ -6443,7 +6443,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
         gen_bpt_io(s, s->tmp2_i32, ot);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_jmp(s, s->pc - s->cs_base);
         }
         break;
@@ -6464,7 +6464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
         gen_bpt_io(s, s->tmp2_i32, ot);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_jmp(s, s->pc - s->cs_base);
         }
         break;
@@ -6482,7 +6482,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
         gen_bpt_io(s, s->tmp2_i32, ot);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_jmp(s, s->pc - s->cs_base);
         }
         break;
@@ -6502,7 +6502,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
         gen_bpt_io(s, s->tmp2_i32, ot);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_jmp(s, s->pc - s->cs_base);
         }
         break;
@@ -7206,7 +7206,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         gen_helper_rdtsc(cpu_env);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_jmp(s, s->pc - s->cs_base);
         }
         break;
@@ -7666,7 +7666,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             }
             gen_helper_rdtscp(cpu_env);
             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                gen_io_end();
+                /* No need for gen_io_end at the end of the block */
                 gen_jmp(s, s->pc - s->cs_base);
             }
             break;
@@ -8036,9 +8036,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                     gen_op_mov_v_reg(s, ot, s->T0, rm);
                     gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
                                          s->T0);
-                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_io_end();
-                    }
+                    /* No need for gen_io_end at the end of the block */
                     gen_jmp_im(s, s->pc - s->cs_base);
                     gen_eob(s);
                 } else {
diff --git a/target/lm32/translate.c b/target/lm32/translate.c
index b9f2f2c4a7..d844177ced 100644
--- a/target/lm32/translate.c
+++ b/target/lm32/translate.c
@@ -885,9 +885,7 @@ static void dec_wcsr(DisasContext *dc)
         }
         gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
-        if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
         dc->is_jmp = DISAS_UPDATE;
         break;
     case CSR_IP:
@@ -897,9 +895,7 @@ static void dec_wcsr(DisasContext *dc)
         }
         gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
-        if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
         dc->is_jmp = DISAS_UPDATE;
         break;
     case CSR_ICC:
@@ -1111,9 +1107,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
          && (dc->pc - page_start < TARGET_PAGE_SIZE)
          && num_insns < max_insns);
 
-    if (tb_cflags(tb) & CF_LAST_IO) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 
     if (unlikely(cs->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 9ce65f3bcf..ac4ee375f2 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1724,8 +1724,8 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
             npc = dc->jmp_pc;
     }
 
-    if (tb_cflags(tb) & CF_LAST_IO)
-        gen_io_end();
+    /* No need for gen_io_end at the end of the block */
+
     /* Force an update if the per-tb cpu state has changed.  */
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
diff --git a/target/mips/translate.c b/target/mips/translate.c
index ca628002ae..e6c0ee68b7 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -7126,9 +7126,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
                 gen_io_start();
             }
             gen_helper_mfc0_count(arg, cpu_env);
-            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-                gen_io_end();
-            }
+            /* No need for gen_io_end at the end of the block */
             /*
              * Break the TB to be able to take timer interrupts immediately
              * after reading count. DISAS_STOP isn't sufficient, we need to
@@ -8293,7 +8291,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 
     /* For simplicity assume that all writes can cause interrupts.  */
     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
         /*
          * DISAS_STOP isn't sufficient, we need to ensure we break out of
          * translated code to check for pending interrupts.
@@ -8604,9 +8602,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
                 gen_io_start();
             }
             gen_helper_mfc0_count(arg, cpu_env);
-            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-                gen_io_end();
-            }
+            /* No need for gen_io_end at the end of the block */
             /*
              * Break the TB to be able to take timer interrupts immediately
              * after reading count. DISAS_STOP isn't sufficient, we need to
@@ -9745,7 +9741,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 
     /* For simplicity assume that all writes can cause interrupts.  */
     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
         /*
          * DISAS_STOP isn't sufficient, we need to ensure we break out of
          * translated code to check for pending interrupts.
@@ -12810,9 +12806,7 @@ static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
             gen_io_start();
         }
         gen_helper_rdhwr_cc(t0, cpu_env);
-        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
         gen_store_gpr(t0, rt);
         /*
          * Break the TB to be able to take timer interrupts immediately
diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index 17d8f1877c..9798184468 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -862,9 +862,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
              !tcg_op_buf_full() &&
              num_insns < max_insns);
 
-    if (tb_cflags(tb) & CF_LAST_IO) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 
     /* Indicate where the next block should start */
     switch (dc->is_jmp) {
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 4a5de28036..fce3243f10 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1860,7 +1860,7 @@ static void gen_darn(DisasContext *ctx)
             gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
         }
         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
+            /* No need for gen_io_end at the end of the block */
             gen_stop_exception(ctx);
         }
     }
@@ -3990,9 +3990,7 @@ static void gen_rfi(DisasContext *ctx)
     gen_update_cfar(ctx, ctx->base.pc_next - 4);
     gen_helper_rfi(cpu_env);
     gen_sync_exception(ctx);
-    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 
@@ -4010,9 +4008,7 @@ static void gen_rfid(DisasContext *ctx)
     gen_update_cfar(ctx, ctx->base.pc_next - 4);
     gen_helper_rfid(cpu_env);
     gen_sync_exception(ctx);
-    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 
@@ -4388,9 +4384,7 @@ static void gen_mtmsrd(DisasContext *ctx)
         /* Must stop the translation as machine state (may have) changed */
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);
-        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
     }
 #endif /* !defined(CONFIG_USER_ONLY) */
 }
@@ -4428,9 +4422,7 @@ static void gen_mtmsr(DisasContext *ctx)
         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
 #endif
         gen_helper_store_msr(cpu_env, msr);
-        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-            gen_io_end();
-        }
+        /* No need for gen_io_end at the end of the block */
         tcg_temp_free(msr);
         /* Must stop the translation as machine state (may have) changed */
         /* Note that mtmsr is not always defined as context-synchronizing */
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 86fc8f2e31..3e7a55987b 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -189,7 +189,7 @@ static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
     }
     gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
         gen_stop_exception(ctx);
     }
 }
@@ -201,7 +201,7 @@ static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
     }
     gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
         gen_stop_exception(ctx);
     }
 }
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c
index ea6473111c..c70cb68ffc 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -511,7 +511,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
 } while (0)
 
 #define RISCV_OP_CSR_POST do {\
-    gen_io_end(); \
+    /* No need for gen_io_end at the end of the block */ \
     gen_set_gpr(a->rd, dest); \
     tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
     exit_tb(ctx); \
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 091bab53af..f5b83e46f8 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4412,10 +4412,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_helper_tick_set_limit(r_tickptr,
                                                               cpu_tick_cmpr);
                                     tcg_temp_free_ptr(r_tickptr);
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_end();
-                                    }
+                                    /*
+                                     * No need for gen_io_end
+                                     * at the end of the block
+                                     */
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4440,10 +4440,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_helper_tick_set_count(r_tickptr,
                                                               cpu_tmp0);
                                     tcg_temp_free_ptr(r_tickptr);
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_end();
-                                    }
+                                    /*
+                                     * No need for gen_io_end
+                                     * at the end of the block
+                                     */
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4468,10 +4468,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_helper_tick_set_limit(r_tickptr,
                                                               cpu_stick_cmpr);
                                     tcg_temp_free_ptr(r_tickptr);
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_end();
-                                    }
+                                    /*
+                                     * No need for gen_io_end
+                                     * at the end of the block
+                                     */
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4588,10 +4588,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_helper_tick_set_count(r_tickptr,
                                                               cpu_tmp0);
                                     tcg_temp_free_ptr(r_tickptr);
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_end();
-                                    }
+                                    /*
+                                     * No need for gen_io_end
+                                     * at the end of the block
+                                     */
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
index d27451eed3..11e6c2d266 100644
--- a/target/unicore32/translate.c
+++ b/target/unicore32/translate.c
@@ -1931,7 +1931,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
                code.  */
             cpu_abort(cs, "IO on conditional branch instruction");
         }
-        gen_io_end();
+        /* No need for gen_io_end at the end of the block */
     }
 
     /* At this stage dc->condjmp will only be set when the skipped
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 6f1da87875..1baf340289 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -540,9 +540,7 @@ static void gen_waiti(DisasContext *dc, uint32_t imm4)
         gen_io_start();
     }
     gen_helper_waiti(cpu_env, pc, intlevel);
-    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
     tcg_temp_free(pc);
     tcg_temp_free(intlevel);
 }
@@ -2216,9 +2214,7 @@ static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[],
     }
     gen_helper_update_ccount(cpu_env);
     tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
-    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 
@@ -2608,9 +2604,7 @@ static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
     tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
     gen_helper_update_ccompare(cpu_env, tmp);
     tcg_temp_free(tmp);
-    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 
@@ -2622,9 +2616,7 @@ static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
         gen_io_start();
     }
     gen_helper_wsr_ccount(cpu_env, arg[0].in);
-    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 
@@ -2831,9 +2823,7 @@ static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
     tcg_gen_mov_i32(arg[0].out, tmp);
     tcg_temp_free(tmp);
 
-    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-        gen_io_end();
-    }
+    /* No need for gen_io_end at the end of the block */
 #endif
 }
 



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls
  2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls Pavel Dovgalyuk
@ 2019-07-25 11:29   ` Paolo Bonzini
  2019-07-25 11:34     ` Pavel Dovgalyuk
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2019-07-25 11:29 UTC (permalink / raw)
  To: Pavel Dovgalyuk, qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, quintela, ciro.santilli,
	jasowang, crosthwaite.peter, armbru, mreitz, alex.bennee,
	maria.klimushenkova, mst, kraxel, boost.lists, thomas.dullien,
	dovgaluk, artem.k.pisarenko, dgilbert, rth

On 25/07/19 10:44, Pavel Dovgalyuk wrote:
> Prior patch resets can_do_io flag at the TB entry. Therefore there is no
> need in resetting this flag at the end of the block.
> This patch removes redundant gen_io_end calls.

Nice.  I don't think the comments are particularly useful, I'll move
them to gen-icount.h if you agree.

Paolo


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls
  2019-07-25 11:29   ` Paolo Bonzini
@ 2019-07-25 11:34     ` Pavel Dovgalyuk
  0 siblings, 0 replies; 11+ messages in thread
From: Pavel Dovgalyuk @ 2019-07-25 11:34 UTC (permalink / raw)
  To: 'Paolo Bonzini', 'Pavel Dovgalyuk', qemu-devel
  Cc: kwolf, peter.maydell, pavel.dovgaluk, quintela, ciro.santilli,
	jasowang, crosthwaite.peter, armbru, mreitz, alex.bennee,
	maria.klimushenkova, mst, kraxel, boost.lists, thomas.dullien,
	artem.k.pisarenko, dgilbert, rth

> From: Paolo Bonzini [mailto:pbonzini@redhat.com]
> On 25/07/19 10:44, Pavel Dovgalyuk wrote:
> > Prior patch resets can_do_io flag at the TB entry. Therefore there is no
> > need in resetting this flag at the end of the block.
> > This patch removes redundant gen_io_end calls.
> 
> Nice.  I don't think the comments are particularly useful, I'll move
> them to gen-icount.h if you agree.

Ok, thanks.

Pavel Dovgalyuk



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-07-25 11:34 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25  8:44 [Qemu-devel] [for-4.2 PATCH v2 0/8] Some record/replay fixes Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 1/8] replay: add missing fix for internal function Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 2/8] replay: document development rules Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 3/8] util/qemu-timer: refactor deadline calculation for external timers Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 4/8] replay: fix replay shutdown Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 5/8] replay: refine replay-time module Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 6/8] replay: rename step-related variables and functions Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 7/8] icount: clean up cpu_can_io at the entry to the block Pavel Dovgalyuk
2019-07-25  8:44 ` [Qemu-devel] [for-4.2 PATCH v2 8/8] icount: remove unnecessary gen_io_end calls Pavel Dovgalyuk
2019-07-25 11:29   ` Paolo Bonzini
2019-07-25 11:34     ` Pavel Dovgalyuk

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.