]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
accel/tcg: Properly unlink a TB linked to itself
authorRichard Henderson <richard.henderson@linaro.org>
Tue, 23 Sep 2025 23:02:03 +0000 (16:02 -0700)
committerRichard Henderson <richard.henderson@linaro.org>
Wed, 24 Sep 2025 16:26:06 +0000 (09:26 -0700)
When we remove dest from orig's links, we lose the link
that we rely on later to reset links.  This can lead to
failure to release from spinlock with self-modifying code.

Cc: qemu-stable@nongnu.org
Reported-by: 李威威 <liweiwei@kubuds.cn>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Anton Johansson <anjo@rev.ng>
Tested-by: Anton Johansson <anjo@rev.ng>
accel/tcg/tb-maint.c

index 0048316f99a778083923d99949d2e1c4fa3919aa..e6d45c9c12702b5806ea08e2dcad9feeacfd4868 100644 (file)
@@ -836,6 +836,14 @@ static inline void tb_remove_from_jmp_list(TranslationBlock *orig, int n_orig)
      * We first acquired the lock, and since the destination pointer matches,
      * we know for sure that @orig is in the jmp list.
      */
+    if (dest == orig) {
+        /*
+         * In the case of a TB that links to itself, removing the entry
+         * from the list means that it won't be present later during
+         * tb_jmp_unlink -- unlink now.
+         */
+        tb_reset_jump(orig, n_orig);
+    }
     pprev = &dest->jmp_list_head;
     TB_FOR_EACH_JMP(dest, tb, n) {
         if (tb == orig && n == n_orig) {