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
This commit is contained in:
Gerd Hoffmann 2020-09-01 16:09:44 +02:00
parent eb398a54e3
commit 5fcf787582

View File

@ -640,10 +640,16 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
} }
for (y = 0; y < lines; y++) { 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; off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1;
assert(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); 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; off_begin += off_pitch;
} }
} }