diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2020-09-01 16:09:44 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2020-09-04 10:12:56 +0200 |
commit | 5fcf787582dd911df3a971718010bfca5a20e61d (patch) | |
tree | be5dc084ffcb1313227889fe2df840a2337d4e11 | |
parent | eb398a54e33ab2ac9701839be9b660af3e50a32e (diff) | |
download | qemu-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.c | 12 |
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; } } |