All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb()
@ 2013-05-09 15:30 Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 1/4] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses Michael Tokarev
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:30 UTC (permalink / raw)
  To: qemu-stable; +Cc: Peter Maydell, Michael Tokarev, qemu-devel

This is a backport of the patch series by Peter Maydell, as found at
http://thread.gmane.org/gmane.comp.emulators.qemu/196629 , to 1.4.y
stable tree, very similar to what's been done for 1.1 tree.  The
difference is in context and because some code were moved between
exec.c and translate-all.c, but basically it is still the same
series.

Peter Maydell (4):
  tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses
  cpu-exec: wrap tcg_qemu_tb_exec() in a fn to restore the PC
  Handle CPU interrupts by inline checking of a flag
  translate-all.c: Remove cpu_unlink_tb()

 cpu-exec.c                |   58 ++++++++++++++++++++++++++---------
 exec.c                    |    2 +-
 include/exec/cpu-defs.h   |    1 +
 include/exec/gen-icount.h |   13 +++++++-
 tcg/tcg.h                 |   49 +++++++++++++++++++++++++++++-
 translate-all.c           |   73 ++-------------------------------------------
 6 files changed, 108 insertions(+), 88 deletions(-)

-- 
1.7.10.4

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

* [Qemu-devel] [PATCH for-1.4.y 1/4] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses
  2013-05-09 15:30 [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb() Michael Tokarev
@ 2013-05-09 15:30 ` Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 2/4] cpu-exec: wrap tcg_qemu_tb_exec() in a fn to restore the PC Michael Tokarev
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:30 UTC (permalink / raw)
  To: qemu-stable; +Cc: Blue Swirl, Peter Maydell, Michael Tokarev, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

Document tcg_qemu_tb_exec(). In particular, its return value is a
combination of a pointer to the next translation block and some
extra information in the low two bits. Provide some #defines for
the values passed in these bits to improve code clarity.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

(cherry picked from commit 0980011b4f66482d2733ab2dd0f2f61747772c6b)

Conflicts:
	tcg/tcg.h

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
 cpu-exec.c                |    9 +++++----
 include/exec/gen-icount.h |    2 +-
 tcg/tcg.h                 |   44 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 19ebb4a..797e11a 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -71,7 +71,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
     next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
     env->current_tb = NULL;
 
-    if ((next_tb & 3) == 2) {
+    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
         /* Restore PC.  This may happen if async event occurs before
            the TB starts executing.  */
         cpu_pc_from_tb(env, tb);
@@ -583,7 +583,8 @@ int cpu_exec(CPUArchState *env)
                    spans two pages, we cannot safely do a direct
                    jump. */
                 if (next_tb != 0 && tb->page_addr[1] == -1) {
-                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
+                    tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
+                                next_tb & TB_EXIT_MASK, tb);
                 }
                 spin_unlock(&tb_lock);
 
@@ -597,10 +598,10 @@ int cpu_exec(CPUArchState *env)
                     tc_ptr = tb->tc_ptr;
                     /* execute the generated code */
                     next_tb = tcg_qemu_tb_exec(env, tc_ptr);
-                    if ((next_tb & 3) == 2) {
+                    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
                         /* Instruction counter expired.  */
                         int insns_left;
-                        tb = (TranslationBlock *)(next_tb & ~3);
+                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
                         /* Restore PC.  */
                         cpu_pc_from_tb(env, tb);
                         insns_left = env->icount_decr.u32;
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 8043b3b..c858a73 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -32,7 +32,7 @@ static void gen_icount_end(TranslationBlock *tb, int num_insns)
     if (use_icount) {
         *icount_arg = num_insns;
         gen_set_label(icount_label);
-        tcg_gen_exit_tb((tcg_target_long)tb + 2);
+        tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED);
     }
 }
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index a427972..10eb3f4 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -660,7 +660,49 @@ TCGv_i64 tcg_const_local_i64(int64_t val);
 
 extern uint8_t *code_gen_prologue;
 
-/* TCG targets may use a different definition of tcg_qemu_tb_exec. */
+/**
+ * tcg_qemu_tb_exec:
+ * @env: CPUArchState * for the CPU
+ * @tb_ptr: address of generated code for the TB to execute
+ *
+ * Start executing code from a given translation block.
+ * Where translation blocks have been linked, execution
+ * may proceed from the given TB into successive ones.
+ * Control eventually returns only when some action is needed
+ * from the top-level loop: either control must pass to a TB
+ * which has not yet been directly linked, or an asynchronous
+ * event such as an interrupt needs handling.
+ *
+ * The return value is a pointer to the next TB to execute
+ * (if known; otherwise zero). This pointer is assumed to be
+ * 4-aligned, and the bottom two bits are used to return further
+ * information:
+ *  0, 1: the link between this TB and the next is via the specified
+ *        TB index (0 or 1). That is, we left the TB via (the equivalent
+ *        of) "goto_tb <index>". The main loop uses this to determine
+ *        how to link the TB just executed to the next.
+ *  2:    we are using instruction counting code generation, and we
+ *        did not start executing this TB because the instruction counter
+ *        would hit zero midway through it. In this case the next-TB pointer
+ *        returned is the TB we were about to execute, and the caller must
+ *        arrange to execute the remaining count of instructions.
+ *
+ * If the bottom two bits indicate an exit-via-index then the CPU
+ * state is correctly synchronised and ready for execution of the next
+ * TB (and in particular the guest PC is the address to execute next).
+ * Otherwise, we gave up on execution of this TB before it started, and
+ * the caller must fix up the CPU state by calling cpu_pc_from_tb()
+ * with the next-TB pointer we return.
+ *
+ * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
+ * to this default (which just calls the prologue.code emitted by
+ * tcg_target_qemu_prologue()).
+ */
+#define TB_EXIT_MASK 3
+#define TB_EXIT_IDX0 0
+#define TB_EXIT_IDX1 1
+#define TB_EXIT_ICOUNT_EXPIRED 2
+
 #if !defined(tcg_qemu_tb_exec)
 # define tcg_qemu_tb_exec(env, tb_ptr) \
     ((tcg_target_ulong (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
-- 
1.7.10.4

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

* [Qemu-devel] [PATCH for-1.4.y 2/4] cpu-exec: wrap tcg_qemu_tb_exec() in a fn to restore the PC
  2013-05-09 15:30 [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb() Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 1/4] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses Michael Tokarev
@ 2013-05-09 15:30 ` Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 4/4] translate-all.c: Remove cpu_unlink_tb() Michael Tokarev
  3 siblings, 0 replies; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:30 UTC (permalink / raw)
  To: qemu-stable; +Cc: Blue Swirl, Peter Maydell, Michael Tokarev, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

If tcg_qemu_tb_exec() returns a value whose low bits don't indicate a
link to an indexed next TB, this means that the TB execution never
started (eg because the instruction counter hit zero).  In this case the
guest PC has to be reset to the address of the start of the TB.
Refactor the cpu-exec code to make all tcg_qemu_tb_exec() calls pass
through a wrapper function which does this restoration if necessary.

Note that the apparent change in cpu_exec_nocache() from calling
cpu_pc_from_tb() with the old TB to calling it with the TB returned by
do_tcg_qemu_tb_exec() is safe, because in the nocache case we can
guarantee that the TB we try to execute is not linked to any others,
so the only possible returned TB is the one we started at. That is,
we should arguably previously have included in cpu_exec_nocache() an
assert(next_tb & ~TB_EXIT_MASK) == tb), since the API requires restore
from next_tb but we were using tb.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

(cherry picked from commit 77211379d73ea0c89c0b5bb6eee74b17cb06f9a8)

Conflicts:
	cpu-exec.c

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
 cpu-exec.c |   28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 797e11a..4ffae22 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -51,12 +51,26 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
 }
 #endif
 
+/* Execute a TB, and fix up the CPU state afterwards if necessary */
+static inline tcg_target_ulong cpu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
+{
+    tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr);
+    if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
+        /* We didn't start executing this TB (eg because the instruction
+         * counter hit zero); we must restore the guest PC to the address
+         * of the start of the TB.
+         */
+        TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+        cpu_pc_from_tb(env, tb);
+    }
+    return next_tb;
+}
+
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
 static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
                              TranslationBlock *orig_tb)
 {
-    tcg_target_ulong next_tb;
     TranslationBlock *tb;
 
     /* Should never happen.
@@ -68,14 +82,8 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
                      max_cycles);
     env->current_tb = tb;
     /* execute the generated code */
-    next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
+    cpu_tb_exec(env, tb->tc_ptr);
     env->current_tb = NULL;
-
-    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
-        /* Restore PC.  This may happen if async event occurs before
-           the TB starts executing.  */
-        cpu_pc_from_tb(env, tb);
-    }
     tb_phys_invalidate(tb, -1);
     tb_free(tb);
 }
@@ -597,13 +605,11 @@ int cpu_exec(CPUArchState *env)
                 if (likely(!env->exit_request)) {
                     tc_ptr = tb->tc_ptr;
                     /* execute the generated code */
-                    next_tb = tcg_qemu_tb_exec(env, tc_ptr);
+                    next_tb = cpu_tb_exec(env, tc_ptr);
                     if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
                         /* Instruction counter expired.  */
                         int insns_left;
                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
-                        /* Restore PC.  */
-                        cpu_pc_from_tb(env, tb);
                         insns_left = env->icount_decr.u32;
                         if (env->icount_extra && insns_left >= 0) {
                             /* Refill decrementer and continue execution.  */
-- 
1.7.10.4

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

* [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag
  2013-05-09 15:30 [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb() Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 1/4] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 2/4] cpu-exec: wrap tcg_qemu_tb_exec() in a fn to restore the PC Michael Tokarev
@ 2013-05-09 15:30 ` Michael Tokarev
  2013-05-09 15:42   ` Michael Tokarev
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 4/4] translate-all.c: Remove cpu_unlink_tb() Michael Tokarev
  3 siblings, 1 reply; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:30 UTC (permalink / raw)
  To: qemu-stable; +Cc: Blue Swirl, Peter Maydell, Michael Tokarev, qemu-devel

Fix some of the nasty TCG race conditions and crashes by implementing
cpu_exit() as setting a flag which is checked at the start of each TB.
This avoids crashes if a thread or signal handler calls cpu_exit()
while the execution thread is itself modifying the TB graph (which
may happen in system emulation mode as well as in linux-user mode
with a multithreaded guest binary).

This fixes the crashes seen in LP:668799; however there are another
class of crashes described in LP:1098729 which stem from the fact
that in linux-user with a multithreaded guest all threads will
use and modify the same global TCG date structures (including the
generated code buffer) without any kind of locking. This means that
multithreaded guest binaries are still in the "unsupported"
category.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

(cherry picked from commit 378df4b23753a11be650af7664ca76bc75cb9f01)

Conflicts:
	exec.c
	include/qom/cpu.h
	translate-all.c
	include/exec/gen-icount.h

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>

Conflicts:
	cpu-exec.c
---
 cpu-exec.c                |   25 ++++++++++++++++++++++++-
 exec.c                    |    2 +-
 include/exec/cpu-defs.h   |    1 +
 include/exec/gen-icount.h |   11 +++++++++++
 tcg/tcg.h                 |    5 +++++
 translate-all.c           |    4 ++--
 6 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 4ffae22..1c6af24 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -63,6 +63,12 @@ static inline tcg_target_ulong cpu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
         TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
         cpu_pc_from_tb(env, tb);
     }
+    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
+        /* We were asked to stop executing TBs (probably a pending
+         * interrupt. We've now stopped, so clear the flag.
+         */
+        env->tcg_exit_req = 0;
+    }
     return next_tb;
 }
 
@@ -606,7 +612,20 @@ int cpu_exec(CPUArchState *env)
                     tc_ptr = tb->tc_ptr;
                     /* execute the generated code */
                     next_tb = cpu_tb_exec(env, tc_ptr);
-                    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
+                    switch (next_tb & TB_EXIT_MASK) {
+                    case TB_EXIT_REQUESTED:
+                        /* Something asked us to stop executing
+                         * chained TBs; just continue round the main
+                         * loop. Whatever requested the exit will also
+                         * have set something else (eg exit_request or
+                         * interrupt_request) which we will handle
+                         * next time around the loop.
+                         */
+                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
+                        next_tb = 0;
+                        break;
+                    case TB_EXIT_ICOUNT_EXPIRED:
+                    {
                         /* Instruction counter expired.  */
                         int insns_left;
                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
@@ -630,6 +649,10 @@ int cpu_exec(CPUArchState *env)
                             next_tb = 0;
                             cpu_loop_exit(env);
                         }
+                        break;
+                    }
+                    default:
+                        break;
                     }
                 }
                 env->current_tb = NULL;
diff --git a/exec.c b/exec.c
index b85508b..371713a 100644
--- a/exec.c
+++ b/exec.c
@@ -493,7 +493,7 @@ void cpu_reset_interrupt(CPUArchState *env, int mask)
 void cpu_exit(CPUArchState *env)
 {
     env->exit_request = 1;
-    cpu_unlink_tb(env);
+    env->tcg_exit_req = 1;
 }
 
 void cpu_abort(CPUArchState *env, const char *fmt, ...)
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 2911b9f..07fce69 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -161,6 +161,7 @@ typedef struct CPUWatchpoint {
     uint32_t halted; /* Nonzero if the CPU is in suspend state */       \
     uint32_t interrupt_request;                                         \
     volatile sig_atomic_t exit_request;                                 \
+    volatile sig_atomic_t tcg_exit_req;                                 \
     CPU_COMMON_TLB                                                      \
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
     /* buffer for temporaries in the code generator */                  \
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index c858a73..f45f975 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -7,10 +7,18 @@
 
 static TCGArg *icount_arg;
 static int icount_label;
+static int exitreq_label;
 
 static inline void gen_icount_start(void)
 {
     TCGv_i32 count;
+    TCGv_i32 flag;
+
+    exitreq_label = gen_new_label();
+    flag = tcg_temp_local_new_i32();
+    tcg_gen_ld_i32(flag, cpu_env, offsetof(CPUArchState, tcg_exit_req));
+    tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
+    tcg_temp_free_i32(flag);
 
     if (!use_icount)
         return;
@@ -29,6 +37,9 @@ static inline void gen_icount_start(void)
 
 static void gen_icount_end(TranslationBlock *tb, int num_insns)
 {
+    gen_set_label(exitreq_label);
+    tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_REQUESTED);
+
     if (use_icount) {
         *icount_arg = num_insns;
         gen_set_label(icount_label);
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 10eb3f4..34b2ca8 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -686,6 +686,10 @@ extern uint8_t *code_gen_prologue;
  *        would hit zero midway through it. In this case the next-TB pointer
  *        returned is the TB we were about to execute, and the caller must
  *        arrange to execute the remaining count of instructions.
+ *  3:    we stopped because the CPU's exit_request flag was set
+ *        (usually meaning that there is an interrupt that needs to be
+ *        handled). The next-TB pointer returned is the TB we were
+ *        about to execute when we noticed the pending exit request.
  *
  * If the bottom two bits indicate an exit-via-index then the CPU
  * state is correctly synchronised and ready for execution of the next
@@ -702,6 +706,7 @@ extern uint8_t *code_gen_prologue;
 #define TB_EXIT_IDX0 0
 #define TB_EXIT_IDX1 1
 #define TB_EXIT_ICOUNT_EXPIRED 2
+#define TB_EXIT_REQUESTED 3
 
 #if !defined(tcg_qemu_tb_exec)
 # define tcg_qemu_tb_exec(env, tb_ptr) \
diff --git a/translate-all.c b/translate-all.c
index bf1db09..1288b2a 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1476,7 +1476,7 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask)
             cpu_abort(env, "Raised interrupt while not in I/O function");
         }
     } else {
-        cpu_unlink_tb(env);
+        env->tcg_exit_req = 1;
     }
 }
 
@@ -1617,7 +1617,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
 void cpu_interrupt(CPUArchState *env, int mask)
 {
     env->interrupt_request |= mask;
-    cpu_unlink_tb(env);
+    env->tcg_exit_req = 1;
 }
 
 /*
-- 
1.7.10.4

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

* [Qemu-devel] [PATCH for-1.4.y 4/4] translate-all.c: Remove cpu_unlink_tb()
  2013-05-09 15:30 [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb() Michael Tokarev
                   ` (2 preceding siblings ...)
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag Michael Tokarev
@ 2013-05-09 15:30 ` Michael Tokarev
  3 siblings, 0 replies; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:30 UTC (permalink / raw)
  To: qemu-stable; +Cc: Blue Swirl, Peter Maydell, Michael Tokarev, qemu-devel

From: Peter Maydell <peter.maydell@linaro.org>

The (unsafe) function cpu_unlink_tb() is now unused, so we can simply
remove it and any code that was only used by it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

(cherry picked from commit 3a808cc407744c30daa7470b5f191cde1fbc1aae)

Conflicts:
	translate-all.c

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
 translate-all.c |   69 -------------------------------------------------------
 1 file changed, 69 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index 1288b2a..ba4d3f6 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1350,55 +1350,6 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
     return &tbs[m_max];
 }
 
-static void tb_reset_jump_recursive(TranslationBlock *tb);
-
-static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
-{
-    TranslationBlock *tb1, *tb_next, **ptb;
-    unsigned int n1;
-
-    tb1 = tb->jmp_next[n];
-    if (tb1 != NULL) {
-        /* find head of list */
-        for (;;) {
-            n1 = (uintptr_t)tb1 & 3;
-            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
-            if (n1 == 2) {
-                break;
-            }
-            tb1 = tb1->jmp_next[n1];
-        }
-        /* we are now sure now that tb jumps to tb1 */
-        tb_next = tb1;
-
-        /* remove tb from the jmp_first list */
-        ptb = &tb_next->jmp_first;
-        for (;;) {
-            tb1 = *ptb;
-            n1 = (uintptr_t)tb1 & 3;
-            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
-            if (n1 == n && tb1 == tb) {
-                break;
-            }
-            ptb = &tb1->jmp_next[n1];
-        }
-        *ptb = tb->jmp_next[n];
-        tb->jmp_next[n] = NULL;
-
-        /* suppress the jump to next tb in generated code */
-        tb_reset_jump(tb, n);
-
-        /* suppress jumps in the tb on which we could have jumped */
-        tb_reset_jump_recursive(tb_next);
-    }
-}
-
-static void tb_reset_jump_recursive(TranslationBlock *tb)
-{
-    tb_reset_jump_recursive2(tb, 0);
-    tb_reset_jump_recursive2(tb, 1);
-}
-
 #if defined(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)
 void tb_invalidate_phys_addr(hwaddr addr)
 {
@@ -1417,26 +1368,6 @@ void tb_invalidate_phys_addr(hwaddr addr)
 }
 #endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */
 
-void cpu_unlink_tb(CPUArchState *env)
-{
-    /* FIXME: TB unchaining isn't SMP safe.  For now just ignore the
-       problem and hope the cpu will stop of its own accord.  For userspace
-       emulation this often isn't actually as bad as it sounds.  Often
-       signals are used primarily to interrupt blocking syscalls.  */
-    TranslationBlock *tb;
-    static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
-
-    spin_lock(&interrupt_lock);
-    tb = env->current_tb;
-    /* if the cpu is currently executing code, we must unlink it and
-       all the potentially executing TB */
-    if (tb) {
-        env->current_tb = NULL;
-        tb_reset_jump_recursive(tb);
-    }
-    spin_unlock(&interrupt_lock);
-}
-
 void tb_check_watchpoint(CPUArchState *env)
 {
     TranslationBlock *tb;
-- 
1.7.10.4

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

* Re: [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag
  2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag Michael Tokarev
@ 2013-05-09 15:42   ` Michael Tokarev
  0 siblings, 0 replies; 6+ messages in thread
From: Michael Tokarev @ 2013-05-09 15:42 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: Blue Swirl, Peter Maydell, qemu-stable, qemu-devel

09.05.2013 19:30, Michael Tokarev wrote:
> Fix some of the nasty TCG race conditions and crashes by implementing
...

Somehow this went out without proper authorship line, dunno why.
I can resent if needed, adding:

From: Peter Maydell <peter.maydell@linaro.org>

Thanks,

/mjt

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

end of thread, other threads:[~2013-05-09 15:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-09 15:30 [Qemu-devel] [PATCH for-1.4.y 0/4] Drop the irredeemably racy cpu_unlink_tb() Michael Tokarev
2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 1/4] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses Michael Tokarev
2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 2/4] cpu-exec: wrap tcg_qemu_tb_exec() in a fn to restore the PC Michael Tokarev
2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 3/4] Handle CPU interrupts by inline checking of a flag Michael Tokarev
2013-05-09 15:42   ` Michael Tokarev
2013-05-09 15:30 ` [Qemu-devel] [PATCH for-1.4.y 4/4] translate-all.c: Remove cpu_unlink_tb() Michael Tokarev

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.