From: Tao Ding <[email protected]>

Separate global and channel register handling to prevent unsigned address 
underflow
when calculating GSDMA channel offsets.

Resolves: Coverity CID 1685514

Reported-by: Alistair Francis <[email protected]>
Signed-off-by: Tao Ding <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Alistair Francis <[email protected]>
---
 hw/dma/k230_gsdma.c | 84 ++++++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/hw/dma/k230_gsdma.c b/hw/dma/k230_gsdma.c
index 7635cd19e88e..bd6db9e64d29 100644
--- a/hw/dma/k230_gsdma.c
+++ b/hw/dma/k230_gsdma.c
@@ -304,54 +304,54 @@ static uint64_t k230_gsdma_read(void *opaque, hwaddr 
addr, unsigned int size)
     hwaddr ch_off;
     uint64_t ret = 0;
 
-    switch (addr) {
-    case K230_GSDMA_DMA_CH_EN:
-        ret = s->dma_ch_en;
-        break;
-    case K230_GSDMA_DMA_INT_MASK:
-        ret = s->dma_int_mask;
-        break;
-    case K230_GSDMA_DMA_INT_STAT:
-        ret = s->dma_int_stat;
-        break;
-    case K230_GSDMA_DMA_CFG:
-        ret = s->dma_cfg;
-        break;
-    case K230_GSDMA_DMA_WEIGHT:
-        ret = s->dma_weight;
-        break;
-    default:
-        if (addr < K230_GSDMA_CH_BASE) {
-            qemu_log_mask(LOG_GUEST_ERROR,
-                        "%s: not implement gdma at offset 0x%" HWADDR_PRIx
-                        "\n", __func__, addr);
-        }
-        break;
-    }
-
-    ch = (addr - K230_GSDMA_CH_BASE) / K230_GSDMA_CH_STRIDE;
-    ch_off = (addr - K230_GSDMA_CH_BASE) % K230_GSDMA_CH_STRIDE;
-    if (ch < K230_GSDMA_NUM_SDMA_CHANNELS) {
-        switch (ch_off) {
-        case K230_GSDMA_CH_CTL:
-            break;
-        case K230_GSDMA_CH_STATUS:
-            ret = s->channels[ch].status;
+    if (addr < K230_GSDMA_CH_BASE) {
+        switch (addr) {
+        case K230_GSDMA_DMA_CH_EN:
+            ret = s->dma_ch_en;
             break;
-        case K230_GSDMA_CH_CFG:
-            ret = s->channels[ch].cfg;
+        case K230_GSDMA_DMA_INT_MASK:
+            ret = s->dma_int_mask;
             break;
-        case K230_GSDMA_CH_USR_DATA:
-            ret = s->channels[ch].usr_data;
+        case K230_GSDMA_DMA_INT_STAT:
+            ret = s->dma_int_stat;
             break;
-        case K230_GSDMA_CH_LLT_SADDR:
-            ret = s->channels[ch].llt_saddr;
+        case K230_GSDMA_DMA_CFG:
+            ret = s->dma_cfg;
             break;
-        case K230_GSDMA_CH_CURRENT_LLT:
-            ret = s->channels[ch].current_llt;
+        case K230_GSDMA_DMA_WEIGHT:
+            ret = s->dma_weight;
             break;
         default:
-            break;
+            qemu_log_mask(LOG_GUEST_ERROR,
+                        "%s: not implement gdma at offset 0x%" HWADDR_PRIx
+                        "\n", __func__, addr);
+            return ret;
+        }
+    } else {
+        ch = (addr - K230_GSDMA_CH_BASE) / K230_GSDMA_CH_STRIDE;
+        ch_off = (addr - K230_GSDMA_CH_BASE) % K230_GSDMA_CH_STRIDE;
+        if (ch < K230_GSDMA_NUM_SDMA_CHANNELS) {
+            switch (ch_off) {
+            case K230_GSDMA_CH_CTL:
+                break;
+            case K230_GSDMA_CH_STATUS:
+                ret = s->channels[ch].status;
+                break;
+            case K230_GSDMA_CH_CFG:
+                ret = s->channels[ch].cfg;
+                break;
+            case K230_GSDMA_CH_USR_DATA:
+                ret = s->channels[ch].usr_data;
+                break;
+            case K230_GSDMA_CH_LLT_SADDR:
+                ret = s->channels[ch].llt_saddr;
+                break;
+            case K230_GSDMA_CH_CURRENT_LLT:
+                ret = s->channels[ch].current_llt;
+                break;
+            default:
+                break;
+            }
         }
     }
 
-- 
2.55.0


Reply via email to