From: Peter Maydell <[email protected]> Currently the mptsas reset function clears intr_status, but it doesn't reset the doorbell state machine. This means that the state machine and the interrupt state get out of sync, and the guest can trigger an assertion failure in mptsas_doorbell_read() where s->doorbell_state is still DOORBELL_READ but s->intr_status does not have MPI_HIS_DOORBELL_INTERRUPT set.
Fix this by having reset also reset the doorbell state. Strictly speaking we don't need to also clear doorbell_reply_idx and doorbell_reply_size, because those are only read when in DOORBELL_READ state, and the code always sets them up before transitioning into that state. But it's less confusing to clear them out on reset. Cc: [email protected] Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/304 Signed-off-by: Peter Maydell <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> (cherry picked from commit 831a13665ab1123b5ccd127820f287e41be137e9) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c index ba7a7d07707..4335ccd5003 100644 --- a/hw/scsi/mptsas.c +++ b/hw/scsi/mptsas.c @@ -811,6 +811,10 @@ static void mptsas_soft_reset(MPTSASState *s) s->intr_status = 0; s->intr_mask = save_mask; + s->doorbell_state = DOORBELL_NONE; + s->doorbell_reply_idx = 0; + s->doorbell_reply_size = 0; + s->reply_free_tail = 0; s->reply_free_head = 0; s->reply_post_tail = 0; -- 2.47.3
