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


Reply via email to