lsi53c895a: keep lsi_request and SCSIRequest in local variables
Protect against changes from reentrant device MMIO during DMA, by always operating on the same request. Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo Bonzini committed
Mar 27, 2026 at 18:32 UTC
1ca38f84e19427c462f077390492f971f9eb11eb
1 file changed
+17
-12
hw/scsi/lsi53c895a.c
+17
-12
@@ -626,6 +626,8 @@ static void lsi_do_dma(LSIState *s, int out)
626
uint32_t count;
627
dma_addr_t addr;
628
SCSIDevice *dev;
629
+ SCSIRequest *req;
630
+ lsi_request *p;
631
632
if (!s->current || !s->current->dma_len) {
633
/* Wait until data is available. */
@@ -633,12 +635,14 @@ static void lsi_do_dma(LSIState *s, int out)
635
return;
636
}
637
636
- dev = s->current->req->dev;
638
+ p = s->current;
639
+ req = s->current->req;
640
+ dev = req->dev;
641
assert(dev);
642
643
count = s->dbc;
640
- if (count > s->current->dma_len)
641
- count = s->current->dma_len;
644
+ if (count > p->dma_len)
645
+ count = p->dma_len;
646
647
addr = s->dnad;
648
/* both 40 and Table Indirect 64-bit DMAs store upper bits in dnad64 */
@@ -653,21 +657,22 @@ static void lsi_do_dma(LSIState *s, int out)
657
s->csbc += count;
658
s->dnad += count;
659
s->dbc -= count;
656
- if (s->current->dma_buf == NULL) {
657
- s->current->dma_buf = scsi_req_get_buf(s->current->req);
660
+ if (p->dma_buf == NULL) {
661
+ p->dma_buf = scsi_req_get_buf(req);
662
}
663
/* ??? Set SFBR to first data byte. */
664
if (out) {
661
- lsi_mem_read(s, addr, s->current->dma_buf, count);
665
+ lsi_mem_read(s, addr, p->dma_buf, count);
666
} else {
663
- lsi_mem_write(s, addr, s->current->dma_buf, count);
667
+ lsi_mem_write(s, addr, p->dma_buf, count);
668
}
665
- s->current->dma_len -= count;
666
- if (s->current->dma_len == 0) {
667
- s->current->dma_buf = NULL;
668
- scsi_req_continue(s->current->req);
669
+
670
+ p->dma_len -= count;
671
+ if (p->dma_len == 0) {
672
+ p->dma_buf = NULL;
673
+ scsi_req_continue(req);
674
} else {
670
- s->current->dma_buf += count;
675
+ p->dma_buf += count;
676
lsi_resume_script(s);
677
}
678
}