vga security fixes (CVE-2016-3710, CVE-2016-3712)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJXMIUCAAoJEEy22O7T6HE4uacP/1IwxsNr7oAc8Mb1x95r3aLe Q7KAh8Nei9VMcNLvUMweAaRSNgrrM+ic84oTNqWTGL5fgbV3oa4JlbTnGlWs174W acCH6tMSG21SqukxnMdO79X/Ldi7IhQEVMHvAm0bq7jwHYYLjdwAhIBOXs5G5oJX 5UcosiGJenrT5USICv5Cr5sMvPgy3wS9qvJVbdGzxZzJ3I7274teS4Y8JjlMrxj0 JIIQ2dDMFI2twlzJbmpXqMlZ3l+RhB4AXA47T8SZW2MSgBv+zI2BZEBuEIS7bQqj debIWA9Rl2lbsroJUHsjqgxyLD89jyKaunt2rhyEo0F6e12jzfuXfP9qdqKSaz9T 5PZ98PDTWD+1K7pAq88TvuQApwawoIIfIyGaNYjktmWiDRZ/607uxtILp7MI8M0v K04K0SBbqM/0whUyAVcjrZkbd7p7hGcN6vn2m2i6vWcqcNkiP3S8kz+coV1fCpXu YSzo1yg8+e6UZMpLxz/VgCdRpwEtRgiLq0CkI6gdhu88gSjldWml5qa/MibuAwYJ NWmtDmaqM1TBburDTHI2EbQ7UGDDPH3NbHBfH21fd73YONJ3PFqnDdTTytdKoXd0 /kinn6YN9au3NcQHLJojCcXKIiGsCfQwIPuXl9aF/oT46f8TweHZJ9WyeMyP35Kh Yg3itPanlsN4PrrGmyMO =v5wH -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20160509-1' into staging vga security fixes (CVE-2016-3710, CVE-2016-3712) # gpg: Signature made Mon 09 May 2016 13:39:30 BST using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-vga-20160509-1: vga: make sure vga register setup for vbe stays intact (CVE-2016-3712). vga: update vga register setup on vbe changes vga: factor out vga register setup vga: add vbe_enabled() helper vga: fix banked access bounds checking (CVE-2016-3710) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						53db932604
					
				
							
								
								
									
										120
									
								
								hw/display/vga.c
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								hw/display/vga.c
									
									
									
									
									
								
							@ -142,6 +142,13 @@ static uint32_t expand4[256];
 | 
				
			|||||||
static uint16_t expand2[256];
 | 
					static uint16_t expand2[256];
 | 
				
			||||||
static uint8_t expand4to8[16];
 | 
					static uint8_t expand4to8[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void vbe_update_vgaregs(VGACommonState *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool vbe_enabled(VGACommonState *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void vga_update_memory_access(VGACommonState *s)
 | 
					static void vga_update_memory_access(VGACommonState *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    hwaddr base, offset, size;
 | 
					    hwaddr base, offset, size;
 | 
				
			||||||
@ -179,6 +186,7 @@ static void vga_update_memory_access(VGACommonState *s)
 | 
				
			|||||||
            size = 0x8000;
 | 
					            size = 0x8000;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        assert(offset + size <= s->vram_size);
 | 
				
			||||||
        memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
 | 
					        memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),
 | 
				
			||||||
                                 "vga.chain4", &s->vram, offset, size);
 | 
					                                 "vga.chain4", &s->vram, offset, size);
 | 
				
			||||||
        memory_region_add_subregion_overlap(s->legacy_address_space, base,
 | 
					        memory_region_add_subregion_overlap(s->legacy_address_space, base,
 | 
				
			||||||
@ -478,6 +486,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
 | 
					        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
 | 
					        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
 | 
				
			||||||
 | 
					        vbe_update_vgaregs(s);
 | 
				
			||||||
        if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
 | 
					        if (s->sr_index == VGA_SEQ_CLOCK_MODE) {
 | 
				
			||||||
            s->update_retrace_info(s);
 | 
					            s->update_retrace_info(s);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -509,6 +518,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
 | 
					        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
 | 
					        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
 | 
				
			||||||
 | 
					        vbe_update_vgaregs(s);
 | 
				
			||||||
        vga_update_memory_access(s);
 | 
					        vga_update_memory_access(s);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case VGA_CRT_IM:
 | 
					    case VGA_CRT_IM:
 | 
				
			||||||
@ -527,10 +537,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
            if (s->cr_index == VGA_CRTC_OVERFLOW) {
 | 
					            if (s->cr_index == VGA_CRTC_OVERFLOW) {
 | 
				
			||||||
                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
 | 
					                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
 | 
				
			||||||
                    (val & 0x10);
 | 
					                    (val & 0x10);
 | 
				
			||||||
 | 
					                vbe_update_vgaregs(s);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        s->cr[s->cr_index] = val;
 | 
					        s->cr[s->cr_index] = val;
 | 
				
			||||||
 | 
					        vbe_update_vgaregs(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        switch(s->cr_index) {
 | 
					        switch(s->cr_index) {
 | 
				
			||||||
        case VGA_CRTC_H_TOTAL:
 | 
					        case VGA_CRTC_H_TOTAL:
 | 
				
			||||||
@ -563,7 +575,7 @@ static void vbe_fixup_regs(VGACommonState *s)
 | 
				
			|||||||
    uint16_t *r = s->vbe_regs;
 | 
					    uint16_t *r = s->vbe_regs;
 | 
				
			||||||
    uint32_t bits, linelength, maxy, offset;
 | 
					    uint32_t bits, linelength, maxy, offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
 | 
					    if (!vbe_enabled(s)) {
 | 
				
			||||||
        /* vbe is turned off -- nothing to do */
 | 
					        /* vbe is turned off -- nothing to do */
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -638,6 +650,49 @@ static void vbe_fixup_regs(VGACommonState *s)
 | 
				
			|||||||
    s->vbe_start_addr  = offset / 4;
 | 
					    s->vbe_start_addr  = offset / 4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* we initialize the VGA graphic mode */
 | 
				
			||||||
 | 
					static void vbe_update_vgaregs(VGACommonState *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int h, shift_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!vbe_enabled(s)) {
 | 
				
			||||||
 | 
					        /* vbe is turned off -- nothing to do */
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* graphic mode + memory map 1 */
 | 
				
			||||||
 | 
					    s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
 | 
				
			||||||
 | 
					        VGA_GR06_GRAPHICS_MODE;
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
 | 
				
			||||||
 | 
					    /* width */
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_H_DISP] =
 | 
				
			||||||
 | 
					        (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
 | 
				
			||||||
 | 
					    /* height (only meaningful if < 1024) */
 | 
				
			||||||
 | 
					    h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_V_DISP_END] = h;
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
 | 
				
			||||||
 | 
					        ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
 | 
				
			||||||
 | 
					    /* line compare to 1023 */
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
 | 
				
			||||||
 | 
					        shift_control = 0;
 | 
				
			||||||
 | 
					        s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        shift_control = 2;
 | 
				
			||||||
 | 
					        /* set chain 4 mode */
 | 
				
			||||||
 | 
					        s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
 | 
				
			||||||
 | 
					        /* activate all planes */
 | 
				
			||||||
 | 
					        s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
 | 
				
			||||||
 | 
					        (shift_control << 5);
 | 
				
			||||||
 | 
					    s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 | 
					static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    VGACommonState *s = opaque;
 | 
					    VGACommonState *s = opaque;
 | 
				
			||||||
@ -714,13 +769,10 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
        case VBE_DISPI_INDEX_Y_OFFSET:
 | 
					        case VBE_DISPI_INDEX_Y_OFFSET:
 | 
				
			||||||
            s->vbe_regs[s->vbe_index] = val;
 | 
					            s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
            vbe_fixup_regs(s);
 | 
					            vbe_fixup_regs(s);
 | 
				
			||||||
 | 
					            vbe_update_vgaregs(s);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case VBE_DISPI_INDEX_BANK:
 | 
					        case VBE_DISPI_INDEX_BANK:
 | 
				
			||||||
            if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
 | 
					 | 
				
			||||||
              val &= (s->vbe_bank_mask >> 2);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
            val &= s->vbe_bank_mask;
 | 
					            val &= s->vbe_bank_mask;
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            s->vbe_regs[s->vbe_index] = val;
 | 
					            s->vbe_regs[s->vbe_index] = val;
 | 
				
			||||||
            s->bank_offset = (val << 16);
 | 
					            s->bank_offset = (val << 16);
 | 
				
			||||||
            vga_update_memory_access(s);
 | 
					            vga_update_memory_access(s);
 | 
				
			||||||
@ -728,52 +780,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
        case VBE_DISPI_INDEX_ENABLE:
 | 
					        case VBE_DISPI_INDEX_ENABLE:
 | 
				
			||||||
            if ((val & VBE_DISPI_ENABLED) &&
 | 
					            if ((val & VBE_DISPI_ENABLED) &&
 | 
				
			||||||
                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
 | 
					                !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
 | 
				
			||||||
                int h, shift_control;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
 | 
				
			||||||
                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
 | 
				
			||||||
                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
 | 
				
			||||||
                s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
 | 
					                s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
 | 
				
			||||||
                vbe_fixup_regs(s);
 | 
					                vbe_fixup_regs(s);
 | 
				
			||||||
 | 
					                vbe_update_vgaregs(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* clear the screen */
 | 
					                /* clear the screen */
 | 
				
			||||||
                if (!(val & VBE_DISPI_NOCLEARMEM)) {
 | 
					                if (!(val & VBE_DISPI_NOCLEARMEM)) {
 | 
				
			||||||
                    memset(s->vram_ptr, 0,
 | 
					                    memset(s->vram_ptr, 0,
 | 
				
			||||||
                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 | 
					                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                /* we initialize the VGA graphic mode */
 | 
					 | 
				
			||||||
                /* graphic mode + memory map 1 */
 | 
					 | 
				
			||||||
                s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
 | 
					 | 
				
			||||||
                    VGA_GR06_GRAPHICS_MODE;
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
 | 
					 | 
				
			||||||
                /* width */
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_H_DISP] =
 | 
					 | 
				
			||||||
                    (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
 | 
					 | 
				
			||||||
                /* height (only meaningful if < 1024) */
 | 
					 | 
				
			||||||
                h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_V_DISP_END] = h;
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
 | 
					 | 
				
			||||||
                    ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
 | 
					 | 
				
			||||||
                /* line compare to 1023 */
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
 | 
					 | 
				
			||||||
                    shift_control = 0;
 | 
					 | 
				
			||||||
                    s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    shift_control = 2;
 | 
					 | 
				
			||||||
                    /* set chain 4 mode */
 | 
					 | 
				
			||||||
                    s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
 | 
					 | 
				
			||||||
                    /* activate all planes */
 | 
					 | 
				
			||||||
                    s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
 | 
					 | 
				
			||||||
                    (shift_control << 5);
 | 
					 | 
				
			||||||
                s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                s->bank_offset = 0;
 | 
					                s->bank_offset = 0;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -819,13 +838,21 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
 | 
					    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
 | 
				
			||||||
        /* chain 4 mode : simplest access */
 | 
					        /* chain 4 mode : simplest access */
 | 
				
			||||||
 | 
					        assert(addr < s->vram_size);
 | 
				
			||||||
        ret = s->vram_ptr[addr];
 | 
					        ret = s->vram_ptr[addr];
 | 
				
			||||||
    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 | 
					    } else if (s->gr[VGA_GFX_MODE] & 0x10) {
 | 
				
			||||||
        /* odd/even mode (aka text mode mapping) */
 | 
					        /* odd/even mode (aka text mode mapping) */
 | 
				
			||||||
        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 | 
					        plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
 | 
				
			||||||
        ret = s->vram_ptr[((addr & ~1) << 1) | plane];
 | 
					        addr = ((addr & ~1) << 1) | plane;
 | 
				
			||||||
 | 
					        if (addr >= s->vram_size) {
 | 
				
			||||||
 | 
					            return 0xff;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ret = s->vram_ptr[addr];
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        /* standard VGA latched access */
 | 
					        /* standard VGA latched access */
 | 
				
			||||||
 | 
					        if (addr * sizeof(uint32_t) >= s->vram_size) {
 | 
				
			||||||
 | 
					            return 0xff;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        s->latch = ((uint32_t *)s->vram_ptr)[addr];
 | 
					        s->latch = ((uint32_t *)s->vram_ptr)[addr];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
 | 
					        if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
 | 
				
			||||||
@ -882,6 +909,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 | 
				
			|||||||
        plane = addr & 3;
 | 
					        plane = addr & 3;
 | 
				
			||||||
        mask = (1 << plane);
 | 
					        mask = (1 << plane);
 | 
				
			||||||
        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
 | 
					        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
 | 
				
			||||||
 | 
					            assert(addr < s->vram_size);
 | 
				
			||||||
            s->vram_ptr[addr] = val;
 | 
					            s->vram_ptr[addr] = val;
 | 
				
			||||||
#ifdef DEBUG_VGA_MEM
 | 
					#ifdef DEBUG_VGA_MEM
 | 
				
			||||||
            printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 | 
					            printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
 | 
				
			||||||
@ -895,6 +923,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 | 
				
			|||||||
        mask = (1 << plane);
 | 
					        mask = (1 << plane);
 | 
				
			||||||
        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
 | 
					        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
 | 
				
			||||||
            addr = ((addr & ~1) << 1) | plane;
 | 
					            addr = ((addr & ~1) << 1) | plane;
 | 
				
			||||||
 | 
					            if (addr >= s->vram_size) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            s->vram_ptr[addr] = val;
 | 
					            s->vram_ptr[addr] = val;
 | 
				
			||||||
#ifdef DEBUG_VGA_MEM
 | 
					#ifdef DEBUG_VGA_MEM
 | 
				
			||||||
            printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 | 
					            printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
 | 
				
			||||||
@ -968,6 +999,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 | 
				
			|||||||
        mask = s->sr[VGA_SEQ_PLANE_WRITE];
 | 
					        mask = s->sr[VGA_SEQ_PLANE_WRITE];
 | 
				
			||||||
        s->plane_updated |= mask; /* only used to detect font change */
 | 
					        s->plane_updated |= mask; /* only used to detect font change */
 | 
				
			||||||
        write_mask = mask16[mask];
 | 
					        write_mask = mask16[mask];
 | 
				
			||||||
 | 
					        if (addr * sizeof(uint32_t) >= s->vram_size) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        ((uint32_t *)s->vram_ptr)[addr] =
 | 
					        ((uint32_t *)s->vram_ptr)[addr] =
 | 
				
			||||||
            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
 | 
					            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
 | 
				
			||||||
            (val & write_mask);
 | 
					            (val & write_mask);
 | 
				
			||||||
@ -1046,7 +1080,7 @@ static void vga_get_offsets(VGACommonState *s,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t start_addr, line_offset, line_compare;
 | 
					    uint32_t start_addr, line_offset, line_compare;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
 | 
					    if (vbe_enabled(s)) {
 | 
				
			||||||
        line_offset = s->vbe_line_offset;
 | 
					        line_offset = s->vbe_line_offset;
 | 
				
			||||||
        start_addr = s->vbe_start_addr;
 | 
					        start_addr = s->vbe_start_addr;
 | 
				
			||||||
        line_compare = 65535;
 | 
					        line_compare = 65535;
 | 
				
			||||||
@ -1371,7 +1405,7 @@ static int vga_get_bpp(VGACommonState *s)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
 | 
					    if (vbe_enabled(s)) {
 | 
				
			||||||
        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
 | 
					        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        ret = 0;
 | 
					        ret = 0;
 | 
				
			||||||
@ -1383,7 +1417,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int width, height;
 | 
					    int width, height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
 | 
					    if (vbe_enabled(s)) {
 | 
				
			||||||
        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
 | 
					        width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
 | 
				
			||||||
        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
 | 
					        height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user