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
