diff mbox

qemu-ppc (prep) crashes with NetBSD guest

Message ID E3198CCE-550C-4ABD-B049-EDFD0F5CBC31@suse.de
State New
Headers show

Commit Message

Alexander Graf Aug. 15, 2013, 1 p.m. UTC
On 13.08.2013, at 08:45, Felix Deichmann wrote:

> Hi,
> 
> I tried to install NetBSD/prep 6.1 in qemu-ppc (-M prep), but qemu
> crashes during installation with "floating point exception" in a
> reproducible way.
> 
> qemu is version 1.5.2-1 from Arch Linux (sorry, didn't have the time
> to build a current one) on a x86_64 host. The same happens with Win
> qemu 1.5.1 binaries from http://lassauge.free.fr/qemu/.
> I boot a custom NetBSD installation image ("sysinst_com0.fs") via the
> "-kernel" option, and use a serial console (VGA doesn't work for me).
> The custom image contains a kernel which does not use NetBSD's pnpbus
> for prep, but hardwired device configuration like ISA IDE
> controller's, as qemu seems to miss PnP information found on real PReP
> machines completely?
> 
> # qemu-system-ppc -nographic -M prep -m 128M -hda hda.qcow2 -cdrom
> NetBSD-6.1-prep.iso -serial ... -kernel sysinst_com0.fs
> 
> There seems to be a connection between the amount of RAM chosen and
> the point where the crash happens. With 128M, qemu will crash when the
> installer extracts some of the earlier packages, with 256M the crash
> will happen later when extracting. Each one is reproducible at the
> exact point of installation. And the amount of bytes extracted could
> be the amount of RAM minus some number.
> (64M and >256MB won't boot at all, so I could not finish installation...)
> 
> The boot image I used can be found at:
> http://www.flxd.de/netbsd/qemu-ppc/sysinst_com0.fs
> 
> The ISO is the standard one from NetBSD.
> 
> Would be great if someone (also with a current qemu) could have a
> look, as I did not even manage to get a core file...

Gerd, this seems to be vbe related and you're the only person I know who might have a clue what's going on there :). Based on where the VGA code was crashing I came up with the following patch, but I'd assume the underlying issue is somewhere else.

  1) During line_offset set val == 0, so we get a division by 0
  2) the VBE ENABLE call tries to clear the frame buffer, but its calculation is bigger than the allocated size


Alex

Comments

Gerd Hoffmann Aug. 15, 2013, 1:39 p.m. UTC | #1
Hi,

>> # qemu-system-ppc -nographic -M prep -m 128M -hda hda.qcow2 -cdrom 
>> NetBSD-6.1-prep.iso -serial ... -kernel sysinst_com0.fs
>> 
>> There seems to be a connection between the amount of RAM chosen
>> and the point where the crash happens. With 128M, qemu will crash
>> when the installer extracts some of the earlier packages, with 256M
>> the crash will happen later when extracting. Each one is
>> reproducible at the exact point of installation. And the amount of
>> bytes extracted could be the amount of RAM minus some number. (64M
>> and >256MB won't boot at all, so I could not finish
>> installation...)

>> Would be great if someone (also with a current qemu) could have a 
>> look, as I did not even manage to get a core file...
> 
> Gerd, this seems to be vbe related and you're the only person I know
> who might have a clue what's going on there :). Based on where the
> VGA code was crashing I came up with the following patch, but I'd
> assume the underlying issue is somewhere else.

Most likely it's somewhere else, yes.  I put my money on someone writing
random yunk into the vga's mmio bar, maybe due to netbsd not detecting
memory correctly.

What does 'info mtree' in the monitor print?

If you append '-global VGA.mmio=0' to the qemu command line, does that
change behavior?

cheers,
  Gerd
Alexander Graf Aug. 15, 2013, 2:04 p.m. UTC | #2
On 15.08.2013, at 15:39, Gerd Hoffmann wrote:

>  Hi,
> 
>>> # qemu-system-ppc -nographic -M prep -m 128M -hda hda.qcow2 -cdrom 
>>> NetBSD-6.1-prep.iso -serial ... -kernel sysinst_com0.fs
>>> 
>>> There seems to be a connection between the amount of RAM chosen
>>> and the point where the crash happens. With 128M, qemu will crash
>>> when the installer extracts some of the earlier packages, with 256M
>>> the crash will happen later when extracting. Each one is
>>> reproducible at the exact point of installation. And the amount of
>>> bytes extracted could be the amount of RAM minus some number. (64M
>>> and >256MB won't boot at all, so I could not finish
>>> installation...)
> 
>>> Would be great if someone (also with a current qemu) could have a 
>>> look, as I did not even manage to get a core file...
>> 
>> Gerd, this seems to be vbe related and you're the only person I know
>> who might have a clue what's going on there :). Based on where the
>> VGA code was crashing I came up with the following patch, but I'd
>> assume the underlying issue is somewhere else.
> 
> Most likely it's somewhere else, yes.  I put my money on someone writing
> random yunk into the vga's mmio bar, maybe due to netbsd not detecting
> memory correctly.

Well, the piece I'm mostly wary of here is that junk can memset() beyond boundaries. Maybe junk can also explicitly bitblt beyond boundaries and thus overwrite host memory? That'd be pretty nasty.

> What does 'info mtree' in the monitor print?

(qemu) info mtree
memory
0000000000000000-7ffffffffffffffe (prio 0, RW): system
  0000000000000000-0000000007ffffff (prio 0, RW): ppc_prep.ram
  0000000001000000-0000000001ffffff (prio 1, RW): vga.vram
  0000000002010000-0000000002010fff (prio 1, RW): vga.mmio
    0000000002010400-000000000201041f (prio 0, RW): vga ioports remapped
    0000000002010500-0000000002010515 (prio 0, RW): bochs dispi interface
  0000000080000000-00000000807fffff (prio 0, RW): ppc-io
  0000000080800000-0000000080bfffff (prio 0, RW): pciio
  00000000bffffff0-00000000bffffff0 (prio 0, RW): pci-intack
  00000000c00a0000-00000000c00affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff
  00000000c00a0000-00000000c00bffff (prio 1, RW): vga-lowmem
  00000000fff00000-00000000ffffffff (prio 0, R-): ppc_prep.bios
I/O
0000000000000000-000000000000ffff (prio 0, RW): io
  0000000000000000-0000000000000007 (prio 0, RW): dma-chan
  0000000000000008-000000000000000f (prio 0, RW): dma-cont
  0000000000000020-0000000000000021 (prio 0, RW): pic
  0000000000000040-0000000000000043 (prio 0, RW): pit
  0000000000000060-0000000000000060 (prio 0, RW): i8042-data
  0000000000000061-0000000000000061 (prio 0, RW): elcr
  0000000000000064-0000000000000064 (prio 0, RW): i8042-cmd
  0000000000000070-0000000000000071 (prio 0, RW): rtc
  0000000000000074-0000000000000077 (prio 0, RW): m48t59
  0000000000000081-0000000000000083 (prio 0, RW): alias dma-page @dma-page 0000000000000081-0000000000000083
  0000000000000087-0000000000000087 (prio 0, RW): alias dma-page @dma-page 0000000000000087-0000000000000087
  0000000000000089-000000000000008b (prio 0, RW): alias dma-page @dma-page 0000000000000089-000000000000008b
  000000000000008f-000000000000008f (prio 0, RW): alias dma-page @dma-page 000000000000008f-000000000000008f
  00000000000000a0-00000000000000a1 (prio 0, RW): pic
  00000000000000c0-00000000000000cf (prio 0, RW): dma-chan
  00000000000000d0-00000000000000df (prio 0, RW): dma-cont
  0000000000000170-0000000000000177 (prio 0, RW): alias ide @ide 0000000000000170-0000000000000177
  00000000000001ce-00000000000001ce (prio 0, RW): alias vbe @vbe 00000000000001ce-00000000000001ce
  00000000000001d0-00000000000001d0 (prio 0, RW): alias vbe @vbe 00000000000001d0-00000000000001d0
  00000000000001f0-00000000000001f7 (prio 0, RW): alias ide @ide 00000000000001f0-00000000000001f7
  00000000000002f8-00000000000002ff (prio 0, RW): serial
  0000000000000300-000000000000031f (prio 0, RW): ne2000
  0000000000000376-0000000000000376 (prio 0, RW): alias ide @ide 0000000000000376-0000000000000376
  0000000000000398-0000000000000399 (prio 0, RW): pc87312
  00000000000003b4-00000000000003b5 (prio 0, RW): alias vga @vga 00000000000003b4-00000000000003b5
  00000000000003ba-00000000000003ba (prio 0, RW): alias vga @vga 00000000000003ba-00000000000003ba
  00000000000003bc-00000000000003c3 (prio 0, RW): alias parallel @parallel 00000000000003bc-00000000000003c3
  00000000000003c0-00000000000003cf (prio 0, RW): alias vga @vga 00000000000003c0-00000000000003cf
  00000000000003d4-00000000000003d5 (prio 0, RW): alias vga @vga 00000000000003d4-00000000000003d5
  00000000000003da-00000000000003da (prio 0, RW): alias vga @vga 00000000000003da-00000000000003da
  00000000000003f1-00000000000003f5 (prio 0, RW): alias fdc @fdc 00000000000003f1-00000000000003f5
  00000000000003f6-00000000000003f6 (prio 0, RW): alias ide @ide 00000000000003f6-00000000000003f6
  00000000000003f7-00000000000003f7 (prio 0, RW): alias fdc @fdc 00000000000003f7-00000000000003f7
  00000000000003f8-00000000000003ff (prio 0, RW): serial
  0000000000000481-0000000000000483 (prio 0, RW): alias dma-pageh @dma-pageh 0000000000000481-0000000000000483
  0000000000000487-0000000000000489 (prio 0, RW): alias dma-pageh @dma-pageh 0000000000000487-0000000000000489
  0000000000000489-000000000000048b (prio 0, RW): alias dma-pageh @dma-pageh 0000000000000489-000000000000048b
  000000000000048f-0000000000000491 (prio 0, RW): alias dma-pageh @dma-pageh 000000000000048f-0000000000000491
  00000000000004d0-00000000000004d0 (prio 0, RW): elcr
  00000000000004d1-00000000000004d1 (prio 0, RW): elcr
  0000000000000cf8-0000000000000cf8 (prio 0, RW): pci-conf-idx
  0000000000000cfc-0000000000000cfc (prio 0, RW): pci-conf-data
raven
0000000000000000-7ffffffffffffffe (prio 0, RW): alias bus master @system 0000000000000000-7ffffffffffffffe
i82378
0000000000000000-7ffffffffffffffe (prio 0, RW): alias bus master @system 0000000000000000-7ffffffffffffffe
VGA
0000000000000000-7ffffffffffffffe (prio 0, RW): alias bus master @system 0000000000000000-7ffffffffffffffe
aliases
vga.vram
0000000001000000-0000000001ffffff (prio 1, RW): vga.vram
dma-page
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-page
dma-page
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-page
dma-page
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-page
dma-page
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-page
ide
0000000000000000-7ffffffffffffffe (prio 0, RW): ide
vbe
0000000000000000-7ffffffffffffffe (prio 0, RW): vbe
vbe
0000000000000000-7ffffffffffffffe (prio 0, RW): vbe
ide
0000000000000000-7ffffffffffffffe (prio 0, RW): ide
ide
0000000000000000-7ffffffffffffffe (prio 0, RW): ide
vga
0000000000000000-7ffffffffffffffe (prio 0, RW): vga
vga
0000000000000000-7ffffffffffffffe (prio 0, RW): vga
parallel
0000000000000000-7ffffffffffffffe (prio 0, RW): parallel
vga
0000000000000000-7ffffffffffffffe (prio 0, RW): vga
vga
0000000000000000-7ffffffffffffffe (prio 0, RW): vga
vga
0000000000000000-7ffffffffffffffe (prio 0, RW): vga
fdc
0000000000000000-7ffffffffffffffe (prio 0, RW): fdc
ide
0000000000000000-7ffffffffffffffe (prio 0, RW): ide
fdc
0000000000000000-7ffffffffffffffe (prio 0, RW): fdc
dma-pageh
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-pageh
dma-pageh
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-pageh
dma-pageh
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-pageh
dma-pageh
0000000000000000-7ffffffffffffffe (prio 0, RW): dma-pageh
system
0000000000000000-7ffffffffffffffe (prio 0, RW): system
  0000000000000000-0000000007ffffff (prio 0, RW): ppc_prep.ram
  0000000001000000-0000000001ffffff (prio 1, RW): vga.vram
  0000000002010000-0000000002010fff (prio 1, RW): vga.mmio
    0000000002010400-000000000201041f (prio 0, RW): vga ioports remapped
    0000000002010500-0000000002010515 (prio 0, RW): bochs dispi interface
  0000000080000000-00000000807fffff (prio 0, RW): ppc-io
  0000000080800000-0000000080bfffff (prio 0, RW): pciio
  00000000bffffff0-00000000bffffff0 (prio 0, RW): pci-intack
  00000000c00a0000-00000000c00affff (prio 2, RW): alias vga.chain4 @vga.vram 0000000000000000-000000000000ffff
  00000000c00a0000-00000000c00bffff (prio 1, RW): vga-lowmem
  00000000fff00000-00000000ffffffff (prio 0, R-): ppc_prep.bios

> 
> If you append '-global VGA.mmio=0' to the qemu command line, does that
> change behavior?

Yup, that makes it work. -vga none also works btw ;).


Alex
diff mbox

Patch

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 21a108d..0ea9b2d 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -697,7 +697,8 @@  void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                 /* clear the screen (should be done in BIOS) */
                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
                     memset(s->vram_ptr, 0,
-                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
+                           MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES] *
+                               s->vbe_line_offset, s->vram_size));
                 }

                 /* we initialize the VGA graphic mode (should be done
@@ -743,7 +744,7 @@  void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             break;
         case VBE_DISPI_INDEX_VIRT_WIDTH:
             {
-                int w, h, line_offset;
+                int w, h = 0, line_offset;

                 if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
                     return;
@@ -752,7 +753,9 @@  void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                     line_offset = w >> 1;
                 else
                     line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
-                h = s->vram_size / line_offset;
+                if (line_offset > 0) {
+                    h = s->vram_size / line_offset;
+                }
                 /* XXX: support weird bochs semantics ? */
                 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
                     return;