From: Weiwei Li <[email protected]>

The problem is triggered in following conditions:
- thread 1:
    run spin loop(ended with a direct jump) like "0x0000006f, // jal zero, #0"
- thread 2:
    do something, and then modify the loop code of thread 1 to nop isntruction,
    finally wait thread 1 exit.

The loop tb which is patched to jump to itself, will not be updated in this case
and will never exit.

Signed-off-by: Weiwei Li <[email protected]>
---
 accel/tcg/cpu-exec.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 8491e5badd..6919d068c8 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -973,8 +973,12 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
                 last_tb = NULL;
             }
 #endif
-            /* See if we can patch the calling TB. */
-            if (last_tb) {
+            /*
+             * See if we can patch the calling TB.
+             * To make self-modifying code work, we prevent patching the single
+             * tb loop.
+             */
+            if (last_tb && last_tb != tb) {
                 tb_add_jump(last_tb, tb_exit, tb);
             }
 
-- 
2.43.0


Reply via email to