@samitouri / QOSamiQemu / commits / 1ca38f84e1

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 }