aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2020-09-01 16:09:44 +0200
committerGerd Hoffmann <kraxel@redhat.com>2020-09-04 10:12:56 +0200
commit5fcf787582dd911df3a971718010bfca5a20e61d (patch)
treebe5dc084ffcb1313227889fe2df840a2337d4e11
parenteb398a54e33ab2ac9701839be9b660af3e50a32e (diff)
downloadqemu-5fcf787582dd911df3a971718010bfca5a20e61d.zip
qemu-5fcf787582dd911df3a971718010bfca5a20e61d.tar.gz
qemu-5fcf787582dd911df3a971718010bfca5a20e61d.tar.bz2
cirrus: handle wraparound in cirrus_invalidate_region
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 <liq3ea@163.com> Reported-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Li Qiang <liq3ea@163.com> Message-id: 20200901140944.24101-1-kraxel@redhat.com
-rw-r--r--hw/display/cirrus_vga.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 02d9ed0..41e71af 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;
}
}