From: Richard Henderson <[email protected]> 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: [email protected] Reported-by: 李威威 <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Reviewed-by: Anton Johansson <[email protected]> Tested-by: Anton Johansson <[email protected]> (cherry picked from commit 03fe6659803f83690b8587d01f8ee56bb4be4b90) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 9d9f651c78..077265172e 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -186,6 +186,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
