qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 4/6] esp: don't underflow fifo when writing to the device


From: Mark Cave-Ayland
Subject: [PATCH v2 4/6] esp: don't underflow fifo when writing to the device
Date: Wed, 17 Mar 2021 23:02:21 +0000

When writing to the device make sure that the fifo is not empty, otherwise the
fifo will underflow triggering an assert.

Buglink: https://bugs.launchpad.net/qemu/+bug/1909247
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index ae362c9dfb..bb57125035 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -509,18 +509,20 @@ static void do_dma_pdma_cb(ESPState *s)
         /* Copy FIFO data to device */
         len = MIN(s->async_len, ESP_FIFO_SZ);
         len = MIN(len, fifo8_num_used(&s->fifo));
-        memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
-        s->async_buf += n;
-        s->async_len -= n;
-        s->ti_size += n;
-
-        if (n < len) {
-            /* Unaligned accesses can cause FIFO wraparound */
-            len = len - n;
+        if (len) {
             memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
             s->async_buf += n;
             s->async_len -= n;
             s->ti_size += n;
+
+            if (n < len) {
+                /* Unaligned accesses can cause FIFO wraparound */
+                len = len - n;
+                memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
+                s->async_buf += n;
+                s->async_len -= n;
+                s->ti_size += n;
+            }
         }
 
         if (s->async_len == 0) {
@@ -730,10 +732,12 @@ static void esp_do_nodma(ESPState *s)
 
     if (to_device) {
         len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ);
-        memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
-        s->async_buf += len;
-        s->async_len -= len;
-        s->ti_size += len;
+        if (len) {
+            memcpy(s->async_buf, fifo8_pop_buf(&s->fifo, len, &n), len);
+            s->async_buf += len;
+            s->async_len -= len;
+            s->ti_size += len;
+        }
     } else {
         len = MIN(s->ti_size, s->async_len);
         len = MIN(len, fifo8_num_free(&s->fifo));
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]