diff --git a/SOURCES/kvm-bswap.h-Remove-cpu_to_32wu.patch b/SOURCES/kvm-bswap.h-Remove-cpu_to_32wu.patch new file mode 100644 index 0000000..9b5425a --- /dev/null +++ b/SOURCES/kvm-bswap.h-Remove-cpu_to_32wu.patch @@ -0,0 +1,68 @@ +From 613e443ae29ae5f64d7f4f6cd4d583316df332c0 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:13 +0200 +Subject: [PATCH 01/11] bswap.h: Remove cpu_to_32wu() + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-2-kraxel@redhat.com> +Patchwork-id: 76821 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 1/7] bswap.h: Remove cpu_to_32wu() +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Peter Maydell + +Replace the legacy cpu_to_32wu() with stl_p(). + +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Reviewed-by: Michael S. Tsirkin +Message-id: 1383669517-25598-10-git-send-email-peter.maydell@linaro.org +Signed-off-by: Anthony Liguori +(cherry picked from commit 7d579514a5a7b308b52d4e8567aa9bd1f7aa761b) + +[ rhel: pick vga update, drop drop include/qemu/bswap.h chunk ] + +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga_template.h | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h +index f6f6a01..6cfae56 100644 +--- a/hw/display/vga_template.h ++++ b/hw/display/vga_template.h +@@ -113,20 +113,22 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, + do { + font_data = font_ptr[0]; + #if BPP == 1 +- cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol); ++ stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol); + v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; +- cpu_to_32wu(((uint32_t *)d)+1, v); ++ stl_p(((uint32_t *)d)+1, v); + if (dup9) + ((uint8_t *)d)[8] = v >> (24 * (1 - BIG)); + else + ((uint8_t *)d)[8] = bgcol; + + #elif BPP == 2 +- cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol); +- cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol); +- cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol); ++ stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol); ++ stl_p(((uint32_t *)d)+1, ++ (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol); ++ stl_p(((uint32_t *)d)+2, ++ (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol); + v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; +- cpu_to_32wu(((uint32_t *)d)+3, v); ++ stl_p(((uint32_t *)d)+3, v); + if (dup9) + ((uint16_t *)d)[8] = v >> (16 * (1 - BIG)); + else +-- +1.8.3.1 + diff --git a/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch b/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch new file mode 100644 index 0000000..4df0e5d --- /dev/null +++ b/SOURCES/kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch @@ -0,0 +1,69 @@ +From bdbdf577ba7c4de8b815510ec7024dc287538d26 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 20 Oct 2017 11:06:19 +0200 +Subject: [PATCH 11/11] cirrus: fix oob access in mode4and5 write functions + +RH-Author: Gerd Hoffmann +Message-id: <20171020110619.2541-12-kraxel@redhat.com> +Patchwork-id: 77403 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 11/11] cirrus: fix oob access in mode4and5 write functions +Bugzilla: 1501294 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +Move dst calculation into the loop, so we apply the mask on each +interation and will not overflow vga memory. + +Cc: Prasad J Pandit +Reported-by: Niu Guoxiang +Signed-off-by: Gerd Hoffmann +Message-id: 20171011084314.21752-1-kraxel@redhat.com +(cherry picked from commit eb38e1bc3740725ca29a535351de94107ec58d51) +Signed-off-by: Miroslav Rezanina +--- + hw/display/cirrus_vga.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index c1324ab..a07fa9c 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -2023,15 +2023,14 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, + unsigned val = mem_value; + uint8_t *dst; + +- dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); + for (x = 0; x < 8; x++) { ++ dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask); + if (val & 0x80) { + *dst = s->cirrus_shadow_gr1; + } else if (mode == 5) { + *dst = s->cirrus_shadow_gr0; + } + val <<= 1; +- dst++; + } + memory_region_set_dirty(&s->vga.vram, offset, 8); + } +@@ -2045,8 +2044,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, + unsigned val = mem_value; + uint8_t *dst; + +- dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); + for (x = 0; x < 8; x++) { ++ dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1); + if (val & 0x80) { + *dst = s->cirrus_shadow_gr1; + *(dst + 1) = s->vga.gr[0x11]; +@@ -2055,7 +2054,6 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, + *(dst + 1) = s->vga.gr[0x10]; + } + val <<= 1; +- dst += 2; + } + memory_region_set_dirty(&s->vga.vram, offset, 16); + } +-- +1.8.3.1 + diff --git a/SOURCES/kvm-hw-use-ld_p-st_p-instead-of-ld_raw-st_raw.patch b/SOURCES/kvm-hw-use-ld_p-st_p-instead-of-ld_raw-st_raw.patch new file mode 100644 index 0000000..071baa0 --- /dev/null +++ b/SOURCES/kvm-hw-use-ld_p-st_p-instead-of-ld_raw-st_raw.patch @@ -0,0 +1,518 @@ +From e4c72f672ead22ca78bbdef54517c120f39cf531 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:14 +0200 +Subject: [PATCH 02/11] hw: use ld_p/st_p instead of ld_raw/st_raw + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-3-kraxel@redhat.com> +Patchwork-id: 76827 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 2/7] hw: use ld_p/st_p instead of ld_raw/st_raw +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Paolo Bonzini + +The ld_raw and st_raw definitions are only needed in code that +must compile for both user-mode and softmmu emulation. Device +models can use the equivalent ld_p/st_p which are simple +pointer accessors. + +Reviewed-by: Peter Maydell +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0983979b3a5edbff399c092b90c8be6dc656f2a4) + +[ rhel: drop hw/arm/nseries.c chunk ] + +Signed-off-by: Miroslav Rezanina +--- + hw/9pfs/virtio-9p-device.c | 2 +- + hw/block/virtio-blk.c | 12 +-- + hw/display/omap_lcd_template.h | 10 +-- + hw/display/sm501_template.h | 6 +- + hw/display/vga_template.h | 4 +- + hw/mips/mips_fulong2e.c | 28 +++---- + hw/mips/mips_malta.c | 176 ++++++++++++++++++++--------------------- + hw/scsi/vhost-scsi.c | 4 +- + hw/scsi/virtio-scsi.c | 28 +++---- + 9 files changed, 135 insertions(+), 135 deletions(-) + +diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c +index 69d781d..0658b2d 100644 +--- a/hw/9pfs/virtio-9p-device.c ++++ b/hw/9pfs/virtio-9p-device.c +@@ -34,7 +34,7 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config) + + len = strlen(s->tag); + cfg = g_malloc0(sizeof(struct virtio_9p_config) + len); +- stw_raw(&cfg->tag_len, len); ++ stw_p(&cfg->tag_len, len); + /* We don't copy the terminating null to config space */ + memcpy(cfg->tag, s->tag, len); + memcpy(config, cfg, s->config_size); +diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c +index 462ac81..50ada79 100644 +--- a/hw/block/virtio-blk.c ++++ b/hw/block/virtio-blk.c +@@ -508,12 +508,12 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) + + bdrv_get_geometry(s->bs, &capacity); + memset(&blkcfg, 0, sizeof(blkcfg)); +- stq_raw(&blkcfg.capacity, capacity); +- stl_raw(&blkcfg.seg_max, 128 - 2); +- stw_raw(&blkcfg.cylinders, s->conf->cyls); +- stl_raw(&blkcfg.blk_size, blk_size); +- stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size); +- stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size); ++ stq_p(&blkcfg.capacity, capacity); ++ stl_p(&blkcfg.seg_max, 128 - 2); ++ stw_p(&blkcfg.cylinders, s->conf->cyls); ++ stl_p(&blkcfg.blk_size, blk_size); ++ stw_p(&blkcfg.min_io_size, s->conf->min_io_size / blk_size); ++ stw_p(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size); + blkcfg.heads = s->conf->heads; + /* + * We must ensure that the block device capacity is a multiple of +diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h +index 2fb96f8..e5dd447 100644 +--- a/hw/display/omap_lcd_template.h ++++ b/hw/display/omap_lcd_template.h +@@ -50,7 +50,7 @@ static void glue(draw_line2_, DEPTH)(void *opaque, + uint8_t v, r, g, b; + + do { +- v = ldub_raw((void *) s); ++ v = ldub_p((void *) s); + r = (pal[v & 3] >> 4) & 0xf0; + g = pal[v & 3] & 0xf0; + b = (pal[v & 3] << 4) & 0xf0; +@@ -89,7 +89,7 @@ static void glue(draw_line4_, DEPTH)(void *opaque, + uint8_t v, r, g, b; + + do { +- v = ldub_raw((void *) s); ++ v = ldub_p((void *) s); + r = (pal[v & 0xf] >> 4) & 0xf0; + g = pal[v & 0xf] & 0xf0; + b = (pal[v & 0xf] << 4) & 0xf0; +@@ -116,7 +116,7 @@ static void glue(draw_line8_, DEPTH)(void *opaque, + uint8_t v, r, g, b; + + do { +- v = ldub_raw((void *) s); ++ v = ldub_p((void *) s); + r = (pal[v] >> 4) & 0xf0; + g = pal[v] & 0xf0; + b = (pal[v] << 4) & 0xf0; +@@ -136,7 +136,7 @@ static void glue(draw_line12_, DEPTH)(void *opaque, + uint8_t r, g, b; + + do { +- v = lduw_raw((void *) s); ++ v = lduw_p((void *) s); + r = (v >> 4) & 0xf0; + g = v & 0xf0; + b = (v << 4) & 0xf0; +@@ -159,7 +159,7 @@ static void glue(draw_line16_, DEPTH)(void *opaque, + uint8_t r, g, b; + + do { +- v = lduw_raw((void *) s); ++ v = lduw_p((void *) s); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; +diff --git a/hw/display/sm501_template.h b/hw/display/sm501_template.h +index 2d4a3d8..87374f5 100644 +--- a/hw/display/sm501_template.h ++++ b/hw/display/sm501_template.h +@@ -47,7 +47,7 @@ static void glue(draw_line8_, PIXEL_NAME)( + { + uint8_t v, r, g, b; + do { +- v = ldub_raw(s); ++ v = ldub_p(s); + r = (pal[v] >> 16) & 0xff; + g = (pal[v] >> 8) & 0xff; + b = (pal[v] >> 0) & 0xff; +@@ -64,7 +64,7 @@ static void glue(draw_line16_, PIXEL_NAME)( + uint8_t r, g, b; + + do { +- rgb565 = lduw_raw(s); ++ rgb565 = lduw_p(s); + r = ((rgb565 >> 11) & 0x1f) << 3; + g = ((rgb565 >> 5) & 0x3f) << 2; + b = ((rgb565 >> 0) & 0x1f) << 3; +@@ -80,7 +80,7 @@ static void glue(draw_line32_, PIXEL_NAME)( + uint8_t r, g, b; + + do { +- ldub_raw(s); ++ ldub_p(s); + #if defined(TARGET_WORDS_BIGENDIAN) + r = s[1]; + g = s[2]; +diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h +index 6cfae56..90ec9c2 100644 +--- a/hw/display/vga_template.h ++++ b/hw/display/vga_template.h +@@ -361,7 +361,7 @@ static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + + w = width; + do { +- v = lduw_raw((void *)s); ++ v = lduw_p((void *)s); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; +@@ -386,7 +386,7 @@ static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + + w = width; + do { +- v = lduw_raw((void *)s); ++ v = lduw_p((void *)s); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; +diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c +index 1aac93a..31c67c6 100644 +--- a/hw/mips/mips_fulong2e.c ++++ b/hw/mips/mips_fulong2e.c +@@ -176,24 +176,24 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, int64_t kernel_a + /* Small bootloader */ + p = (uint32_t *) base; + +- stl_raw(p++, 0x0bf00010); /* j 0x1fc00040 */ +- stl_raw(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x0bf00010); /* j 0x1fc00040 */ ++ stl_p(p++, 0x00000000); /* nop */ + + /* Second part of the bootloader */ + p = (uint32_t *) (base + 0x040); + +- stl_raw(p++, 0x3c040000); /* lui a0, 0 */ +- stl_raw(p++, 0x34840002); /* ori a0, a0, 2 */ +- stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */ +- stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */ +- stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ +- stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ +- stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(env->ram_size) */ +- stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */ +- stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff)); /* lui ra, high(kernel_addr) */; +- stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff)); /* ori ra, ra, low(kernel_addr) */ +- stl_raw(p++, 0x03e00008); /* jr ra */ +- stl_raw(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x3c040000); /* lui a0, 0 */ ++ stl_p(p++, 0x34840002); /* ori a0, a0, 2 */ ++ stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */ ++ stl_p(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a0, low(ENVP_ADDR) */ ++ stl_p(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ ++ stl_p(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ ++ stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(env->ram_size) */ ++ stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(env->ram_size) */ ++ stl_p(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff)); /* lui ra, high(kernel_addr) */; ++ stl_p(p++, 0x37ff0000 | (kernel_addr & 0xffff)); /* ori ra, ra, low(kernel_addr) */ ++ stl_p(p++, 0x03e00008); /* jr ra */ ++ stl_p(p++, 0x00000000); /* nop */ + } + + +diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c +index 9d521cc..cf719de 100644 +--- a/hw/mips/mips_malta.c ++++ b/hw/mips/mips_malta.c +@@ -514,136 +514,136 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, + + /* Small bootloader */ + p = (uint32_t *)base; +- stl_raw(p++, 0x0bf00160); /* j 0x1fc00580 */ +- stl_raw(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x0bf00160); /* j 0x1fc00580 */ ++ stl_p(p++, 0x00000000); /* nop */ + + /* YAMON service vector */ +- stl_raw(base + 0x500, 0xbfc00580); /* start: */ +- stl_raw(base + 0x504, 0xbfc0083c); /* print_count: */ +- stl_raw(base + 0x520, 0xbfc00580); /* start: */ +- stl_raw(base + 0x52c, 0xbfc00800); /* flush_cache: */ +- stl_raw(base + 0x534, 0xbfc00808); /* print: */ +- stl_raw(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */ +- stl_raw(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */ +- stl_raw(base + 0x540, 0xbfc00800); /* reg_ic_isr: */ +- stl_raw(base + 0x544, 0xbfc00800); /* unred_ic_isr: */ +- stl_raw(base + 0x548, 0xbfc00800); /* reg_esr: */ +- stl_raw(base + 0x54c, 0xbfc00800); /* unreg_esr: */ +- stl_raw(base + 0x550, 0xbfc00800); /* getchar: */ +- stl_raw(base + 0x554, 0xbfc00800); /* syscon_read: */ ++ stl_p(base + 0x500, 0xbfc00580); /* start: */ ++ stl_p(base + 0x504, 0xbfc0083c); /* print_count: */ ++ stl_p(base + 0x520, 0xbfc00580); /* start: */ ++ stl_p(base + 0x52c, 0xbfc00800); /* flush_cache: */ ++ stl_p(base + 0x534, 0xbfc00808); /* print: */ ++ stl_p(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */ ++ stl_p(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */ ++ stl_p(base + 0x540, 0xbfc00800); /* reg_ic_isr: */ ++ stl_p(base + 0x544, 0xbfc00800); /* unred_ic_isr: */ ++ stl_p(base + 0x548, 0xbfc00800); /* reg_esr: */ ++ stl_p(base + 0x54c, 0xbfc00800); /* unreg_esr: */ ++ stl_p(base + 0x550, 0xbfc00800); /* getchar: */ ++ stl_p(base + 0x554, 0xbfc00800); /* syscon_read: */ + + + /* Second part of the bootloader */ + p = (uint32_t *) (base + 0x580); +- stl_raw(p++, 0x24040002); /* addiu a0, zero, 2 */ +- stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */ +- stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */ +- stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */ +- stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */ +- stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ +- stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ +- stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */ +- stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */ ++ stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ ++ stl_p(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */ ++ stl_p(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */ ++ stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */ ++ stl_p(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */ ++ stl_p(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */ ++ stl_p(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */ ++ stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */ ++ stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */ + + /* Load BAR registers as done by YAMON */ +- stl_raw(p++, 0x3c09b400); /* lui t1, 0xb400 */ ++ stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ + + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c08df00); /* lui t0, 0xdf00 */ ++ stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */ + #else +- stl_raw(p++, 0x340800df); /* ori t0, r0, 0x00df */ ++ stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */ + #endif +- stl_raw(p++, 0xad280068); /* sw t0, 0x0068(t1) */ ++ stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */ + +- stl_raw(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ ++ stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ + + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c08c000); /* lui t0, 0xc000 */ ++ stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */ + #else +- stl_raw(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ ++ stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ + #endif +- stl_raw(p++, 0xad280048); /* sw t0, 0x0048(t1) */ ++ stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */ + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c084000); /* lui t0, 0x4000 */ ++ stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */ + #else +- stl_raw(p++, 0x34080040); /* ori t0, r0, 0x0040 */ ++ stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */ + #endif +- stl_raw(p++, 0xad280050); /* sw t0, 0x0050(t1) */ ++ stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */ + + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c088000); /* lui t0, 0x8000 */ ++ stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */ + #else +- stl_raw(p++, 0x34080080); /* ori t0, r0, 0x0080 */ ++ stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */ + #endif +- stl_raw(p++, 0xad280058); /* sw t0, 0x0058(t1) */ ++ stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */ + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c083f00); /* lui t0, 0x3f00 */ ++ stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */ + #else +- stl_raw(p++, 0x3408003f); /* ori t0, r0, 0x003f */ ++ stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */ + #endif +- stl_raw(p++, 0xad280060); /* sw t0, 0x0060(t1) */ ++ stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */ + + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c08c100); /* lui t0, 0xc100 */ ++ stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */ + #else +- stl_raw(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ ++ stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ + #endif +- stl_raw(p++, 0xad280080); /* sw t0, 0x0080(t1) */ ++ stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */ + #ifdef TARGET_WORDS_BIGENDIAN +- stl_raw(p++, 0x3c085e00); /* lui t0, 0x5e00 */ ++ stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */ + #else +- stl_raw(p++, 0x3408005e); /* ori t0, r0, 0x005e */ ++ stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */ + #endif +- stl_raw(p++, 0xad280088); /* sw t0, 0x0088(t1) */ ++ stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ + + /* Jump to kernel code */ +- stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ +- stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ +- stl_raw(p++, 0x03e00008); /* jr ra */ +- stl_raw(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ ++ stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ ++ stl_p(p++, 0x03e00008); /* jr ra */ ++ stl_p(p++, 0x00000000); /* nop */ + + /* YAMON subroutines */ + p = (uint32_t *) (base + 0x800); +- stl_raw(p++, 0x03e00008); /* jr ra */ +- stl_raw(p++, 0x24020000); /* li v0,0 */ ++ stl_p(p++, 0x03e00008); /* jr ra */ ++ stl_p(p++, 0x24020000); /* li v0,0 */ + /* 808 YAMON print */ +- stl_raw(p++, 0x03e06821); /* move t5,ra */ +- stl_raw(p++, 0x00805821); /* move t3,a0 */ +- stl_raw(p++, 0x00a05021); /* move t2,a1 */ +- stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */ +- stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */ +- stl_raw(p++, 0x10800005); /* beqz a0,834 */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x0ff0021c); /* jal 870 */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x08000205); /* j 814 */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x01a00008); /* jr t5 */ +- stl_raw(p++, 0x01602021); /* move a0,t3 */ ++ stl_p(p++, 0x03e06821); /* move t5,ra */ ++ stl_p(p++, 0x00805821); /* move t3,a0 */ ++ stl_p(p++, 0x00a05021); /* move t2,a1 */ ++ stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ ++ stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ ++ stl_p(p++, 0x10800005); /* beqz a0,834 */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x0ff0021c); /* jal 870 */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x08000205); /* j 814 */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x01a00008); /* jr t5 */ ++ stl_p(p++, 0x01602021); /* move a0,t3 */ + /* 0x83c YAMON print_count */ +- stl_raw(p++, 0x03e06821); /* move t5,ra */ +- stl_raw(p++, 0x00805821); /* move t3,a0 */ +- stl_raw(p++, 0x00a05021); /* move t2,a1 */ +- stl_raw(p++, 0x00c06021); /* move t4,a2 */ +- stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */ +- stl_raw(p++, 0x0ff0021c); /* jal 870 */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */ +- stl_raw(p++, 0x258cffff); /* addiu t4,t4,-1 */ +- stl_raw(p++, 0x1580fffa); /* bnez t4,84c */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x01a00008); /* jr t5 */ +- stl_raw(p++, 0x01602021); /* move a0,t3 */ ++ stl_p(p++, 0x03e06821); /* move t5,ra */ ++ stl_p(p++, 0x00805821); /* move t3,a0 */ ++ stl_p(p++, 0x00a05021); /* move t2,a1 */ ++ stl_p(p++, 0x00c06021); /* move t4,a2 */ ++ stl_p(p++, 0x91440000); /* lbu a0,0(t2) */ ++ stl_p(p++, 0x0ff0021c); /* jal 870 */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */ ++ stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */ ++ stl_p(p++, 0x1580fffa); /* bnez t4,84c */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x01a00008); /* jr t5 */ ++ stl_p(p++, 0x01602021); /* move a0,t3 */ + /* 0x870 */ +- stl_raw(p++, 0x3c08b800); /* lui t0,0xb400 */ +- stl_raw(p++, 0x350803f8); /* ori t0,t0,0x3f8 */ +- stl_raw(p++, 0x91090005); /* lbu t1,5(t0) */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x31290040); /* andi t1,t1,0x40 */ +- stl_raw(p++, 0x1120fffc); /* beqz t1,878 */ +- stl_raw(p++, 0x00000000); /* nop */ +- stl_raw(p++, 0x03e00008); /* jr ra */ +- stl_raw(p++, 0xa1040000); /* sb a0,0(t0) */ ++ stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */ ++ stl_p(p++, 0x350803f8); /* ori t0,t0,0x3f8 */ ++ stl_p(p++, 0x91090005); /* lbu t1,5(t0) */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */ ++ stl_p(p++, 0x1120fffc); /* beqz t1,878 */ ++ stl_p(p++, 0x00000000); /* nop */ ++ stl_p(p++, 0x03e00008); /* jr ra */ ++ stl_p(p++, 0xa1040000); /* sb a0,0(t0) */ + + } + +diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c +index 5e3cc61..96c4fb7 100644 +--- a/hw/scsi/vhost-scsi.c ++++ b/hw/scsi/vhost-scsi.c +@@ -164,8 +164,8 @@ static void vhost_scsi_set_config(VirtIODevice *vdev, + VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); + +- if ((uint32_t) ldl_raw(&scsiconf->sense_size) != vs->sense_size || +- (uint32_t) ldl_raw(&scsiconf->cdb_size) != vs->cdb_size) { ++ if ((uint32_t) ldl_p(&scsiconf->sense_size) != vs->sense_size || ++ (uint32_t) ldl_p(&scsiconf->cdb_size) != vs->cdb_size) { + error_report("vhost-scsi does not support changing the sense data and CDB sizes"); + exit(1); + } +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index 808eb54..0b2dc9c 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -423,16 +423,16 @@ static void virtio_scsi_get_config(VirtIODevice *vdev, + VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; + VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(vdev); + +- stl_raw(&scsiconf->num_queues, s->conf.num_queues); +- stl_raw(&scsiconf->seg_max, 128 - 2); +- stl_raw(&scsiconf->max_sectors, s->conf.max_sectors); +- stl_raw(&scsiconf->cmd_per_lun, s->conf.cmd_per_lun); +- stl_raw(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent)); +- stl_raw(&scsiconf->sense_size, s->sense_size); +- stl_raw(&scsiconf->cdb_size, s->cdb_size); +- stw_raw(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL); +- stw_raw(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET); +- stl_raw(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN); ++ stl_p(&scsiconf->num_queues, s->conf.num_queues); ++ stl_p(&scsiconf->seg_max, 128 - 2); ++ stl_p(&scsiconf->max_sectors, s->conf.max_sectors); ++ stl_p(&scsiconf->cmd_per_lun, s->conf.cmd_per_lun); ++ stl_p(&scsiconf->event_info_size, sizeof(VirtIOSCSIEvent)); ++ stl_p(&scsiconf->sense_size, s->sense_size); ++ stl_p(&scsiconf->cdb_size, s->cdb_size); ++ stw_p(&scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL); ++ stw_p(&scsiconf->max_target, VIRTIO_SCSI_MAX_TARGET); ++ stl_p(&scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN); + } + + static void virtio_scsi_set_config(VirtIODevice *vdev, +@@ -441,14 +441,14 @@ static void virtio_scsi_set_config(VirtIODevice *vdev, + VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); + +- if ((uint32_t) ldl_raw(&scsiconf->sense_size) >= 65536 || +- (uint32_t) ldl_raw(&scsiconf->cdb_size) >= 256) { ++ if ((uint32_t) ldl_p(&scsiconf->sense_size) >= 65536 || ++ (uint32_t) ldl_p(&scsiconf->cdb_size) >= 256) { + error_report("bad data written to virtio-scsi configuration space"); + exit(1); + } + +- vs->sense_size = ldl_raw(&scsiconf->sense_size); +- vs->cdb_size = ldl_raw(&scsiconf->cdb_size); ++ vs->sense_size = ldl_p(&scsiconf->sense_size); ++ vs->cdb_size = ldl_p(&scsiconf->cdb_size); + } + + static uint32_t virtio_scsi_get_features(VirtIODevice *vdev, +-- +1.8.3.1 + diff --git a/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch b/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch new file mode 100644 index 0000000..33f5c9b --- /dev/null +++ b/SOURCES/kvm-multiboot-validate-multiboot-header-address-values.patch @@ -0,0 +1,74 @@ +From 65550e3682fd27304c905e4627c3cd9f5840c260 Mon Sep 17 00:00:00 2001 +From: Bandan Das +Date: Thu, 26 Oct 2017 10:03:48 +0200 +Subject: [PATCH] multiboot: validate multiboot header address values + +RH-Author: Bandan Das +Message-id: +Patchwork-id: 77443 +O-Subject: [RHEL-7.5 qemu-kvm PATCH] multiboot: validate multiboot header address values +Bugzilla: 1501120 +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier +RH-Acked-by: Peter Xu + +While loading kernel via multiboot-v1 image, (flags & 0x00010000) +indicates that multiboot header contains valid addresses to load +the kernel image. These addresses are used to compute kernel +size and kernel text offset in the OS image. Validate these +address values to avoid an OOB access issue. + +This is CVE-2017-14167. + +Reported-by: Thomas Garnier +Signed-off-by: Prasad J Pandit +Message-Id: <20170907063256.7418-1-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb) +Signed-off-by: Miroslav Rezanina +--- + hw/i386/multiboot.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c +index 09211e0..7eec230 100644 +--- a/hw/i386/multiboot.c ++++ b/hw/i386/multiboot.c +@@ -200,15 +200,34 @@ int load_multiboot(FWCfgState *fw_cfg, + uint32_t mh_header_addr = ldl_p(header+i+12); + uint32_t mh_load_end_addr = ldl_p(header+i+20); + uint32_t mh_bss_end_addr = ldl_p(header+i+24); ++ + mh_load_addr = ldl_p(header+i+16); ++ if (mh_header_addr < mh_load_addr) { ++ fprintf(stderr, "invalid mh_load_addr address\n"); ++ exit(1); ++ } ++ + uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); + uint32_t mb_load_size = 0; + mh_entry_addr = ldl_p(header+i+28); + + if (mh_load_end_addr) { ++ if (mh_bss_end_addr < mh_load_addr) { ++ fprintf(stderr, "invalid mh_bss_end_addr address\n"); ++ exit(1); ++ } + mb_kernel_size = mh_bss_end_addr - mh_load_addr; ++ ++ if (mh_load_end_addr < mh_load_addr) { ++ fprintf(stderr, "invalid mh_load_end_addr address\n"); ++ exit(1); ++ } + mb_load_size = mh_load_end_addr - mh_load_addr; + } else { ++ if (kernel_file_size < mb_kernel_text_offset) { ++ fprintf(stderr, "invalid kernel_file_size\n"); ++ exit(1); ++ } + mb_kernel_size = kernel_file_size - mb_kernel_text_offset; + mb_load_size = mb_kernel_size; + } +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-Add-mechanism-to-force-the-use-of-a-shadow-surfa.patch b/SOURCES/kvm-vga-Add-mechanism-to-force-the-use-of-a-shadow-surfa.patch new file mode 100644 index 0000000..144892b --- /dev/null +++ b/SOURCES/kvm-vga-Add-mechanism-to-force-the-use-of-a-shadow-surfa.patch @@ -0,0 +1,88 @@ +From c7b591dff2d72eb1571f05d7f328471954980966 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 20 Oct 2017 11:06:17 +0200 +Subject: [PATCH 09/11] vga: Add mechanism to force the use of a shadow surface + +RH-Author: Gerd Hoffmann +Message-id: <20171020110619.2541-10-kraxel@redhat.com> +Patchwork-id: 77409 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 09/11] vga: Add mechanism to force the use of a shadow surface +Bugzilla: 1501294 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +From: Benjamin Herrenschmidt + +This prevents surface sharing which will be necessary to +fix cirrus HW cursor support. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 5508099397c480f1c3b4f14b0e64593ebe284b26) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 17 +++++++++++++++-- + hw/display/vga_int.h | 1 + + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index dda3f5f..a343a0a 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1510,6 +1510,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + uint8_t *d; + uint32_t v, addr1, addr; + vga_draw_line_func *vga_draw_line; ++ bool share_surface; + #if defined(TARGET_WORDS_BIGENDIAN) + static const bool big_endian_fb = true; + #else +@@ -1558,18 +1559,30 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + } + + depth = s->get_bpp(s); ++ ++ share_surface = (!s->force_shadow) && ++ ( depth == 32 || (depth == 16 && !byteswap) ); + if (s->line_offset != s->last_line_offset || + disp_width != s->last_width || + height != s->last_height || +- s->last_depth != depth) { +- if (depth == 32 || (depth == 16 && !byteswap)) { ++ s->last_depth != depth || ++ share_surface != is_buffer_shared(surface)) { ++ if (share_surface) { + surface = qemu_create_displaysurface_from(disp_width, + height, depth, s->line_offset, + s->vram_ptr + (s->start_addr * 4), byteswap); + dpy_gfx_replace_surface(s->con, surface); ++#ifdef DEBUG_VGA ++ printf("VGA: Using shared surface for depth=%d swap=%d\n", ++ depth, byteswap); ++#endif + } else { + qemu_console_resize(s->con, disp_width, height); + surface = qemu_console_surface(s->con); ++#ifdef DEBUG_VGA ++ printf("VGA: Using shadow surface for depth=%d swap=%d\n", ++ depth, byteswap); ++#endif + } + s->last_scr_width = disp_width; + s->last_scr_height = height; +diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h +index 94add2f..5b9ca87 100644 +--- a/hw/display/vga_int.h ++++ b/hw/display/vga_int.h +@@ -149,6 +149,7 @@ typedef struct VGACommonState { + uint32_t last_width, last_height; /* in chars or pixels */ + uint32_t last_scr_width, last_scr_height; /* in pixels */ + uint32_t last_depth; /* in bits */ ++ bool force_shadow; + uint8_t cursor_start, cursor_end; + bool cursor_visible_phase; + int64_t cursor_blink_time; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-Remove-remainder-of-old-conversion-cruft.patch b/SOURCES/kvm-vga-Remove-remainder-of-old-conversion-cruft.patch new file mode 100644 index 0000000..189ccca --- /dev/null +++ b/SOURCES/kvm-vga-Remove-remainder-of-old-conversion-cruft.patch @@ -0,0 +1,559 @@ +From 83143be104bdf9d750078d4331c53c66581f7b26 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:16 +0200 +Subject: [PATCH 04/11] vga: Remove remainder of old conversion cruft + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-5-kraxel@redhat.com> +Patchwork-id: 76826 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 4/7] vga: Remove remainder of old conversion cruft +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Benjamin Herrenschmidt + +All the macros used to generate different versions of vga_template.h +are now unnecessary, take them all out and remove the _32 suffix from +most functions. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Gerd Hoffmann +Reviewed-by: David Gibson +(cherry picked from commit d2e043a804141ec0a896270d25d6ae370c473ddd) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 46 +++++----- + hw/display/vga_template.h | 227 +++++++++++++++------------------------------- + 2 files changed, 95 insertions(+), 178 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index dab75a3..1a292a9 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1047,10 +1047,8 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) + typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width); + +-#define DEPTH 32 + #include "vga_template.h" + +- + static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) + { + unsigned int col; +@@ -1349,19 +1347,19 @@ static void vga_draw_text(VGACommonState *s, int full_update) + bgcol = palette[cattr >> 4]; + fgcol = palette[cattr & 0x0f]; + if (cw == 16) { +- vga_draw_glyph16_32(d1, linesize, +- font_ptr, cheight, fgcol, bgcol); ++ vga_draw_glyph16(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol); + } else if (cw != 9) { +- vga_draw_glyph8_32(d1, linesize, +- font_ptr, cheight, fgcol, bgcol); ++ vga_draw_glyph8(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol); + } else { + dup9 = 0; + if (ch >= 0xb0 && ch <= 0xdf && + (s->ar[VGA_ATC_MODE] & 0x04)) { + dup9 = 1; + } +- vga_draw_glyph9_32(d1, linesize, +- font_ptr, cheight, fgcol, bgcol, dup9); ++ vga_draw_glyph9(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol, dup9); + } + if (src == cursor_ptr && + !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && +@@ -1377,14 +1375,14 @@ static void vga_draw_text(VGACommonState *s, int full_update) + h = line_last - line_start + 1; + d = d1 + linesize * line_start; + if (cw == 16) { +- vga_draw_glyph16_32(d, linesize, +- cursor_glyph, h, fgcol, bgcol); ++ vga_draw_glyph16(d, linesize, ++ cursor_glyph, h, fgcol, bgcol); + } else if (cw != 9) { +- vga_draw_glyph8_32(d, linesize, +- cursor_glyph, h, fgcol, bgcol); ++ vga_draw_glyph8(d, linesize, ++ cursor_glyph, h, fgcol, bgcol); + } else { +- vga_draw_glyph9_32(d, linesize, +- cursor_glyph, h, fgcol, bgcol, 1); ++ vga_draw_glyph9(d, linesize, ++ cursor_glyph, h, fgcol, bgcol, 1); + } + } + } +@@ -1422,16 +1420,16 @@ enum { + }; + + static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { +- vga_draw_line2_32, +- vga_draw_line2d2_32, +- vga_draw_line4_32, +- vga_draw_line4d2_32, +- vga_draw_line8d2_32, +- vga_draw_line8_32, +- vga_draw_line15_32, +- vga_draw_line16_32, +- vga_draw_line24_32, +- vga_draw_line32_32, ++ vga_draw_line2, ++ vga_draw_line2d2, ++ vga_draw_line4, ++ vga_draw_line4d2, ++ vga_draw_line8d2, ++ vga_draw_line8, ++ vga_draw_line15, ++ vga_draw_line16, ++ vga_draw_line24, ++ vga_draw_line32, + }; + + static int vga_get_bpp(VGACommonState *s) +diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h +index 90ec9c2..0660b52 100644 +--- a/hw/display/vga_template.h ++++ b/hw/display/vga_template.h +@@ -22,41 +22,9 @@ + * THE SOFTWARE. + */ + +-#if DEPTH == 8 +-#define BPP 1 +-#define PIXEL_TYPE uint8_t +-#elif DEPTH == 15 || DEPTH == 16 +-#define BPP 2 +-#define PIXEL_TYPE uint16_t +-#elif DEPTH == 32 +-#define BPP 4 +-#define PIXEL_TYPE uint32_t +-#else +-#error unsupport depth +-#endif +- +-#ifdef BGR_FORMAT +-#define PIXEL_NAME glue(DEPTH, bgr) +-#else +-#define PIXEL_NAME DEPTH +-#endif /* BGR_FORMAT */ +- +-#if DEPTH != 15 && !defined(BGR_FORMAT) +- +-static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, +- uint32_t font_data, +- uint32_t xorcol, +- uint32_t bgcol) ++static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data, ++ uint32_t xorcol, uint32_t bgcol) + { +-#if BPP == 1 +- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol; +- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; +-#elif BPP == 2 +- ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; +- ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol; +- ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol; +- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; +-#else + ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; + ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; +@@ -65,25 +33,24 @@ static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, + ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; +-#endif + } + +-static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol) ++static void vga_draw_glyph8(uint8_t *d, int linesize, ++ const uint8_t *font_ptr, int h, ++ uint32_t fgcol, uint32_t bgcol) + { + uint32_t font_data, xorcol; + + xorcol = bgcol ^ fgcol; + do { + font_data = font_ptr[0]; +- glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol); ++ vga_draw_glyph_line(d, font_data, xorcol, bgcol); + font_ptr += 4; + d += linesize; + } while (--h); + } + +-static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize, ++static void vga_draw_glyph16(uint8_t *d, int linesize, + const uint8_t *font_ptr, int h, + uint32_t fgcol, uint32_t bgcol) + { +@@ -92,48 +59,24 @@ static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize, + xorcol = bgcol ^ fgcol; + do { + font_data = font_ptr[0]; +- glue(vga_draw_glyph_line_, DEPTH)(d, +- expand4to8[font_data >> 4], +- xorcol, bgcol); +- glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP, +- expand4to8[font_data & 0x0f], +- xorcol, bgcol); ++ vga_draw_glyph_line(d, expand4to8[font_data >> 4], ++ xorcol, bgcol); ++ vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f], ++ xorcol, bgcol); + font_ptr += 4; + d += linesize; + } while (--h); + } + +-static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol, int dup9) ++static void vga_draw_glyph9(uint8_t *d, int linesize, ++ const uint8_t *font_ptr, int h, ++ uint32_t fgcol, uint32_t bgcol, int dup9) + { + uint32_t font_data, xorcol, v; + + xorcol = bgcol ^ fgcol; + do { + font_data = font_ptr[0]; +-#if BPP == 1 +- stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol); +- v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; +- stl_p(((uint32_t *)d)+1, v); +- if (dup9) +- ((uint8_t *)d)[8] = v >> (24 * (1 - BIG)); +- else +- ((uint8_t *)d)[8] = bgcol; +- +-#elif BPP == 2 +- stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol); +- stl_p(((uint32_t *)d)+1, +- (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol); +- stl_p(((uint32_t *)d)+2, +- (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol); +- v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; +- stl_p(((uint32_t *)d)+3, v); +- if (dup9) +- ((uint16_t *)d)[8] = v >> (16 * (1 - BIG)); +- else +- ((uint16_t *)d)[8] = bgcol; +-#else + ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; + ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; + ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; +@@ -147,7 +90,6 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, + ((uint32_t *)d)[8] = v; + else + ((uint32_t *)d)[8] = bgcol; +-#endif + font_ptr += 4; + d += linesize; + } while (--h); +@@ -156,8 +98,8 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, + /* + * 4 color mode + */ +-static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t plane_mask, *palette, data, v; + int x; +@@ -170,36 +112,30 @@ static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d, + data &= plane_mask; + v = expand2[GET_PLANE(data, 0)]; + v |= expand2[GET_PLANE(data, 2)] << 2; +- ((PIXEL_TYPE *)d)[0] = palette[v >> 12]; +- ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf]; +- ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf]; +- ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf]; ++ ((uint32_t *)d)[0] = palette[v >> 12]; ++ ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf]; + + v = expand2[GET_PLANE(data, 1)]; + v |= expand2[GET_PLANE(data, 3)] << 2; +- ((PIXEL_TYPE *)d)[4] = palette[v >> 12]; +- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf]; +- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf]; +- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf]; +- d += BPP * 8; ++ ((uint32_t *)d)[4] = palette[v >> 12]; ++ ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; ++ d += 32; + s += 4; + } + } + +-#if BPP == 1 +-#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v) +-#elif BPP == 2 +-#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v) +-#else + #define PUT_PIXEL2(d, n, v) \ + ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v) +-#endif + + /* + * 4 color mode, dup2 horizontal + */ +-static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t plane_mask, *palette, data, v; + int x; +@@ -223,7 +159,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); + PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); + PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); +- d += BPP * 16; ++ d += 64; + s += 4; + } + } +@@ -231,8 +167,8 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + /* + * 16 color mode + */ +-static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line4(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t plane_mask, data, v, *palette; + int x; +@@ -247,15 +183,15 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, + v |= expand4[GET_PLANE(data, 1)] << 1; + v |= expand4[GET_PLANE(data, 2)] << 2; + v |= expand4[GET_PLANE(data, 3)] << 3; +- ((PIXEL_TYPE *)d)[0] = palette[v >> 28]; +- ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf]; +- ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf]; +- ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf]; +- ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf]; +- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf]; +- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf]; +- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf]; +- d += BPP * 8; ++ ((uint32_t *)d)[0] = palette[v >> 28]; ++ ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf]; ++ ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf]; ++ ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf]; ++ ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf]; ++ ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; ++ d += 32; + s += 4; + } + } +@@ -263,8 +199,8 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, + /* + * 16 color mode, dup2 horizontal + */ +-static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t plane_mask, data, v, *palette; + int x; +@@ -287,7 +223,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); + PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); + PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); +- d += BPP * 16; ++ d += 64; + s += 4; + } + } +@@ -297,8 +233,8 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + * + * XXX: add plane_mask support (never used in standard VGA modes) + */ +-static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t *palette; + int x; +@@ -310,7 +246,7 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + PUT_PIXEL2(d, 1, palette[s[1]]); + PUT_PIXEL2(d, 2, palette[s[2]]); + PUT_PIXEL2(d, 3, palette[s[3]]); +- d += BPP * 8; ++ d += 32; + s += 4; + } + } +@@ -320,8 +256,8 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, + * + * XXX: add plane_mask support (never used in standard VGA modes) + */ +-static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line8(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + uint32_t *palette; + int x; +@@ -329,33 +265,28 @@ static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d, + palette = s1->last_palette; + width >>= 3; + for(x = 0; x < width; x++) { +- ((PIXEL_TYPE *)d)[0] = palette[s[0]]; +- ((PIXEL_TYPE *)d)[1] = palette[s[1]]; +- ((PIXEL_TYPE *)d)[2] = palette[s[2]]; +- ((PIXEL_TYPE *)d)[3] = palette[s[3]]; +- ((PIXEL_TYPE *)d)[4] = palette[s[4]]; +- ((PIXEL_TYPE *)d)[5] = palette[s[5]]; +- ((PIXEL_TYPE *)d)[6] = palette[s[6]]; +- ((PIXEL_TYPE *)d)[7] = palette[s[7]]; +- d += BPP * 8; ++ ((uint32_t *)d)[0] = palette[s[0]]; ++ ((uint32_t *)d)[1] = palette[s[1]]; ++ ((uint32_t *)d)[2] = palette[s[2]]; ++ ((uint32_t *)d)[3] = palette[s[3]]; ++ ((uint32_t *)d)[4] = palette[s[4]]; ++ ((uint32_t *)d)[5] = palette[s[5]]; ++ ((uint32_t *)d)[6] = palette[s[6]]; ++ ((uint32_t *)d)[7] = palette[s[7]]; ++ d += 32; + s += 8; + } + } + +-#endif /* DEPTH != 15 */ +- + + /* XXX: optimize */ + + /* + * 15 bit color + */ +-static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line15(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { +-#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +- memcpy(d, s, width * 2); +-#else + int w; + uint32_t v, r, g, b; + +@@ -365,22 +296,18 @@ static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; +- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; +- d += BPP; ++ d += 4; + } while (--w != 0); +-#endif + } + + /* + * 16 bit color + */ +-static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line16(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { +-#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +- memcpy(d, s, width * 2); +-#else + int w; + uint32_t v, r, g, b; + +@@ -390,18 +317,17 @@ static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; +- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; +- d += BPP; ++ d += 4; + } while (--w != 0); +-#endif + } + + /* + * 24 bit color + */ +-static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line24(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + int w; + uint32_t r, g, b; +@@ -417,19 +343,19 @@ static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + g = s[1]; + r = s[2]; + #endif +- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 3; +- d += BPP; ++ d += 4; + } while (--w != 0); + } + + /* + * 32 bit color + */ +-static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line32(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { +-#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT) ++#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) + memcpy(d, s, width * 4); + #else + int w; +@@ -446,16 +372,9 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, + g = s[1]; + r = s[2]; + #endif +- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 4; +- d += BPP; ++ d += 4; + } while (--w != 0); + #endif + } +- +-#undef PUT_PIXEL2 +-#undef DEPTH +-#undef BPP +-#undef PIXEL_TYPE +-#undef PIXEL_NAME +-#undef BGR_FORMAT +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch b/SOURCES/kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch new file mode 100644 index 0000000..a028674 --- /dev/null +++ b/SOURCES/kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch @@ -0,0 +1,939 @@ +From d5e0842eca8498600dac7114a0e0a617df7f4ea4 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:18 +0200 +Subject: [PATCH 06/11] vga: Rename vga_template.h to vga-helpers.h + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-7-kraxel@redhat.com> +Patchwork-id: 76822 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 6/7] vga: Rename vga_template.h to vga-helpers.h +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Benjamin Herrenschmidt + +It's no longer a template, we only instanciate the file once. + +Keep it a #included file so the functions remain static. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Gerd Hoffmann +Reviewed-by: David Gibson +(cherry picked from commit e657d8ef3c810c4c46d3a61bb76103f77bdb499b) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga-helpers.h | 439 ++++++++++++++++++++++++++++++++++++++++++++++ + hw/display/vga.c | 2 +- + hw/display/vga_template.h | 439 ---------------------------------------------- + 3 files changed, 440 insertions(+), 440 deletions(-) + create mode 100644 hw/display/vga-helpers.h + delete mode 100644 hw/display/vga_template.h + +diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h +new file mode 100644 +index 0000000..94f6de2 +--- /dev/null ++++ b/hw/display/vga-helpers.h +@@ -0,0 +1,439 @@ ++/* ++ * QEMU VGA Emulator templates ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. ++ */ ++ ++static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data, ++ uint32_t xorcol, uint32_t bgcol) ++{ ++ ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; ++} ++ ++static void vga_draw_glyph8(uint8_t *d, int linesize, ++ const uint8_t *font_ptr, int h, ++ uint32_t fgcol, uint32_t bgcol) ++{ ++ uint32_t font_data, xorcol; ++ ++ xorcol = bgcol ^ fgcol; ++ do { ++ font_data = font_ptr[0]; ++ vga_draw_glyph_line(d, font_data, xorcol, bgcol); ++ font_ptr += 4; ++ d += linesize; ++ } while (--h); ++} ++ ++static void vga_draw_glyph16(uint8_t *d, int linesize, ++ const uint8_t *font_ptr, int h, ++ uint32_t fgcol, uint32_t bgcol) ++{ ++ uint32_t font_data, xorcol; ++ ++ xorcol = bgcol ^ fgcol; ++ do { ++ font_data = font_ptr[0]; ++ vga_draw_glyph_line(d, expand4to8[font_data >> 4], ++ xorcol, bgcol); ++ vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f], ++ xorcol, bgcol); ++ font_ptr += 4; ++ d += linesize; ++ } while (--h); ++} ++ ++static void vga_draw_glyph9(uint8_t *d, int linesize, ++ const uint8_t *font_ptr, int h, ++ uint32_t fgcol, uint32_t bgcol, int dup9) ++{ ++ uint32_t font_data, xorcol, v; ++ ++ xorcol = bgcol ^ fgcol; ++ do { ++ font_data = font_ptr[0]; ++ ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; ++ v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; ++ ((uint32_t *)d)[7] = v; ++ if (dup9) ++ ((uint32_t *)d)[8] = v; ++ else ++ ((uint32_t *)d)[8] = bgcol; ++ font_ptr += 4; ++ d += linesize; ++ } while (--h); ++} ++ ++/* ++ * 4 color mode ++ */ ++static void vga_draw_line2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t plane_mask, *palette, data, v; ++ int x; ++ ++ palette = s1->last_palette; ++ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ data = ((uint32_t *)s)[0]; ++ data &= plane_mask; ++ v = expand2[GET_PLANE(data, 0)]; ++ v |= expand2[GET_PLANE(data, 2)] << 2; ++ ((uint32_t *)d)[0] = palette[v >> 12]; ++ ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf]; ++ ++ v = expand2[GET_PLANE(data, 1)]; ++ v |= expand2[GET_PLANE(data, 3)] << 2; ++ ((uint32_t *)d)[4] = palette[v >> 12]; ++ ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; ++ d += 32; ++ s += 4; ++ } ++} ++ ++#define PUT_PIXEL2(d, n, v) \ ++((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v) ++ ++/* ++ * 4 color mode, dup2 horizontal ++ */ ++static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t plane_mask, *palette, data, v; ++ int x; ++ ++ palette = s1->last_palette; ++ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ data = ((uint32_t *)s)[0]; ++ data &= plane_mask; ++ v = expand2[GET_PLANE(data, 0)]; ++ v |= expand2[GET_PLANE(data, 2)] << 2; ++ PUT_PIXEL2(d, 0, palette[v >> 12]); ++ PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]); ++ PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]); ++ PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]); ++ ++ v = expand2[GET_PLANE(data, 1)]; ++ v |= expand2[GET_PLANE(data, 3)] << 2; ++ PUT_PIXEL2(d, 4, palette[v >> 12]); ++ PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); ++ PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); ++ PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); ++ d += 64; ++ s += 4; ++ } ++} ++ ++/* ++ * 16 color mode ++ */ ++static void vga_draw_line4(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t plane_mask, data, v, *palette; ++ int x; ++ ++ palette = s1->last_palette; ++ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ data = ((uint32_t *)s)[0]; ++ data &= plane_mask; ++ v = expand4[GET_PLANE(data, 0)]; ++ v |= expand4[GET_PLANE(data, 1)] << 1; ++ v |= expand4[GET_PLANE(data, 2)] << 2; ++ v |= expand4[GET_PLANE(data, 3)] << 3; ++ ((uint32_t *)d)[0] = palette[v >> 28]; ++ ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf]; ++ ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf]; ++ ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf]; ++ ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf]; ++ ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; ++ ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; ++ ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; ++ d += 32; ++ s += 4; ++ } ++} ++ ++/* ++ * 16 color mode, dup2 horizontal ++ */ ++static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t plane_mask, data, v, *palette; ++ int x; ++ ++ palette = s1->last_palette; ++ plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ data = ((uint32_t *)s)[0]; ++ data &= plane_mask; ++ v = expand4[GET_PLANE(data, 0)]; ++ v |= expand4[GET_PLANE(data, 1)] << 1; ++ v |= expand4[GET_PLANE(data, 2)] << 2; ++ v |= expand4[GET_PLANE(data, 3)] << 3; ++ PUT_PIXEL2(d, 0, palette[v >> 28]); ++ PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]); ++ PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]); ++ PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]); ++ PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]); ++ PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); ++ PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); ++ PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); ++ d += 64; ++ s += 4; ++ } ++} ++ ++/* ++ * 256 color mode, double pixels ++ * ++ * XXX: add plane_mask support (never used in standard VGA modes) ++ */ ++static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t *palette; ++ int x; ++ ++ palette = s1->last_palette; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ PUT_PIXEL2(d, 0, palette[s[0]]); ++ PUT_PIXEL2(d, 1, palette[s[1]]); ++ PUT_PIXEL2(d, 2, palette[s[2]]); ++ PUT_PIXEL2(d, 3, palette[s[3]]); ++ d += 32; ++ s += 4; ++ } ++} ++ ++/* ++ * standard 256 color mode ++ * ++ * XXX: add plane_mask support (never used in standard VGA modes) ++ */ ++static void vga_draw_line8(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ uint32_t *palette; ++ int x; ++ ++ palette = s1->last_palette; ++ width >>= 3; ++ for(x = 0; x < width; x++) { ++ ((uint32_t *)d)[0] = palette[s[0]]; ++ ((uint32_t *)d)[1] = palette[s[1]]; ++ ((uint32_t *)d)[2] = palette[s[2]]; ++ ((uint32_t *)d)[3] = palette[s[3]]; ++ ((uint32_t *)d)[4] = palette[s[4]]; ++ ((uint32_t *)d)[5] = palette[s[5]]; ++ ((uint32_t *)d)[6] = palette[s[6]]; ++ ((uint32_t *)d)[7] = palette[s[7]]; ++ d += 32; ++ s += 8; ++ } ++} ++ ++/* ++ * 15 bit color ++ */ ++static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_le_p((void *)s); ++ r = (v >> 7) & 0xf8; ++ g = (v >> 2) & 0xf8; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_be_p((void *)s); ++ r = (v >> 7) & 0xf8; ++ g = (v >> 2) & 0xf8; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++/* ++ * 16 bit color ++ */ ++static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_le_p((void *)s); ++ r = (v >> 8) & 0xf8; ++ g = (v >> 3) & 0xfc; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_be_p((void *)s); ++ r = (v >> 8) & 0xf8; ++ g = (v >> 3) & 0xfc; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++/* ++ * 24 bit color ++ */ ++static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ b = s[0]; ++ g = s[1]; ++ r = s[2]; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 3; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ r = s[0]; ++ g = s[1]; ++ b = s[2]; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 3; ++ d += 4; ++ } while (--w != 0); ++} ++ ++/* ++ * 32 bit color ++ */ ++static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++#ifndef HOST_WORDS_BIGENDIAN ++ memcpy(d, s, width * 4); ++#else ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ b = s[0]; ++ g = s[1]; ++ r = s[2]; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 4; ++ d += 4; ++ } while (--w != 0); ++#endif ++} ++ ++static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++#ifdef HOST_WORDS_BIGENDIAN ++ memcpy(d, s, width * 4); ++#else ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ r = s[1]; ++ g = s[2]; ++ b = s[3]; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 4; ++ d += 4; ++ } while (--w != 0); ++#endif ++} +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 50999ee..4618823 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1047,7 +1047,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) + typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width); + +-#include "vga_template.h" ++#include "vga-helpers.h" + + static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) + { +diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h +deleted file mode 100644 +index 94f6de2..0000000 +--- a/hw/display/vga_template.h ++++ /dev/null +@@ -1,439 +0,0 @@ +-/* +- * QEMU VGA Emulator templates +- * +- * Copyright (c) 2003 Fabrice Bellard +- * +- * Permission is hereby granted, free of charge, to any person obtaining a copy +- * of this software and associated documentation files (the "Software"), to deal +- * in the Software without restriction, including without limitation the rights +- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +- * copies of the Software, and to permit persons to whom the Software is +- * furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +- * THE SOFTWARE. +- */ +- +-static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data, +- uint32_t xorcol, uint32_t bgcol) +-{ +- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; +- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; +-} +- +-static void vga_draw_glyph8(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol) +-{ +- uint32_t font_data, xorcol; +- +- xorcol = bgcol ^ fgcol; +- do { +- font_data = font_ptr[0]; +- vga_draw_glyph_line(d, font_data, xorcol, bgcol); +- font_ptr += 4; +- d += linesize; +- } while (--h); +-} +- +-static void vga_draw_glyph16(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol) +-{ +- uint32_t font_data, xorcol; +- +- xorcol = bgcol ^ fgcol; +- do { +- font_data = font_ptr[0]; +- vga_draw_glyph_line(d, expand4to8[font_data >> 4], +- xorcol, bgcol); +- vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f], +- xorcol, bgcol); +- font_ptr += 4; +- d += linesize; +- } while (--h); +-} +- +-static void vga_draw_glyph9(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol, int dup9) +-{ +- uint32_t font_data, xorcol, v; +- +- xorcol = bgcol ^ fgcol; +- do { +- font_data = font_ptr[0]; +- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; +- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; +- v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; +- ((uint32_t *)d)[7] = v; +- if (dup9) +- ((uint32_t *)d)[8] = v; +- else +- ((uint32_t *)d)[8] = bgcol; +- font_ptr += 4; +- d += linesize; +- } while (--h); +-} +- +-/* +- * 4 color mode +- */ +-static void vga_draw_line2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t plane_mask, *palette, data, v; +- int x; +- +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; +- width >>= 3; +- for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; +- data &= plane_mask; +- v = expand2[GET_PLANE(data, 0)]; +- v |= expand2[GET_PLANE(data, 2)] << 2; +- ((uint32_t *)d)[0] = palette[v >> 12]; +- ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf]; +- ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf]; +- ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf]; +- +- v = expand2[GET_PLANE(data, 1)]; +- v |= expand2[GET_PLANE(data, 3)] << 2; +- ((uint32_t *)d)[4] = palette[v >> 12]; +- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; +- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; +- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; +- d += 32; +- s += 4; +- } +-} +- +-#define PUT_PIXEL2(d, n, v) \ +-((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v) +- +-/* +- * 4 color mode, dup2 horizontal +- */ +-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t plane_mask, *palette, data, v; +- int x; +- +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; +- width >>= 3; +- for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; +- data &= plane_mask; +- v = expand2[GET_PLANE(data, 0)]; +- v |= expand2[GET_PLANE(data, 2)] << 2; +- PUT_PIXEL2(d, 0, palette[v >> 12]); +- PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]); +- PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]); +- PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]); +- +- v = expand2[GET_PLANE(data, 1)]; +- v |= expand2[GET_PLANE(data, 3)] << 2; +- PUT_PIXEL2(d, 4, palette[v >> 12]); +- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); +- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); +- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); +- d += 64; +- s += 4; +- } +-} +- +-/* +- * 16 color mode +- */ +-static void vga_draw_line4(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t plane_mask, data, v, *palette; +- int x; +- +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; +- width >>= 3; +- for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; +- data &= plane_mask; +- v = expand4[GET_PLANE(data, 0)]; +- v |= expand4[GET_PLANE(data, 1)] << 1; +- v |= expand4[GET_PLANE(data, 2)] << 2; +- v |= expand4[GET_PLANE(data, 3)] << 3; +- ((uint32_t *)d)[0] = palette[v >> 28]; +- ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf]; +- ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf]; +- ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf]; +- ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf]; +- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; +- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; +- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; +- d += 32; +- s += 4; +- } +-} +- +-/* +- * 16 color mode, dup2 horizontal +- */ +-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t plane_mask, data, v, *palette; +- int x; +- +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; +- width >>= 3; +- for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; +- data &= plane_mask; +- v = expand4[GET_PLANE(data, 0)]; +- v |= expand4[GET_PLANE(data, 1)] << 1; +- v |= expand4[GET_PLANE(data, 2)] << 2; +- v |= expand4[GET_PLANE(data, 3)] << 3; +- PUT_PIXEL2(d, 0, palette[v >> 28]); +- PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]); +- PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]); +- PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]); +- PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]); +- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); +- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); +- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); +- d += 64; +- s += 4; +- } +-} +- +-/* +- * 256 color mode, double pixels +- * +- * XXX: add plane_mask support (never used in standard VGA modes) +- */ +-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t *palette; +- int x; +- +- palette = s1->last_palette; +- width >>= 3; +- for(x = 0; x < width; x++) { +- PUT_PIXEL2(d, 0, palette[s[0]]); +- PUT_PIXEL2(d, 1, palette[s[1]]); +- PUT_PIXEL2(d, 2, palette[s[2]]); +- PUT_PIXEL2(d, 3, palette[s[3]]); +- d += 32; +- s += 4; +- } +-} +- +-/* +- * standard 256 color mode +- * +- * XXX: add plane_mask support (never used in standard VGA modes) +- */ +-static void vga_draw_line8(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- uint32_t *palette; +- int x; +- +- palette = s1->last_palette; +- width >>= 3; +- for(x = 0; x < width; x++) { +- ((uint32_t *)d)[0] = palette[s[0]]; +- ((uint32_t *)d)[1] = palette[s[1]]; +- ((uint32_t *)d)[2] = palette[s[2]]; +- ((uint32_t *)d)[3] = palette[s[3]]; +- ((uint32_t *)d)[4] = palette[s[4]]; +- ((uint32_t *)d)[5] = palette[s[5]]; +- ((uint32_t *)d)[6] = palette[s[6]]; +- ((uint32_t *)d)[7] = palette[s[7]]; +- d += 32; +- s += 8; +- } +-} +- +-/* +- * 15 bit color +- */ +-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t v, r, g, b; +- +- w = width; +- do { +- v = lduw_le_p((void *)s); +- r = (v >> 7) & 0xf8; +- g = (v >> 2) & 0xf8; +- b = (v << 3) & 0xf8; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; +- d += 4; +- } while (--w != 0); +-} +- +-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t v, r, g, b; +- +- w = width; +- do { +- v = lduw_be_p((void *)s); +- r = (v >> 7) & 0xf8; +- g = (v >> 2) & 0xf8; +- b = (v << 3) & 0xf8; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; +- d += 4; +- } while (--w != 0); +-} +- +-/* +- * 16 bit color +- */ +-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t v, r, g, b; +- +- w = width; +- do { +- v = lduw_le_p((void *)s); +- r = (v >> 8) & 0xf8; +- g = (v >> 3) & 0xfc; +- b = (v << 3) & 0xf8; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; +- d += 4; +- } while (--w != 0); +-} +- +-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t v, r, g, b; +- +- w = width; +- do { +- v = lduw_be_p((void *)s); +- r = (v >> 8) & 0xf8; +- g = (v >> 3) & 0xfc; +- b = (v << 3) & 0xf8; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; +- d += 4; +- } while (--w != 0); +-} +- +-/* +- * 24 bit color +- */ +-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t r, g, b; +- +- w = width; +- do { +- b = s[0]; +- g = s[1]; +- r = s[2]; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 3; +- d += 4; +- } while (--w != 0); +-} +- +-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +- int w; +- uint32_t r, g, b; +- +- w = width; +- do { +- r = s[0]; +- g = s[1]; +- b = s[2]; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 3; +- d += 4; +- } while (--w != 0); +-} +- +-/* +- * 32 bit color +- */ +-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +-#ifndef HOST_WORDS_BIGENDIAN +- memcpy(d, s, width * 4); +-#else +- int w; +- uint32_t r, g, b; +- +- w = width; +- do { +- b = s[0]; +- g = s[1]; +- r = s[2]; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 4; +- d += 4; +- } while (--w != 0); +-#endif +-} +- +-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) +-{ +-#ifdef HOST_WORDS_BIGENDIAN +- memcpy(d, s, width * 4); +-#else +- int w; +- uint32_t r, g, b; +- +- w = width; +- do { +- r = s[1]; +- g = s[2]; +- b = s[3]; +- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 4; +- d += 4; +- } while (--w != 0); +-#endif +-} +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-Separate-LE-and-BE-conversion-functions.patch b/SOURCES/kvm-vga-Separate-LE-and-BE-conversion-functions.patch new file mode 100644 index 0000000..36b14a4 --- /dev/null +++ b/SOURCES/kvm-vga-Separate-LE-and-BE-conversion-functions.patch @@ -0,0 +1,297 @@ +From 6b22d494d91773be44318574e14cc59491c8f77f Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:17 +0200 +Subject: [PATCH 05/11] vga: Separate LE and BE conversion functions + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-6-kraxel@redhat.com> +Patchwork-id: 76824 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 5/7] vga: Separate LE and BE conversion functions +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Benjamin Herrenschmidt + +Provide different functions for converting from an LE vs a BE +framebuffer. We cannot rely on the simple cases always being +shared surfaces since cirrus will need to always shadow for +cursor emulation, so we need the full set of functions to +be able to later handle runtime switching. + +Signed-off-by: Benjamin Herrenschmidt \ +Signed-off-by: Gerd Hoffmann +Reviewed-by: David Gibson +(cherry picked from commit 46c3a8c8ebe2966cc1f7af12626f89c83d547bfb) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 43 +++++++++++------- + hw/display/vga_template.h | 109 +++++++++++++++++++++++++++++++++++----------- + 2 files changed, 112 insertions(+), 40 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 1a292a9..50999ee 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1412,10 +1412,14 @@ enum { + VGA_DRAW_LINE4D2, + VGA_DRAW_LINE8D2, + VGA_DRAW_LINE8, +- VGA_DRAW_LINE15, +- VGA_DRAW_LINE16, +- VGA_DRAW_LINE24, +- VGA_DRAW_LINE32, ++ VGA_DRAW_LINE15_LE, ++ VGA_DRAW_LINE16_LE, ++ VGA_DRAW_LINE24_LE, ++ VGA_DRAW_LINE32_LE, ++ VGA_DRAW_LINE15_BE, ++ VGA_DRAW_LINE16_BE, ++ VGA_DRAW_LINE24_BE, ++ VGA_DRAW_LINE32_BE, + VGA_DRAW_LINE_NB, + }; + +@@ -1426,10 +1430,14 @@ static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { + vga_draw_line4d2, + vga_draw_line8d2, + vga_draw_line8, +- vga_draw_line15, +- vga_draw_line16, +- vga_draw_line24, +- vga_draw_line32, ++ vga_draw_line15_le, ++ vga_draw_line16_le, ++ vga_draw_line24_le, ++ vga_draw_line32_le, ++ vga_draw_line15_be, ++ vga_draw_line16_be, ++ vga_draw_line24_be, ++ vga_draw_line32_be, + }; + + static int vga_get_bpp(VGACommonState *s) +@@ -1502,10 +1510,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + uint8_t *d; + uint32_t v, addr1, addr; + vga_draw_line_func *vga_draw_line; +-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +- static const bool byteswap = false; ++#if defined(TARGET_WORDS_BIGENDIAN) ++ static const bool big_endian_fb = true; + #else +- static const bool byteswap = true; ++ static const bool big_endian_fb = false; ++#endif ++#if defined(HOST_WORDS_BIGENDIAN) ++ static const bool byteswap = !big_endian_fb; ++#else ++ static const bool byteswap = big_endian_fb; + #endif + + full_update |= update_basic_params(s); +@@ -1606,19 +1619,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + bits = 8; + break; + case 15: +- v = VGA_DRAW_LINE15; ++ v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; + bits = 16; + break; + case 16: +- v = VGA_DRAW_LINE16; ++ v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; + bits = 16; + break; + case 24: +- v = VGA_DRAW_LINE24; ++ v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; + bits = 24; + break; + case 32: +- v = VGA_DRAW_LINE32; ++ v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; + bits = 32; + break; + } +diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h +index 0660b52..94f6de2 100644 +--- a/hw/display/vga_template.h ++++ b/hw/display/vga_template.h +@@ -278,21 +278,36 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d, + } + } + +- +-/* XXX: optimize */ +- + /* + * 15 bit color + */ +-static void vga_draw_line15(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_p((void *)s); ++ v = lduw_le_p((void *)s); ++ r = (v >> 7) & 0xf8; ++ g = (v >> 2) & 0xf8; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_be_p((void *)s); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; +@@ -305,15 +320,33 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d, + /* + * 16 bit color + */ +-static void vga_draw_line16(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_p((void *)s); ++ v = lduw_le_p((void *)s); ++ r = (v >> 8) & 0xf8; ++ g = (v >> 3) & 0xfc; ++ b = (v << 3) & 0xf8; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 2; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t v, r, g, b; ++ ++ w = width; ++ do { ++ v = lduw_be_p((void *)s); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; +@@ -326,23 +359,34 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d, + /* + * 24 bit color + */ +-static void vga_draw_line24(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { + int w; + uint32_t r, g, b; + + w = width; + do { +-#if defined(TARGET_WORDS_BIGENDIAN) +- r = s[0]; +- g = s[1]; +- b = s[2]; +-#else + b = s[0]; + g = s[1]; + r = s[2]; +-#endif ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 3; ++ d += 4; ++ } while (--w != 0); ++} ++ ++static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ r = s[0]; ++ g = s[1]; ++ b = s[2]; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 3; + d += 4; +@@ -352,10 +396,10 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d, + /* + * 32 bit color + */ +-static void vga_draw_line32(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) + { +-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) ++#ifndef HOST_WORDS_BIGENDIAN + memcpy(d, s, width * 4); + #else + int w; +@@ -363,15 +407,30 @@ static void vga_draw_line32(VGACommonState *s1, uint8_t *d, + + w = width; + do { +-#if defined(TARGET_WORDS_BIGENDIAN) +- r = s[1]; +- g = s[2]; +- b = s[3]; +-#else + b = s[0]; + g = s[1]; + r = s[2]; ++ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); ++ s += 4; ++ d += 4; ++ } while (--w != 0); + #endif ++} ++ ++static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, ++ const uint8_t *s, int width) ++{ ++#ifdef HOST_WORDS_BIGENDIAN ++ memcpy(d, s, width * 4); ++#else ++ int w; ++ uint32_t r, g, b; ++ ++ w = width; ++ do { ++ r = s[1]; ++ g = s[2]; ++ b = s[3]; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 4; + d += 4; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch b/SOURCES/kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch new file mode 100644 index 0000000..521c307 --- /dev/null +++ b/SOURCES/kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch @@ -0,0 +1,413 @@ +From 7839b693640dc53bd97279b99b1a2747883ada2a Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:15 +0200 +Subject: [PATCH 03/11] vga: Start cutting out non-32bpp conversion support + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-4-kraxel@redhat.com> +Patchwork-id: 76825 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 3/7] vga: Start cutting out non-32bpp conversion support +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +From: Benjamin Herrenschmidt + +Nowadays, we either share a surface with the host, or we create +a 32bpp ARGB console surface. + +So we only need to draw/convert to 32bpp, enabling us to remove +all but one instance of vga_template.h inclusion (to be further +cleaned up), rgb_to_pixel_* etc... + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Gerd Hoffmann +Reviewed-by: David Gibson +(cherry picked from commit 9e057c0b09c3018cd24c7a49995f8b66d5b3d1eb) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 258 +++++-------------------------------------------------- + 1 file changed, 22 insertions(+), 236 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 4e3c3f3..dab75a3 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1044,81 +1044,12 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) + } + } + +-typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol); +-typedef void vga_draw_glyph9_func(uint8_t *d, int linesize, +- const uint8_t *font_ptr, int h, +- uint32_t fgcol, uint32_t bgcol, int dup9); + typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width); + +-#define DEPTH 8 +-#include "vga_template.h" +- +-#define DEPTH 15 +-#include "vga_template.h" +- +-#define BGR_FORMAT +-#define DEPTH 15 +-#include "vga_template.h" +- +-#define DEPTH 16 +-#include "vga_template.h" +- +-#define BGR_FORMAT +-#define DEPTH 16 +-#include "vga_template.h" +- + #define DEPTH 32 + #include "vga_template.h" + +-#define BGR_FORMAT +-#define DEPTH 32 +-#include "vga_template.h" +- +-static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b) +-{ +- unsigned int col; +- col = rgb_to_pixel8(r, g, b); +- col |= col << 8; +- col |= col << 16; +- return col; +-} +- +-static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b) +-{ +- unsigned int col; +- col = rgb_to_pixel15(r, g, b); +- col |= col << 16; +- return col; +-} +- +-static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g, +- unsigned int b) +-{ +- unsigned int col; +- col = rgb_to_pixel15bgr(r, g, b); +- col |= col << 16; +- return col; +-} +- +-static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b) +-{ +- unsigned int col; +- col = rgb_to_pixel16(r, g, b); +- col |= col << 16; +- return col; +-} +- +-static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g, +- unsigned int b) +-{ +- unsigned int col; +- col = rgb_to_pixel16bgr(r, g, b); +- col |= col << 16; +- return col; +-} + + static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) + { +@@ -1127,13 +1058,6 @@ static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned + return col; + } + +-static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b) +-{ +- unsigned int col; +- col = rgb_to_pixel32bgr(r, g, b); +- return col; +-} +- + /* return true if the palette was modified */ + static int update_palette16(VGACommonState *s) + { +@@ -1240,56 +1164,6 @@ static int update_basic_params(VGACommonState *s) + return full_update; + } + +-#define NB_DEPTHS 7 +- +-static inline int get_depth_index(DisplaySurface *s) +-{ +- switch (surface_bits_per_pixel(s)) { +- default: +- case 8: +- return 0; +- case 15: +- return 1; +- case 16: +- return 2; +- case 32: +- if (is_surface_bgr(s)) { +- return 4; +- } else { +- return 3; +- } +- } +-} +- +-static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = { +- vga_draw_glyph8_8, +- vga_draw_glyph8_16, +- vga_draw_glyph8_16, +- vga_draw_glyph8_32, +- vga_draw_glyph8_32, +- vga_draw_glyph8_16, +- vga_draw_glyph8_16, +-}; +- +-static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = { +- vga_draw_glyph16_8, +- vga_draw_glyph16_16, +- vga_draw_glyph16_16, +- vga_draw_glyph16_32, +- vga_draw_glyph16_32, +- vga_draw_glyph16_16, +- vga_draw_glyph16_16, +-}; +- +-static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = { +- vga_draw_glyph9_8, +- vga_draw_glyph9_16, +- vga_draw_glyph9_16, +- vga_draw_glyph9_32, +- vga_draw_glyph9_32, +- vga_draw_glyph9_16, +- vga_draw_glyph9_16, +-}; + + static const uint8_t cursor_glyph[32 * 4] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +@@ -1341,18 +1215,6 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight + *pcheight = cheight; + } + +-typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b); +- +-static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = { +- rgb_to_pixel8_dup, +- rgb_to_pixel15_dup, +- rgb_to_pixel16_dup, +- rgb_to_pixel32_dup, +- rgb_to_pixel32bgr_dup, +- rgb_to_pixel15bgr_dup, +- rgb_to_pixel16bgr_dup, +-}; +- + /* + * Text mode update + * Missing: +@@ -1369,11 +1231,9 @@ static void vga_draw_text(VGACommonState *s, int full_update) + uint32_t offset, fgcol, bgcol, v, cursor_offset; + uint8_t *d1, *d, *src, *dest, *cursor_ptr; + const uint8_t *font_ptr, *font_base[2]; +- int dup9, line_offset, depth_index; ++ int dup9, line_offset; + uint32_t *palette; + uint32_t *ch_attr_ptr; +- vga_draw_glyph8_func *vga_draw_glyph8; +- vga_draw_glyph9_func *vga_draw_glyph9; + int64_t now = qemu_get_clock_ms(vm_clock); + + /* compute font data address (in plane 2) */ +@@ -1425,8 +1285,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) + s->last_cw = cw; + full_update = 1; + } +- s->rgb_to_pixel = +- rgb_to_pixel_dup_table[get_depth_index(surface)]; ++ s->rgb_to_pixel = rgb_to_pixel32_dup; + full_update |= update_palette16(s); + palette = s->last_palette; + x_incr = cw * surface_bytes_per_pixel(surface); +@@ -1460,13 +1319,6 @@ static void vga_draw_text(VGACommonState *s, int full_update) + s->cursor_visible_phase = !s->cursor_visible_phase; + } + +- depth_index = get_depth_index(surface); +- if (cw == 16) +- vga_draw_glyph8 = vga_draw_glyph16_table[depth_index]; +- else +- vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; +- vga_draw_glyph9 = vga_draw_glyph9_table[depth_index]; +- + dest = surface_data(surface); + linesize = surface_stride(surface); + ch_attr_ptr = s->last_ch_attr; +@@ -1496,17 +1348,20 @@ static void vga_draw_text(VGACommonState *s, int full_update) + font_ptr += 32 * 4 * ch; + bgcol = palette[cattr >> 4]; + fgcol = palette[cattr & 0x0f]; +- if (cw != 9) { +- vga_draw_glyph8(d1, linesize, +- font_ptr, cheight, fgcol, bgcol); ++ if (cw == 16) { ++ vga_draw_glyph16_32(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol); ++ } else if (cw != 9) { ++ vga_draw_glyph8_32(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol); + } else { + dup9 = 0; + if (ch >= 0xb0 && ch <= 0xdf && + (s->ar[VGA_ATC_MODE] & 0x04)) { + dup9 = 1; + } +- vga_draw_glyph9(d1, linesize, +- font_ptr, cheight, fgcol, bgcol, dup9); ++ vga_draw_glyph9_32(d1, linesize, ++ font_ptr, cheight, fgcol, bgcol, dup9); + } + if (src == cursor_ptr && + !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && +@@ -1521,12 +1376,15 @@ static void vga_draw_text(VGACommonState *s, int full_update) + if (line_last >= line_start && line_start < cheight) { + h = line_last - line_start + 1; + d = d1 + linesize * line_start; +- if (cw != 9) { +- vga_draw_glyph8(d, linesize, +- cursor_glyph, h, fgcol, bgcol); ++ if (cw == 16) { ++ vga_draw_glyph16_32(d, linesize, ++ cursor_glyph, h, fgcol, bgcol); ++ } else if (cw != 9) { ++ vga_draw_glyph8_32(d, linesize, ++ cursor_glyph, h, fgcol, bgcol); + } else { +- vga_draw_glyph9(d, linesize, +- cursor_glyph, h, fgcol, bgcol, 1); ++ vga_draw_glyph9_32(d, linesize, ++ cursor_glyph, h, fgcol, bgcol, 1); + } + } + } +@@ -1563,86 +1421,17 @@ enum { + VGA_DRAW_LINE_NB, + }; + +-static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = { +- vga_draw_line2_8, +- vga_draw_line2_16, +- vga_draw_line2_16, +- vga_draw_line2_32, ++static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { + vga_draw_line2_32, +- vga_draw_line2_16, +- vga_draw_line2_16, +- +- vga_draw_line2d2_8, +- vga_draw_line2d2_16, +- vga_draw_line2d2_16, +- vga_draw_line2d2_32, + vga_draw_line2d2_32, +- vga_draw_line2d2_16, +- vga_draw_line2d2_16, +- +- vga_draw_line4_8, +- vga_draw_line4_16, +- vga_draw_line4_16, + vga_draw_line4_32, +- vga_draw_line4_32, +- vga_draw_line4_16, +- vga_draw_line4_16, +- +- vga_draw_line4d2_8, +- vga_draw_line4d2_16, +- vga_draw_line4d2_16, + vga_draw_line4d2_32, +- vga_draw_line4d2_32, +- vga_draw_line4d2_16, +- vga_draw_line4d2_16, +- +- vga_draw_line8d2_8, +- vga_draw_line8d2_16, +- vga_draw_line8d2_16, +- vga_draw_line8d2_32, + vga_draw_line8d2_32, +- vga_draw_line8d2_16, +- vga_draw_line8d2_16, +- +- vga_draw_line8_8, +- vga_draw_line8_16, +- vga_draw_line8_16, +- vga_draw_line8_32, + vga_draw_line8_32, +- vga_draw_line8_16, +- vga_draw_line8_16, +- +- vga_draw_line15_8, +- vga_draw_line15_15, +- vga_draw_line15_16, + vga_draw_line15_32, +- vga_draw_line15_32bgr, +- vga_draw_line15_15bgr, +- vga_draw_line15_16bgr, +- +- vga_draw_line16_8, +- vga_draw_line16_15, +- vga_draw_line16_16, + vga_draw_line16_32, +- vga_draw_line16_32bgr, +- vga_draw_line16_15bgr, +- vga_draw_line16_16bgr, +- +- vga_draw_line24_8, +- vga_draw_line24_15, +- vga_draw_line24_16, + vga_draw_line24_32, +- vga_draw_line24_32bgr, +- vga_draw_line24_15bgr, +- vga_draw_line24_16bgr, +- +- vga_draw_line32_8, +- vga_draw_line32_15, +- vga_draw_line32_16, + vga_draw_line32_32, +- vga_draw_line32_32bgr, +- vga_draw_line32_15bgr, +- vga_draw_line32_16bgr, + }; + + static int vga_get_bpp(VGACommonState *s) +@@ -1787,8 +1576,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + dpy_gfx_replace_surface(s->con, surface); + } + +- s->rgb_to_pixel = +- rgb_to_pixel_dup_table[get_depth_index(surface)]; ++ s->rgb_to_pixel = rgb_to_pixel32_dup; + + if (shift_control == 0) { + full_update |= update_palette16(s); +@@ -1837,8 +1625,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + break; + } + } +- vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + +- get_depth_index(surface)]; ++ vga_draw_line = vga_draw_line_table[v]; + + if (!is_buffer_shared(surface) && s->cursor_invalidate) { + s->cursor_invalidate(s); +@@ -1936,8 +1723,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update) + if (s->last_scr_width <= 0 || s->last_scr_height <= 0) + return; + +- s->rgb_to_pixel = +- rgb_to_pixel_dup_table[get_depth_index(surface)]; ++ s->rgb_to_pixel = rgb_to_pixel32_dup; + if (surface_bits_per_pixel(surface) == 8) { + val = s->rgb_to_pixel(0, 0, 0); + } else { +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-drop-line_offset-variable.patch b/SOURCES/kvm-vga-drop-line_offset-variable.patch new file mode 100644 index 0000000..eeea0de --- /dev/null +++ b/SOURCES/kvm-vga-drop-line_offset-variable.patch @@ -0,0 +1,54 @@ +From 68dd20867cb9103d0d51ba0223d677e74b7cc51a Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 20 Oct 2017 11:06:16 +0200 +Subject: [PATCH 08/11] vga: drop line_offset variable + +RH-Author: Gerd Hoffmann +Message-id: <20171020110619.2541-9-kraxel@redhat.com> +Patchwork-id: 77399 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 08/11] vga: drop line_offset variable +Bugzilla: 1501294 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 362f811793ff6cb4d209ab61d76cc4f841bb5e46) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 5b0b864..dda3f5f 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1504,7 +1504,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + { + DisplaySurface *surface = qemu_console_surface(s->con); + int y1, y, update, linesize, y_start, double_scan, mask, depth; +- int width, height, shift_control, line_offset, bwidth, bits; ++ int width, height, shift_control, bwidth, bits; + ram_addr_t page0, page1, page_min, page_max; + int disp_width, multi_scan, multi_run; + uint8_t *d; +@@ -1642,7 +1642,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + s->cursor_invalidate(s); + } + +- line_offset = s->line_offset; + #if 0 + printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", + width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], +@@ -1697,7 +1696,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + if (!multi_run) { + mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3; + if ((y1 & mask) == mask) +- addr1 += line_offset; ++ addr1 += s->line_offset; + y1++; + multi_run = multi_scan; + } else { +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch b/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch new file mode 100644 index 0000000..38c14d2 --- /dev/null +++ b/SOURCES/kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch @@ -0,0 +1,107 @@ +From d120e85aeaaeb925ef3fb63a5f962ef64ae26815 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 20 Oct 2017 11:06:18 +0200 +Subject: [PATCH 10/11] vga: handle cirrus vbe mode wraparounds. + +RH-Author: Gerd Hoffmann +Message-id: <20171020110619.2541-11-kraxel@redhat.com> +Patchwork-id: 77404 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 10/11] vga: handle cirrus vbe mode wraparounds. +Bugzilla: 1501294 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Miroslav Rezanina + +Commit "3d90c62548 vga: stop passing pointers to vga_draw_line* +functions" is incomplete. It doesn't handle the case that the vga +rendering code tries to create a shared surface, i.e. a pixman image +backed by vga video memory. That can not work in case the guest display +wraps from end of video memory to the start. So force shadowing in that +case. Also adjust the snapshot region calculation. + +Can trigger with cirrus only, when programming vbe modes using the bochs +api (stdvga, also qxl and virtio-vga in vga compat mode) wrap arounds +can't happen. + +Fixes: CVE-2017-13672 +Fixes: 3d90c6254863693a6b13d918d2b8682e08bbc681 +Cc: P J P +Reported-by: David Buchanan +Signed-off-by: Gerd Hoffmann +Message-id: 20171010141323.14049-3-kraxel@redhat.com +(cherry picked from commit 28f77de26a4f9995458ddeb9d34bb06c0193bdc9) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga.c | 31 ++++++++++++++++++++++++------- + 1 file changed, 24 insertions(+), 7 deletions(-) + +diff --git a/hw/display/vga.c b/hw/display/vga.c +index a343a0a..c40744f 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1505,12 +1505,12 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + DisplaySurface *surface = qemu_console_surface(s->con); + int y1, y, update, linesize, y_start, double_scan, mask, depth; + int width, height, shift_control, bwidth, bits; +- ram_addr_t page0, page1, page_min, page_max; ++ ram_addr_t page0, page1, page_min, page_max, region_start, region_end; + int disp_width, multi_scan, multi_run; + uint8_t *d; + uint32_t v, addr1, addr; + vga_draw_line_func *vga_draw_line; +- bool share_surface; ++ bool share_surface, force_shadow = false; + #if defined(TARGET_WORDS_BIGENDIAN) + static const bool big_endian_fb = true; + #else +@@ -1530,6 +1530,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + s->get_resolution(s, &width, &height); + disp_width = width; + ++ region_start = (s->start_addr * 4); ++ region_end = region_start + s->line_offset * height; ++ if (region_end > s->vbe_size) { ++ /* wraps around (can happen with cirrus vbe modes) */ ++ region_start = 0; ++ region_end = s->vbe_size; ++ force_shadow = true; ++ } ++ + shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3; + double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7); + if (shift_control != 1) { +@@ -1560,7 +1569,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + + depth = s->get_bpp(s); + +- share_surface = (!s->force_shadow) && ++ share_surface = (!s->force_shadow) && !force_shadow && + ( depth == 32 || (depth == 16 && !byteswap) ); + if (s->line_offset != s->last_line_offset || + disp_width != s->last_width || +@@ -1680,10 +1689,18 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + addr = (addr & ~0x8000) | ((y1 & 2) << 14); + } + update = full_update; +- page0 = addr; +- page1 = addr + bwidth - 1; +- update |= memory_region_get_dirty(&s->vram, page0, page1 - page0, +- DIRTY_MEMORY_VGA); ++ page0 = addr & s->vbe_size_mask; ++ page1 = (addr + bwidth - 1) & s->vbe_size_mask; ++ if (page1 < page0) { ++ /* scanline wraps from end of video memory to the start */ ++ update |= memory_region_get_dirty(&s->vram, page0, 0, ++ DIRTY_MEMORY_VGA); ++ update |= memory_region_get_dirty(&s->vram, page1, 0, ++ DIRTY_MEMORY_VGA); ++ } else { ++ update |= memory_region_get_dirty(&s->vram, page0, page1 - page0, ++ DIRTY_MEMORY_VGA); ++ } + /* explicit invalidation for the hardware cursor */ + update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; + if (update) { +-- +1.8.3.1 + diff --git a/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch b/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch new file mode 100644 index 0000000..412e986 --- /dev/null +++ b/SOURCES/kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch @@ -0,0 +1,508 @@ +From 1ac530769380bb6e481e97502925b656efdfa8fc Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 5 Oct 2017 14:51:19 +0200 +Subject: [PATCH 07/11] vga: stop passing pointers to vga_draw_line* functions + +RH-Author: Gerd Hoffmann +Message-id: <20171005145119.15277-8-kraxel@redhat.com> +Patchwork-id: 76828 +O-Subject: [RHEL-7.5 qemu-kvm PATCH 7/7] vga: stop passing pointers to vga_draw_line* functions +Bugzilla: 1501294 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Thomas Huth +RH-Acked-by: Miroslav Rezanina + +Instead pass around the address (aka offset into vga memory). +Add vga_read_* helper functions which apply vbe_size_mask to +the address, to make sure the address stays within the valid +range, similar to the cirrus blitter fixes (commits ffaf857778 +and 026aeffcb4). + +Impact: DoS for privileged guest users. qemu crashes with +a segfault, when hitting the guard page after vga memory +allocation, while reading vga memory for display updates. + +Fixes: CVE-2017-13672 +Cc: P J P +Reported-by: David Buchanan +Signed-off-by: Gerd Hoffmann +Message-id: 20170828122906.18993-1-kraxel@redhat.com +(cherry picked from commit 3d90c6254863693a6b13d918d2b8682e08bbc681) +Signed-off-by: Miroslav Rezanina +--- + hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++--------------------- + hw/display/vga.c | 5 +- + hw/display/vga_int.h | 1 + + 3 files changed, 114 insertions(+), 94 deletions(-) + +diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h +index 94f6de2..5a752b3 100644 +--- a/hw/display/vga-helpers.h ++++ b/hw/display/vga-helpers.h +@@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize, + } while (--h); + } + ++static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr) ++{ ++ return vga->vram_ptr[addr & vga->vbe_size_mask]; ++} ++ ++static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr) ++{ ++ uint32_t offset = addr & vga->vbe_size_mask & ~1; ++ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset); ++ return lduw_le_p(ptr); ++} ++ ++static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr) ++{ ++ uint32_t offset = addr & vga->vbe_size_mask & ~1; ++ uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset); ++ return lduw_be_p(ptr); ++} ++ ++static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr) ++{ ++ uint32_t offset = addr & vga->vbe_size_mask & ~3; ++ uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset); ++ return ldl_le_p(ptr); ++} ++ + /* + * 4 color mode + */ +-static void vga_draw_line2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line2(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t plane_mask, *palette, data, v; + int x; + +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ palette = vga->last_palette; ++ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; + width >>= 3; + for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; ++ data = vga_read_dword_le(vga, addr); + data &= plane_mask; + v = expand2[GET_PLANE(data, 0)]; + v |= expand2[GET_PLANE(data, 2)] << 2; +@@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d, + ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; + ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; + d += 32; +- s += 4; ++ addr += 4; + } + } + +@@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d, + /* + * 4 color mode, dup2 horizontal + */ +-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t plane_mask, *palette, data, v; + int x; + +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ palette = vga->last_palette; ++ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; + width >>= 3; + for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; ++ data = vga_read_dword_le(vga, addr); + data &= plane_mask; + v = expand2[GET_PLANE(data, 0)]; + v |= expand2[GET_PLANE(data, 2)] << 2; +@@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, + PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); + PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); + d += 64; +- s += 4; ++ addr += 4; + } + } + + /* + * 16 color mode + */ +-static void vga_draw_line4(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line4(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t plane_mask, data, v, *palette; + int x; + +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ palette = vga->last_palette; ++ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; + width >>= 3; + for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; ++ data = vga_read_dword_le(vga, addr); + data &= plane_mask; + v = expand4[GET_PLANE(data, 0)]; + v |= expand4[GET_PLANE(data, 1)] << 1; +@@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d, + ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; + ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; + d += 32; +- s += 4; ++ addr += 4; + } + } + + /* + * 16 color mode, dup2 horizontal + */ +-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t plane_mask, data, v, *palette; + int x; + +- palette = s1->last_palette; +- plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; ++ palette = vga->last_palette; ++ plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf]; + width >>= 3; + for(x = 0; x < width; x++) { +- data = ((uint32_t *)s)[0]; ++ data = vga_read_dword_le(vga, addr); + data &= plane_mask; + v = expand4[GET_PLANE(data, 0)]; + v |= expand4[GET_PLANE(data, 1)] << 1; +@@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, + PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); + PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); + d += 64; +- s += 4; ++ addr += 4; + } + } + +@@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, + * + * XXX: add plane_mask support (never used in standard VGA modes) + */ +-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t *palette; + int x; + +- palette = s1->last_palette; ++ palette = vga->last_palette; + width >>= 3; + for(x = 0; x < width; x++) { +- PUT_PIXEL2(d, 0, palette[s[0]]); +- PUT_PIXEL2(d, 1, palette[s[1]]); +- PUT_PIXEL2(d, 2, palette[s[2]]); +- PUT_PIXEL2(d, 3, palette[s[3]]); ++ PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]); ++ PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]); ++ PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]); ++ PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]); + d += 32; +- s += 4; ++ addr += 4; + } + } + +@@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, + * + * XXX: add plane_mask support (never used in standard VGA modes) + */ +-static void vga_draw_line8(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line8(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + uint32_t *palette; + int x; + +- palette = s1->last_palette; ++ palette = vga->last_palette; + width >>= 3; + for(x = 0; x < width; x++) { +- ((uint32_t *)d)[0] = palette[s[0]]; +- ((uint32_t *)d)[1] = palette[s[1]]; +- ((uint32_t *)d)[2] = palette[s[2]]; +- ((uint32_t *)d)[3] = palette[s[3]]; +- ((uint32_t *)d)[4] = palette[s[4]]; +- ((uint32_t *)d)[5] = palette[s[5]]; +- ((uint32_t *)d)[6] = palette[s[6]]; +- ((uint32_t *)d)[7] = palette[s[7]]; ++ ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)]; ++ ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)]; ++ ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)]; ++ ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)]; ++ ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)]; ++ ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)]; ++ ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)]; ++ ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)]; + d += 32; +- s += 8; ++ addr += 8; + } + } + + /* + * 15 bit color + */ +-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_le_p((void *)s); ++ v = vga_read_word_le(vga, addr); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; ++ addr += 2; + d += 4; + } while (--w != 0); + } + +-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_be_p((void *)s); ++ v = vga_read_word_be(vga, addr); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; ++ addr += 2; + d += 4; + } while (--w != 0); + } +@@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, + /* + * 16 bit color + */ +-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_le_p((void *)s); ++ v = vga_read_word_le(vga, addr); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; ++ addr += 2; + d += 4; + } while (--w != 0); + } + +-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t v, r, g, b; + + w = width; + do { +- v = lduw_be_p((void *)s); ++ v = vga_read_word_be(vga, addr); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 2; ++ addr += 2; + d += 4; + } while (--w != 0); + } +@@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, + /* + * 24 bit color + */ +-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t r, g, b; + + w = width; + do { +- b = s[0]; +- g = s[1]; +- r = s[2]; ++ b = vga_read_byte(vga, addr + 0); ++ g = vga_read_byte(vga, addr + 1); ++ r = vga_read_byte(vga, addr + 2); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 3; ++ addr += 3; + d += 4; + } while (--w != 0); + } + +-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { + int w; + uint32_t r, g, b; + + w = width; + do { +- r = s[0]; +- g = s[1]; +- b = s[2]; ++ r = vga_read_byte(vga, addr + 0); ++ g = vga_read_byte(vga, addr + 1); ++ b = vga_read_byte(vga, addr + 2); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 3; ++ addr += 3; + d += 4; + } while (--w != 0); + } +@@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, + /* + * 32 bit color + */ +-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { +-#ifndef HOST_WORDS_BIGENDIAN +- memcpy(d, s, width * 4); +-#else + int w; + uint32_t r, g, b; + + w = width; + do { +- b = s[0]; +- g = s[1]; +- r = s[2]; ++ b = vga_read_byte(vga, addr + 0); ++ g = vga_read_byte(vga, addr + 1); ++ r = vga_read_byte(vga, addr + 2); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 4; ++ addr += 4; + d += 4; + } while (--w != 0); +-#endif + } + +-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width) ++static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d, ++ uint32_t addr, int width) + { +-#ifdef HOST_WORDS_BIGENDIAN +- memcpy(d, s, width * 4); +-#else + int w; + uint32_t r, g, b; + + w = width; + do { +- r = s[1]; +- g = s[2]; +- b = s[3]; ++ r = vga_read_byte(vga, addr + 1); ++ g = vga_read_byte(vga, addr + 2); ++ b = vga_read_byte(vga, addr + 3); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); +- s += 4; ++ addr += 4; + d += 4; + } while (--w != 0); +-#endif + } +diff --git a/hw/display/vga.c b/hw/display/vga.c +index 4618823..5b0b864 100644 +--- a/hw/display/vga.c ++++ b/hw/display/vga.c +@@ -1045,7 +1045,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) + } + + typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, +- const uint8_t *s, int width); ++ uint32_t srcaddr, int width); + + #include "vga-helpers.h" + +@@ -1682,7 +1682,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) + if (page1 > page_max) + page_max = page1; + if (!(is_buffer_shared(surface))) { +- vga_draw_line(s, d, s->vram_ptr + addr, width); ++ vga_draw_line(s, d, addr, width); + if (s->cursor_draw_line) + s->cursor_draw_line(s, d, y); + } +@@ -2162,6 +2162,7 @@ void vga_common_init(VGACommonState *s) + if (!s->vbe_size) { + s->vbe_size = s->vram_size; + } ++ s->vbe_size_mask = s->vbe_size - 1; + + s->is_vbe_vmstate = 1; + memory_region_init_ram(&s->vram, "vga.vram", s->vram_size); +diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h +index 7c758ac..94add2f 100644 +--- a/hw/display/vga_int.h ++++ b/hw/display/vga_int.h +@@ -94,6 +94,7 @@ typedef struct VGACommonState { + uint32_t vram_size; + uint32_t vram_size_mb; /* property */ + uint32_t vbe_size; ++ uint32_t vbe_size_mask; + uint32_t latch; + MemoryRegion *chain4_alias; + uint8_t sr_index; +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index d7f6d4f..ec913ee 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 1.5.3 -Release: 141%{?dist}.2 +Release: 141%{?dist}.4 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2+ and LGPLv2+ and BSD @@ -3600,6 +3600,30 @@ Patch1771: kvm-qemu-nbd-Ignore-SIGPIPE.patch Patch1772: kvm-virtio-net-dynamic-network-offloads-configuration.patch # For bz#1482468 - KVM: windows guest migration from EL6 to EL7 fails. [rhel-7.4.z] Patch1773: kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1774: kvm-bswap.h-Remove-cpu_to_32wu.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1775: kvm-hw-use-ld_p-st_p-instead-of-ld_raw-st_raw.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1776: kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1777: kvm-vga-Remove-remainder-of-old-conversion-cruft.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1778: kvm-vga-Separate-LE-and-BE-conversion-functions.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1779: kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1780: kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1781: kvm-vga-drop-line_offset-variable.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1782: kvm-vga-Add-mechanism-to-force-the-use-of-a-shadow-surfa.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1783: kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch +# For bz#1501294 - CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z] +Patch1784: kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch +# For bz#1501120 - CVE-2017-14167 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.4.z] +Patch1785: kvm-multiboot-validate-multiboot-header-address-values.patch BuildRequires: zlib-devel @@ -5551,6 +5575,18 @@ tar -xf %{SOURCE21} %patch1771 -p1 %patch1772 -p1 %patch1773 -p1 +%patch1774 -p1 +%patch1775 -p1 +%patch1776 -p1 +%patch1777 -p1 +%patch1778 -p1 +%patch1779 -p1 +%patch1780 -p1 +%patch1781 -p1 +%patch1782 -p1 +%patch1783 -p1 +%patch1784 -p1 +%patch1785 -p1 %build buildarch="%{kvm_target}-softmmu" @@ -5996,6 +6032,26 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_mandir}/man8/qemu-nbd.8* %changelog +* Fri Nov 10 2017 Miroslav Rezanina - 1.5.3-141.el7_4.4 +- kvm-multiboot-validate-multiboot-header-address-values.patch [bz#1501120] +- Resolves: bz#1501120 + (CVE-2017-14167 qemu-kvm: Qemu: i386: multiboot OOB access while loading kernel image [rhel-7.4.z]) + +* Tue Nov 07 2017 Miroslav Rezanina - 1.5.3-141.el7_4.3 +- kvm-bswap.h-Remove-cpu_to_32wu.patch [bz#1501294] +- kvm-hw-use-ld_p-st_p-instead-of-ld_raw-st_raw.patch [bz#1501294] +- kvm-vga-Start-cutting-out-non-32bpp-conversion-support.patch [bz#1501294] +- kvm-vga-Remove-remainder-of-old-conversion-cruft.patch [bz#1501294] +- kvm-vga-Separate-LE-and-BE-conversion-functions.patch [bz#1501294] +- kvm-vga-Rename-vga_template.h-to-vga-helpers.h.patch [bz#1501294] +- kvm-vga-stop-passing-pointers-to-vga_draw_line-functions.patch [bz#1501294] +- kvm-vga-drop-line_offset-variable.patch [bz#1501294] +- kvm-vga-Add-mechanism-to-force-the-use-of-a-shadow-surfa.patch [bz#1501294] +- kvm-vga-handle-cirrus-vbe-mode-wraparounds.patch [bz#1501294] +- kvm-cirrus-fix-oob-access-in-mode4and5-write-functions.patch [bz#1501294] +- Resolves: bz#1501294 + (CVE-2017-15289 qemu-kvm: Qemu: cirrus: OOB access issue in mode4and5 write functions [rhel-7.4.z]) + * Mon Aug 21 2017 Miroslav Rezanina - 1.5.3-141.el7_4.2 - kvm-virtio-net-dynamic-network-offloads-configuration.patch [bz#1482468] - kvm-Workaround-rhel6-ctrl_guest_offloads-machine-type-mi.patch [bz#1482468]