From daf8f84e7410cdd2ce1fe4c98d44cfba2726a244 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 23 Sep 2025 16:02:03 -0700 Subject: [PATCH] accel/tcg: Properly unlink a TB linked to itself MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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: 李威威 Signed-off-by: Richard Henderson Reviewed-by: Anton Johansson Tested-by: Anton Johansson (cherry picked from commit 03fe6659803f83690b8587d01f8ee56bb4be4b90) Signed-off-by: Michael Tokarev --- accel/tcg/tb-maint.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 0048316f99a..e6d45c9c127 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -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) { -- 2.47.3