From eb398a54e33ab2ac9701839be9b660af3e50a32e Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Thu, 27 Aug 2020 11:58:55 +0800 Subject: [PATCH 1/2] virtio-gpu: fix unmap the already mapped items we go here either (!(*iov)[i].iov_base) or (len != l), so we need to consider to unmap the 'i'th item as well when the 'i'th item is not nil CC: Li Qiang Signed-off-by: Li Zhijian Message-id: 20200827035855.24354-1-lizhijian@cn.fujitsu.com Signed-off-by: Gerd Hoffmann --- hw/display/virtio-gpu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 5f0dd7c150..90be4e3ed7 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -646,9 +646,9 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g, uint64_t a = le64_to_cpu(ents[i].addr); uint32_t l = le32_to_cpu(ents[i].length); hwaddr len = l; - (*iov)[i].iov_len = l; (*iov)[i].iov_base = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len, DMA_DIRECTION_TO_DEVICE); + (*iov)[i].iov_len = len; if (addr) { (*addr)[i] = a; } @@ -656,6 +656,9 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g, qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" " resource %d element %d\n", __func__, ab->resource_id, i); + if ((*iov)[i].iov_base) { + i++; /* cleanup the 'i'th map */ + } virtio_gpu_cleanup_mapping_iov(g, *iov, i); g_free(ents); *iov = NULL; From 5fcf787582dd911df3a971718010bfca5a20e61d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 1 Sep 2020 16:09:44 +0200 Subject: [PATCH 2/2] cirrus: handle wraparound in cirrus_invalidate_region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code simply asserts that there is no wraparound instead of handling it properly. The assert() can be triggered by the guest (must be privilidged inside the guest though). Fix it. Buglink: https://bugs.launchpad.net/qemu/+bug/1880189 Cc: Li Qiang Reported-by: Philippe Mathieu-Daudé Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Li Qiang Message-id: 20200901140944.24101-1-kraxel@redhat.com --- hw/display/cirrus_vga.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 02d9ed0bd4..41e71af08a 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -640,10 +640,16 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, } for (y = 0; y < lines; y++) { - off_cur = off_begin; + off_cur = off_begin & s->cirrus_addr_mask; off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1; - assert(off_cur_end >= off_cur); - memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); + if (off_cur_end >= off_cur) { + memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); + } else { + /* wraparound */ + memory_region_set_dirty(&s->vga.vram, off_cur, + s->cirrus_addr_mask + 1 - off_cur); + memory_region_set_dirty(&s->vga.vram, 0, off_cur_end); + } off_begin += off_pitch; } }