Patchwork [v3,5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode

login
register
mail settings
Submitter Jan Kiszka
Date Sept. 12, 2011, 3:33 p.m.
Message ID <4E6E2631.4060300@siemens.com>
Download mbox | patch
Permalink /patch/114389/
State New
Headers show

Comments

Jan Kiszka - Sept. 12, 2011, 3:33 p.m.
On 2011-09-12 17:20, Alexander Graf wrote:
> Jan Kiszka wrote:
>> Most VGA memory access modes require MMIO handling as they demand weird
>> logic to get a byte from or into the video RAM. However, there is one
>> exception: chain 4 mode with all memory planes enabled for writing. This
>> mode actually allows lineary mapping, which can then be combined with
>> dirty logging to accelerate KVM.
>>
>> This patch accelerates specifically VBE accesses like they are used by
>> grub in graphical mode. Not only the standard VGA adapter benefits from
>> this, also vmware and spice in VGA mode.
>>
>> CC: Gerd Hoffmann <kraxel@redhat.com>
>> CC: Avi Kivity <avi@redhat.com>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>   
> 
> [...]
> 
>> +static void vga_update_memory_access(VGACommonState *s)
>> +{
>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>> +    target_phys_addr_t base, offset, size;
>> +
>> +    s->chain4_alias = NULL;
>> +
>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>> +        offset = 0;
>> +        switch ((s->gr[6] >> 2) & 3) {
>> +        case 0:
>> +            base = 0xa0000;
>> +            size = 0x20000;
>> +            break;
>> +        case 1:
>> +            base = 0xa0000;
>> +            size = 0x10000;
>> +            offset = s->bank_offset;
>> +            break;
>> +        case 2:
>> +            base = 0xb0000;
>> +            size = 0x8000;
>> +            break;
>> +        case 3:
>> +            base = 0xb8000;
>> +            size = 0x8000;
>> +            break;
>> +        }
>> +        region = g_malloc(sizeof(*region));
>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>> +                                            region, 2);
>>   
> 
> This one eventually gives me the following in info mtree with -M g3beige
> on qemu-system-ppc:
> 
> (qemu) info mtree
> memory
> system addr 00000000 off 00000000 size 7fffffffffffffff
> -vga.chain4 addr 000a0000 off 00000000 size 10000
> -macio addr 80880000 off 00000000 size 80000
> --macio-nvram addr 00060000 off 00000000 size 20000
> --pmac-ide addr 00020000 off 00000000 size 1000
> --cuda addr 00016000 off 00000000 size 2000
> --escc-bar addr 00013000 off 00000000 size 40
> --dbdma addr 00008000 off 00000000 size 1000
> --heathrow-pic addr 00000000 off 00000000 size 1000
> -vga.rom addr 80800000 off 00000000 size 10000
> -vga.vram addr 80000000 off 00000000 size 800000
> -vga-lowmem addr 800a0000 off 00000000 size 20000
> -escc addr 80013000 off 00000000 size 40
> -isa-mmio addr fe000000 off 00000000 size 200000
> I/O
> io addr 00000000 off 00000000 size 10000
> -cmd646-bmdma addr 00000700 off 00000000 size 10
> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
> -cmd646-cmd addr 00000680 off 00000000 size 4
> -cmd646-data addr 00000600 off 00000000 size 8
> -cmd646-cmd addr 00000580 off 00000000 size 4
> -cmd646-data addr 00000500 off 00000000 size 8
> -ne2000 addr 00000400 off 00000000 size 100
> 
> This ends up overmapping 0xa0000, effectively overwriting kernel data.
> If I #if 0 the offending chunk out, everything is fine. I would assume
> that chain4 really needs to be inside of lowmem? No idea about VGA, but
> I'm sure you know what's going on :).

Does this help?


Jan
Andreas Färber - Sept. 12, 2011, 3:45 p.m.
Am 12.09.2011 17:33, schrieb Jan Kiszka:
> On 2011-09-12 17:20, Alexander Graf wrote:
>> Jan Kiszka wrote:
>>> Most VGA memory access modes require MMIO handling as they demand weird
>>> logic to get a byte from or into the video RAM. However, there is one
>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>> mode actually allows lineary mapping, which can then be combined with
>>> dirty logging to accelerate KVM.
>>>
>>> This patch accelerates specifically VBE accesses like they are used by
>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>> this, also vmware and spice in VGA mode.
>>>
>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>> CC: Avi Kivity <avi@redhat.com>
>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>   
>> [...]
>>
>>> +static void vga_update_memory_access(VGACommonState *s)
>>> +{
>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>> +    target_phys_addr_t base, offset, size;
>>> +
>>> +    s->chain4_alias = NULL;
>>> +
>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>> +        offset = 0;
>>> +        switch ((s->gr[6] >> 2) & 3) {
>>> +        case 0:
>>> +            base = 0xa0000;
>>> +            size = 0x20000;
>>> +            break;
>>> +        case 1:
>>> +            base = 0xa0000;
>>> +            size = 0x10000;
>>> +            offset = s->bank_offset;
>>> +            break;
>>> +        case 2:
>>> +            base = 0xb0000;
>>> +            size = 0x8000;
>>> +            break;
>>> +        case 3:
>>> +            base = 0xb8000;
>>> +            size = 0x8000;
>>> +            break;
>>> +        }
>>> +        region = g_malloc(sizeof(*region));
>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>> +                                            region, 2);
>>>   
>> This one eventually gives me the following in info mtree with -M g3beige
>> on qemu-system-ppc:
>>
>> (qemu) info mtree
>> memory
>> system addr 00000000 off 00000000 size 7fffffffffffffff
>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>> -macio addr 80880000 off 00000000 size 80000
>> --macio-nvram addr 00060000 off 00000000 size 20000
>> --pmac-ide addr 00020000 off 00000000 size 1000
>> --cuda addr 00016000 off 00000000 size 2000
>> --escc-bar addr 00013000 off 00000000 size 40
>> --dbdma addr 00008000 off 00000000 size 1000
>> --heathrow-pic addr 00000000 off 00000000 size 1000
>> -vga.rom addr 80800000 off 00000000 size 10000
>> -vga.vram addr 80000000 off 00000000 size 800000
>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>> -escc addr 80013000 off 00000000 size 40
>> -isa-mmio addr fe000000 off 00000000 size 200000
>> I/O
>> io addr 00000000 off 00000000 size 10000
>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>> -cmd646-cmd addr 00000680 off 00000000 size 4
>> -cmd646-data addr 00000600 off 00000000 size 8
>> -cmd646-cmd addr 00000580 off 00000000 size 4
>> -cmd646-data addr 00000500 off 00000000 size 8
>> -ne2000 addr 00000400 off 00000000 size 100
>>
>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>> If I #if 0 the offending chunk out, everything is fine. I would assume
>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>> I'm sure you know what's going on :).
> Does this help?
>
> diff --git a/hw/vga.c b/hw/vga.c
> index 125fb29..0a0c5a6 100644
> --- a/hw/vga.c
> +++ b/hw/vga.c
> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>              size = 0x8000;
>              break;
>          }
> +        base += isa_mem_base;
>          region = g_malloc(sizeof(*region));
>          memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>          memory_region_add_subregion_overlap(s->legacy_address_space, base,

No longer oopses, but the screen looks chaotic now (black bar at bottom,
part of contents at top etc.).

Andreas
Jan Kiszka - Sept. 12, 2011, 3:49 p.m.
On 2011-09-12 17:45, Andreas Färber wrote:
> Am 12.09.2011 17:33, schrieb Jan Kiszka:
>> On 2011-09-12 17:20, Alexander Graf wrote:
>>> Jan Kiszka wrote:
>>>> Most VGA memory access modes require MMIO handling as they demand weird
>>>> logic to get a byte from or into the video RAM. However, there is one
>>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>>> mode actually allows lineary mapping, which can then be combined with
>>>> dirty logging to accelerate KVM.
>>>>
>>>> This patch accelerates specifically VBE accesses like they are used by
>>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>>> this, also vmware and spice in VGA mode.
>>>>
>>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>>> CC: Avi Kivity <avi@redhat.com>
>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>   
>>> [...]
>>>
>>>> +static void vga_update_memory_access(VGACommonState *s)
>>>> +{
>>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>>> +    target_phys_addr_t base, offset, size;
>>>> +
>>>> +    s->chain4_alias = NULL;
>>>> +
>>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>>> +        offset = 0;
>>>> +        switch ((s->gr[6] >> 2) & 3) {
>>>> +        case 0:
>>>> +            base = 0xa0000;
>>>> +            size = 0x20000;
>>>> +            break;
>>>> +        case 1:
>>>> +            base = 0xa0000;
>>>> +            size = 0x10000;
>>>> +            offset = s->bank_offset;
>>>> +            break;
>>>> +        case 2:
>>>> +            base = 0xb0000;
>>>> +            size = 0x8000;
>>>> +            break;
>>>> +        case 3:
>>>> +            base = 0xb8000;
>>>> +            size = 0x8000;
>>>> +            break;
>>>> +        }
>>>> +        region = g_malloc(sizeof(*region));
>>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>> +                                            region, 2);
>>>>   
>>> This one eventually gives me the following in info mtree with -M g3beige
>>> on qemu-system-ppc:
>>>
>>> (qemu) info mtree
>>> memory
>>> system addr 00000000 off 00000000 size 7fffffffffffffff
>>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>>> -macio addr 80880000 off 00000000 size 80000
>>> --macio-nvram addr 00060000 off 00000000 size 20000
>>> --pmac-ide addr 00020000 off 00000000 size 1000
>>> --cuda addr 00016000 off 00000000 size 2000
>>> --escc-bar addr 00013000 off 00000000 size 40
>>> --dbdma addr 00008000 off 00000000 size 1000
>>> --heathrow-pic addr 00000000 off 00000000 size 1000
>>> -vga.rom addr 80800000 off 00000000 size 10000
>>> -vga.vram addr 80000000 off 00000000 size 800000
>>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>>> -escc addr 80013000 off 00000000 size 40
>>> -isa-mmio addr fe000000 off 00000000 size 200000
>>> I/O
>>> io addr 00000000 off 00000000 size 10000
>>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>>> -cmd646-cmd addr 00000680 off 00000000 size 4
>>> -cmd646-data addr 00000600 off 00000000 size 8
>>> -cmd646-cmd addr 00000580 off 00000000 size 4
>>> -cmd646-data addr 00000500 off 00000000 size 8
>>> -ne2000 addr 00000400 off 00000000 size 100
>>>
>>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>>> If I #if 0 the offending chunk out, everything is fine. I would assume
>>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>>> I'm sure you know what's going on :).
>> Does this help?
>>
>> diff --git a/hw/vga.c b/hw/vga.c
>> index 125fb29..0a0c5a6 100644
>> --- a/hw/vga.c
>> +++ b/hw/vga.c
>> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>>              size = 0x8000;
>>              break;
>>          }
>> +        base += isa_mem_base;
>>          region = g_malloc(sizeof(*region));
>>          memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>          memory_region_add_subregion_overlap(s->legacy_address_space, base,
> 
> No longer oopses, but the screen looks chaotic now (black bar at bottom,
> part of contents at top etc.).

Does this PPC machine map the ISA range and forward VGA accesses to the
adapter in general?

Jan
Jan Kiszka - Sept. 12, 2011, 3:57 p.m.
On 2011-09-12 17:49, Jan Kiszka wrote:
> On 2011-09-12 17:45, Andreas Färber wrote:
>> Am 12.09.2011 17:33, schrieb Jan Kiszka:
>>> On 2011-09-12 17:20, Alexander Graf wrote:
>>>> Jan Kiszka wrote:
>>>>> Most VGA memory access modes require MMIO handling as they demand weird
>>>>> logic to get a byte from or into the video RAM. However, there is one
>>>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>>>> mode actually allows lineary mapping, which can then be combined with
>>>>> dirty logging to accelerate KVM.
>>>>>
>>>>> This patch accelerates specifically VBE accesses like they are used by
>>>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>>>> this, also vmware and spice in VGA mode.
>>>>>
>>>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>>>> CC: Avi Kivity <avi@redhat.com>
>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>   
>>>> [...]
>>>>
>>>>> +static void vga_update_memory_access(VGACommonState *s)
>>>>> +{
>>>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>>>> +    target_phys_addr_t base, offset, size;
>>>>> +
>>>>> +    s->chain4_alias = NULL;
>>>>> +
>>>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>>>> +        offset = 0;
>>>>> +        switch ((s->gr[6] >> 2) & 3) {
>>>>> +        case 0:
>>>>> +            base = 0xa0000;
>>>>> +            size = 0x20000;
>>>>> +            break;
>>>>> +        case 1:
>>>>> +            base = 0xa0000;
>>>>> +            size = 0x10000;
>>>>> +            offset = s->bank_offset;
>>>>> +            break;
>>>>> +        case 2:
>>>>> +            base = 0xb0000;
>>>>> +            size = 0x8000;
>>>>> +            break;
>>>>> +        case 3:
>>>>> +            base = 0xb8000;
>>>>> +            size = 0x8000;
>>>>> +            break;
>>>>> +        }
>>>>> +        region = g_malloc(sizeof(*region));
>>>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>> +                                            region, 2);
>>>>>   
>>>> This one eventually gives me the following in info mtree with -M g3beige
>>>> on qemu-system-ppc:
>>>>
>>>> (qemu) info mtree
>>>> memory
>>>> system addr 00000000 off 00000000 size 7fffffffffffffff
>>>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>>>> -macio addr 80880000 off 00000000 size 80000
>>>> --macio-nvram addr 00060000 off 00000000 size 20000
>>>> --pmac-ide addr 00020000 off 00000000 size 1000
>>>> --cuda addr 00016000 off 00000000 size 2000
>>>> --escc-bar addr 00013000 off 00000000 size 40
>>>> --dbdma addr 00008000 off 00000000 size 1000
>>>> --heathrow-pic addr 00000000 off 00000000 size 1000
>>>> -vga.rom addr 80800000 off 00000000 size 10000
>>>> -vga.vram addr 80000000 off 00000000 size 800000
>>>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>>>> -escc addr 80013000 off 00000000 size 40
>>>> -isa-mmio addr fe000000 off 00000000 size 200000
>>>> I/O
>>>> io addr 00000000 off 00000000 size 10000
>>>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>>>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>>>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>>>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>>>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>>>> -cmd646-cmd addr 00000680 off 00000000 size 4
>>>> -cmd646-data addr 00000600 off 00000000 size 8
>>>> -cmd646-cmd addr 00000580 off 00000000 size 4
>>>> -cmd646-data addr 00000500 off 00000000 size 8
>>>> -ne2000 addr 00000400 off 00000000 size 100
>>>>
>>>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>>>> If I #if 0 the offending chunk out, everything is fine. I would assume
>>>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>>>> I'm sure you know what's going on :).
>>> Does this help?
>>>
>>> diff --git a/hw/vga.c b/hw/vga.c
>>> index 125fb29..0a0c5a6 100644
>>> --- a/hw/vga.c
>>> +++ b/hw/vga.c
>>> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>>>              size = 0x8000;
>>>              break;
>>>          }
>>> +        base += isa_mem_base;
>>>          region = g_malloc(sizeof(*region));
>>>          memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>          memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>
>> No longer oopses, but the screen looks chaotic now (black bar at bottom,
>> part of contents at top etc.).
> 
> Does this PPC machine map the ISA range and forward VGA accesses to the
> adapter in general?

If it does, please post a dump of the VGACommonState while the screen is
corrupted (gdb or via device_show [1]. Maybe I missed some condition
that prevents chain4 optimizations, and your guest triggers this.

Jan

[1] http://thread.gmane.org/gmane.comp.emulators.qemu/114853
Alexander Graf - Sept. 13, 2011, 7:39 a.m.
On 12.09.2011, at 17:57, Jan Kiszka wrote:

> On 2011-09-12 17:49, Jan Kiszka wrote:
>> On 2011-09-12 17:45, Andreas Färber wrote:
>>> Am 12.09.2011 17:33, schrieb Jan Kiszka:
>>>> On 2011-09-12 17:20, Alexander Graf wrote:
>>>>> Jan Kiszka wrote:
>>>>>> Most VGA memory access modes require MMIO handling as they demand weird
>>>>>> logic to get a byte from or into the video RAM. However, there is one
>>>>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>>>>> mode actually allows lineary mapping, which can then be combined with
>>>>>> dirty logging to accelerate KVM.
>>>>>> 
>>>>>> This patch accelerates specifically VBE accesses like they are used by
>>>>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>>>>> this, also vmware and spice in VGA mode.
>>>>>> 
>>>>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>>>>> CC: Avi Kivity <avi@redhat.com>
>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>> 
>>>>> [...]
>>>>> 
>>>>>> +static void vga_update_memory_access(VGACommonState *s)
>>>>>> +{
>>>>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>>>>> +    target_phys_addr_t base, offset, size;
>>>>>> +
>>>>>> +    s->chain4_alias = NULL;
>>>>>> +
>>>>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>>>>> +        offset = 0;
>>>>>> +        switch ((s->gr[6] >> 2) & 3) {
>>>>>> +        case 0:
>>>>>> +            base = 0xa0000;
>>>>>> +            size = 0x20000;
>>>>>> +            break;
>>>>>> +        case 1:
>>>>>> +            base = 0xa0000;
>>>>>> +            size = 0x10000;
>>>>>> +            offset = s->bank_offset;
>>>>>> +            break;
>>>>>> +        case 2:
>>>>>> +            base = 0xb0000;
>>>>>> +            size = 0x8000;
>>>>>> +            break;
>>>>>> +        case 3:
>>>>>> +            base = 0xb8000;
>>>>>> +            size = 0x8000;
>>>>>> +            break;
>>>>>> +        }
>>>>>> +        region = g_malloc(sizeof(*region));
>>>>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>>> +                                            region, 2);
>>>>>> 
>>>>> This one eventually gives me the following in info mtree with -M g3beige
>>>>> on qemu-system-ppc:
>>>>> 
>>>>> (qemu) info mtree
>>>>> memory
>>>>> system addr 00000000 off 00000000 size 7fffffffffffffff
>>>>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>>>>> -macio addr 80880000 off 00000000 size 80000
>>>>> --macio-nvram addr 00060000 off 00000000 size 20000
>>>>> --pmac-ide addr 00020000 off 00000000 size 1000
>>>>> --cuda addr 00016000 off 00000000 size 2000
>>>>> --escc-bar addr 00013000 off 00000000 size 40
>>>>> --dbdma addr 00008000 off 00000000 size 1000
>>>>> --heathrow-pic addr 00000000 off 00000000 size 1000
>>>>> -vga.rom addr 80800000 off 00000000 size 10000
>>>>> -vga.vram addr 80000000 off 00000000 size 800000
>>>>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>>>>> -escc addr 80013000 off 00000000 size 40
>>>>> -isa-mmio addr fe000000 off 00000000 size 200000
>>>>> I/O
>>>>> io addr 00000000 off 00000000 size 10000
>>>>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>>>>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>>>>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>>>>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>>>>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>>>>> -cmd646-cmd addr 00000680 off 00000000 size 4
>>>>> -cmd646-data addr 00000600 off 00000000 size 8
>>>>> -cmd646-cmd addr 00000580 off 00000000 size 4
>>>>> -cmd646-data addr 00000500 off 00000000 size 8
>>>>> -ne2000 addr 00000400 off 00000000 size 100
>>>>> 
>>>>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>>>>> If I #if 0 the offending chunk out, everything is fine. I would assume
>>>>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>>>>> I'm sure you know what's going on :).
>>>> Does this help?
>>>> 
>>>> diff --git a/hw/vga.c b/hw/vga.c
>>>> index 125fb29..0a0c5a6 100644
>>>> --- a/hw/vga.c
>>>> +++ b/hw/vga.c
>>>> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>>>>             size = 0x8000;
>>>>             break;
>>>>         }
>>>> +        base += isa_mem_base;
>>>>         region = g_malloc(sizeof(*region));
>>>>         memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>         memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>> 
>>> No longer oopses, but the screen looks chaotic now (black bar at bottom,
>>> part of contents at top etc.).
>> 
>> Does this PPC machine map the ISA range and forward VGA accesses to the
>> adapter in general?
> 
> If it does, please post a dump of the VGACommonState while the screen is
> corrupted (gdb or via device_show [1]. Maybe I missed some condition
> that prevents chain4 optimizations, and your guest triggers this.

Picture: http://dl.dropbox.com/u/8976842/qemu/Screen%20shot%202011-09-13%20at%2009.37.15.png

(qemu) info qtree 
bus: main-system-bus
  type System
  dev: fw_cfg, id "#8"
    dev-prop: ctl_iobase = 0x0
    dev-prop: data_iobase = 0x0
    irq 0
    mmio f0000510/00000002
    mmio f0000512/00000002
  dev: escc, id "#4"
    dev-prop: frequency = 3686400
    dev-prop: it_shift = 4
    dev-prop: disabled = 0
    dev-prop: disabled = 0
    dev-prop: chnBtype = 0
    dev-prop: chnAtype = 0
    dev-prop: chrB = <null>
    dev-prop: chrA = serial0
    irq 2
    mmio 80013000/00000040
  dev: grackle, id "#1"
    irq 0
    mmio fec00000/00001000
    mmio fee00000/00001000
    bus: pci
      type PCI
      dev: cmd646-ide, id "#6"
        dev-prop: secondary = 0
        bus-prop: addr = 03.0
        bus-prop: romfile = <null>
        bus-prop: rombar = 1
        bus-prop: multifunction = off
        bus-prop: command_serr_enable = on
        class IDE controller, addr 00:03.0, pci id 1095:0646 (sub 1af4:1100)
        bar 0: i/o at 0x500 [0x507]
        bar 1: i/o at 0x580 [0x583]
        bar 2: i/o at 0x600 [0x607]
        bar 3: i/o at 0x680 [0x683]
        bar 4: i/o at 0x700 [0x70f]
        bus: ide.1
          type IDE
        bus: ide.0
          type IDE
          dev: ide-cd, id "#7"
            dev-prop: drive = ide1-cd0
            dev-prop: logical_block_size = 512
            dev-prop: physical_block_size = 512
            dev-prop: min_io_size = 0
            dev-prop: opt_io_size = 0
            dev-prop: bootindex = -1
            dev-prop: discard_granularity = 0
            dev-prop: ver = "0.15.50"
            dev-prop: serial = "QM00003"
            bus-prop: unit = 0
      dev: ne2k_pci, id "#5"
        dev-prop: mac = 52:54:00:12:34:56
        dev-prop: vlan = 0
        dev-prop: netdev = <null>
        dev-prop: bootindex = -1
        bus-prop: addr = 02.0
        bus-prop: romfile = <null>
        bus-prop: rombar = 1
        bus-prop: multifunction = off
        bus-prop: command_serr_enable = on
        class Ethernet controller, addr 00:02.0, pci id 10ec:8029 (sub 1af4:1100)
        bar 0: i/o at 0x400 [0x4ff]
      dev: VGA, id "#3"
        bus-prop: addr = 01.0
        bus-prop: romfile = "vgabios-stdvga.bin"
        bus-prop: rombar = 1
        bus-prop: multifunction = off
        bus-prop: command_serr_enable = on
        class VGA controller, addr 00:01.0, pci id 1234:1111 (sub 1af4:1100)
        bar 0: mem at 0x80000000 [0x807fffff]
        bar 6: mem at 0x80800000 [0x8080ffff]
      dev: grackle, id "#2"
        bus-prop: addr = 00.0
        bus-prop: romfile = <null>
        bus-prop: rombar = 1
        bus-prop: multifunction = off
        bus-prop: command_serr_enable = on
        class Host bridge, addr 00:00.0, pci id 1057:0002 (sub 1af4:1100)



(qemu) device_show #3
dev: VGA, id "#3", version 2
  dev.
    version_id:         00000002
    config:             00 00 00 00 10 d1 cf 20 - 00 00 00 00 10 d1 d0 30
                        ...
    irq_state:          00 00 00 00 00 00 00 10 - 00 00 00 00 00 00 00 00
  vga.
    latch:              00000000
    sr_index:           00
    sr:                 00 00 0f 00 08 00 00 00
    gr_index:           00
    gr:                 00 00 00 00 00 40 05 00 - 00 00 00 00 00 00 00 00
    ar_index:           20
    ar:                 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
                        ...
    ar_flip_flop:       00000001
    cr_index:           00
    cr:                 00 63 00 00 00 00 00 50 - 00 40 00 00 00 00 00 00
                        ...
    msr:                00
    fcr:                00
    st00:               00
    st01:               00
    dac_state:          00
    dac_sub_index:      00
    dac_read_index:     00
    dac_write_index:    10
    dac_cache:          3f 3f 3f
    palette:            00 00 00 00 00 2a 00 2a - 00 00 2a 2a 2a 00 00 2a
                        ...
    bank_offset:        00000000
    is_vbe_vmstate:     01
    vbe_index:          0004
    vbe_regs[00]:       b0c5
    vbe_regs[01]:       0320
    vbe_regs[02]:       0258
    vbe_regs[03]:       000f
    vbe_regs[04]:       0001
    vbe_regs[05]:       0000
    vbe_regs[06]:       0320
    vbe_regs[07]:       0258
    vbe_regs[08]:       0000
    vbe_regs[09]:       0000
    vbe_start_addr:     00000000
    vbe_line_offset:    00000640
    vbe_bank_mask:      0000007f



Thanks!

Alex
Jan Kiszka - Sept. 13, 2011, 8:14 a.m.
On 2011-09-13 09:39, Alexander Graf wrote:
> 
> On 12.09.2011, at 17:57, Jan Kiszka wrote:
> 
>> On 2011-09-12 17:49, Jan Kiszka wrote:
>>> On 2011-09-12 17:45, Andreas Färber wrote:
>>>> Am 12.09.2011 17:33, schrieb Jan Kiszka:
>>>>> On 2011-09-12 17:20, Alexander Graf wrote:
>>>>>> Jan Kiszka wrote:
>>>>>>> Most VGA memory access modes require MMIO handling as they demand weird
>>>>>>> logic to get a byte from or into the video RAM. However, there is one
>>>>>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>>>>>> mode actually allows lineary mapping, which can then be combined with
>>>>>>> dirty logging to accelerate KVM.
>>>>>>>
>>>>>>> This patch accelerates specifically VBE accesses like they are used by
>>>>>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>>>>>> this, also vmware and spice in VGA mode.
>>>>>>>
>>>>>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>>>>>> CC: Avi Kivity <avi@redhat.com>
>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> +static void vga_update_memory_access(VGACommonState *s)
>>>>>>> +{
>>>>>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>>>>>> +    target_phys_addr_t base, offset, size;
>>>>>>> +
>>>>>>> +    s->chain4_alias = NULL;
>>>>>>> +
>>>>>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>>>>>> +        offset = 0;
>>>>>>> +        switch ((s->gr[6] >> 2) & 3) {
>>>>>>> +        case 0:
>>>>>>> +            base = 0xa0000;
>>>>>>> +            size = 0x20000;
>>>>>>> +            break;
>>>>>>> +        case 1:
>>>>>>> +            base = 0xa0000;
>>>>>>> +            size = 0x10000;
>>>>>>> +            offset = s->bank_offset;
>>>>>>> +            break;
>>>>>>> +        case 2:
>>>>>>> +            base = 0xb0000;
>>>>>>> +            size = 0x8000;
>>>>>>> +            break;
>>>>>>> +        case 3:
>>>>>>> +            base = 0xb8000;
>>>>>>> +            size = 0x8000;
>>>>>>> +            break;
>>>>>>> +        }
>>>>>>> +        region = g_malloc(sizeof(*region));
>>>>>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>>>> +                                            region, 2);
>>>>>>>
>>>>>> This one eventually gives me the following in info mtree with -M g3beige
>>>>>> on qemu-system-ppc:
>>>>>>
>>>>>> (qemu) info mtree
>>>>>> memory
>>>>>> system addr 00000000 off 00000000 size 7fffffffffffffff
>>>>>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>>>>>> -macio addr 80880000 off 00000000 size 80000
>>>>>> --macio-nvram addr 00060000 off 00000000 size 20000
>>>>>> --pmac-ide addr 00020000 off 00000000 size 1000
>>>>>> --cuda addr 00016000 off 00000000 size 2000
>>>>>> --escc-bar addr 00013000 off 00000000 size 40
>>>>>> --dbdma addr 00008000 off 00000000 size 1000
>>>>>> --heathrow-pic addr 00000000 off 00000000 size 1000
>>>>>> -vga.rom addr 80800000 off 00000000 size 10000
>>>>>> -vga.vram addr 80000000 off 00000000 size 800000
>>>>>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>>>>>> -escc addr 80013000 off 00000000 size 40
>>>>>> -isa-mmio addr fe000000 off 00000000 size 200000
>>>>>> I/O
>>>>>> io addr 00000000 off 00000000 size 10000
>>>>>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>>>>>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>>>>>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>>>>>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>>>>>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>>>>>> -cmd646-cmd addr 00000680 off 00000000 size 4
>>>>>> -cmd646-data addr 00000600 off 00000000 size 8
>>>>>> -cmd646-cmd addr 00000580 off 00000000 size 4
>>>>>> -cmd646-data addr 00000500 off 00000000 size 8
>>>>>> -ne2000 addr 00000400 off 00000000 size 100
>>>>>>
>>>>>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>>>>>> If I #if 0 the offending chunk out, everything is fine. I would assume
>>>>>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>>>>>> I'm sure you know what's going on :).
>>>>> Does this help?
>>>>>
>>>>> diff --git a/hw/vga.c b/hw/vga.c
>>>>> index 125fb29..0a0c5a6 100644
>>>>> --- a/hw/vga.c
>>>>> +++ b/hw/vga.c
>>>>> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>>>>>             size = 0x8000;
>>>>>             break;
>>>>>         }
>>>>> +        base += isa_mem_base;
>>>>>         region = g_malloc(sizeof(*region));
>>>>>         memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>>         memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>
>>>> No longer oopses, but the screen looks chaotic now (black bar at bottom,
>>>> part of contents at top etc.).
>>>
>>> Does this PPC machine map the ISA range and forward VGA accesses to the
>>> adapter in general?
>>
>> If it does, please post a dump of the VGACommonState while the screen is
>> corrupted (gdb or via device_show [1]. Maybe I missed some condition
>> that prevents chain4 optimizations, and your guest triggers this.
> 
> Picture: http://dl.dropbox.com/u/8976842/qemu/Screen%20shot%202011-09-13%20at%2009.37.15.png
> 
> (qemu) info qtree 
> bus: main-system-bus
>   type System
>   dev: fw_cfg, id "#8"
>     dev-prop: ctl_iobase = 0x0
>     dev-prop: data_iobase = 0x0
>     irq 0
>     mmio f0000510/00000002
>     mmio f0000512/00000002
>   dev: escc, id "#4"
>     dev-prop: frequency = 3686400
>     dev-prop: it_shift = 4
>     dev-prop: disabled = 0
>     dev-prop: disabled = 0
>     dev-prop: chnBtype = 0
>     dev-prop: chnAtype = 0
>     dev-prop: chrB = <null>
>     dev-prop: chrA = serial0
>     irq 2
>     mmio 80013000/00000040
>   dev: grackle, id "#1"
>     irq 0
>     mmio fec00000/00001000
>     mmio fee00000/00001000
>     bus: pci
>       type PCI
>       dev: cmd646-ide, id "#6"
>         dev-prop: secondary = 0
>         bus-prop: addr = 03.0
>         bus-prop: romfile = <null>
>         bus-prop: rombar = 1
>         bus-prop: multifunction = off
>         bus-prop: command_serr_enable = on
>         class IDE controller, addr 00:03.0, pci id 1095:0646 (sub 1af4:1100)
>         bar 0: i/o at 0x500 [0x507]
>         bar 1: i/o at 0x580 [0x583]
>         bar 2: i/o at 0x600 [0x607]
>         bar 3: i/o at 0x680 [0x683]
>         bar 4: i/o at 0x700 [0x70f]
>         bus: ide.1
>           type IDE
>         bus: ide.0
>           type IDE
>           dev: ide-cd, id "#7"
>             dev-prop: drive = ide1-cd0
>             dev-prop: logical_block_size = 512
>             dev-prop: physical_block_size = 512
>             dev-prop: min_io_size = 0
>             dev-prop: opt_io_size = 0
>             dev-prop: bootindex = -1
>             dev-prop: discard_granularity = 0
>             dev-prop: ver = "0.15.50"
>             dev-prop: serial = "QM00003"
>             bus-prop: unit = 0
>       dev: ne2k_pci, id "#5"
>         dev-prop: mac = 52:54:00:12:34:56
>         dev-prop: vlan = 0
>         dev-prop: netdev = <null>
>         dev-prop: bootindex = -1
>         bus-prop: addr = 02.0
>         bus-prop: romfile = <null>
>         bus-prop: rombar = 1
>         bus-prop: multifunction = off
>         bus-prop: command_serr_enable = on
>         class Ethernet controller, addr 00:02.0, pci id 10ec:8029 (sub 1af4:1100)
>         bar 0: i/o at 0x400 [0x4ff]
>       dev: VGA, id "#3"
>         bus-prop: addr = 01.0
>         bus-prop: romfile = "vgabios-stdvga.bin"
>         bus-prop: rombar = 1
>         bus-prop: multifunction = off
>         bus-prop: command_serr_enable = on
>         class VGA controller, addr 00:01.0, pci id 1234:1111 (sub 1af4:1100)
>         bar 0: mem at 0x80000000 [0x807fffff]
>         bar 6: mem at 0x80800000 [0x8080ffff]
>       dev: grackle, id "#2"
>         bus-prop: addr = 00.0
>         bus-prop: romfile = <null>
>         bus-prop: rombar = 1
>         bus-prop: multifunction = off
>         bus-prop: command_serr_enable = on
>         class Host bridge, addr 00:00.0, pci id 1057:0002 (sub 1af4:1100)
> 
> 
> 
> (qemu) device_show #3
> dev: VGA, id "#3", version 2
>   dev.
>     version_id:         00000002
>     config:             00 00 00 00 10 d1 cf 20 - 00 00 00 00 10 d1 d0 30
>                         ...
>     irq_state:          00 00 00 00 00 00 00 10 - 00 00 00 00 00 00 00 00
>   vga.
>     latch:              00000000
>     sr_index:           00
>     sr:                 00 00 0f 00 08 00 00 00
>     gr_index:           00
>     gr:                 00 00 00 00 00 40 05 00 - 00 00 00 00 00 00 00 00
>     ar_index:           20
>     ar:                 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
>                         ...
>     ar_flip_flop:       00000001
>     cr_index:           00
>     cr:                 00 63 00 00 00 00 00 50 - 00 40 00 00 00 00 00 00
>                         ...
>     msr:                00
>     fcr:                00
>     st00:               00
>     st01:               00
>     dac_state:          00
>     dac_sub_index:      00
>     dac_read_index:     00
>     dac_write_index:    10
>     dac_cache:          3f 3f 3f
>     palette:            00 00 00 00 00 2a 00 2a - 00 00 2a 2a 2a 00 00 2a
>                         ...
>     bank_offset:        00000000
>     is_vbe_vmstate:     01
>     vbe_index:          0004
>     vbe_regs[00]:       b0c5
>     vbe_regs[01]:       0320
>     vbe_regs[02]:       0258
>     vbe_regs[03]:       000f
>     vbe_regs[04]:       0001
>     vbe_regs[05]:       0000
>     vbe_regs[06]:       0320
>     vbe_regs[07]:       0258
>     vbe_regs[08]:       0000
>     vbe_regs[09]:       0000
>     vbe_start_addr:     00000000
>     vbe_line_offset:    00000640
>     vbe_bank_mask:      0000007f
> 

Makes no sense, must work with this setup. Maybe it's dynamic effect
when switching modes of bank offsets. Do you have some test image for me?

Jan
Alexander Graf - Sept. 13, 2011, 8:17 a.m.
On 13.09.2011, at 10:14, Jan Kiszka wrote:

> On 2011-09-13 09:39, Alexander Graf wrote:
>> 
>> On 12.09.2011, at 17:57, Jan Kiszka wrote:
>> 
>>> On 2011-09-12 17:49, Jan Kiszka wrote:
>>>> On 2011-09-12 17:45, Andreas Färber wrote:
>>>>> Am 12.09.2011 17:33, schrieb Jan Kiszka:
>>>>>> On 2011-09-12 17:20, Alexander Graf wrote:
>>>>>>> Jan Kiszka wrote:
>>>>>>>> Most VGA memory access modes require MMIO handling as they demand weird
>>>>>>>> logic to get a byte from or into the video RAM. However, there is one
>>>>>>>> exception: chain 4 mode with all memory planes enabled for writing. This
>>>>>>>> mode actually allows lineary mapping, which can then be combined with
>>>>>>>> dirty logging to accelerate KVM.
>>>>>>>> 
>>>>>>>> This patch accelerates specifically VBE accesses like they are used by
>>>>>>>> grub in graphical mode. Not only the standard VGA adapter benefits from
>>>>>>>> this, also vmware and spice in VGA mode.
>>>>>>>> 
>>>>>>>> CC: Gerd Hoffmann <kraxel@redhat.com>
>>>>>>>> CC: Avi Kivity <avi@redhat.com>
>>>>>>>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>>>>>>> 
>>>>>>> [...]
>>>>>>> 
>>>>>>>> +static void vga_update_memory_access(VGACommonState *s)
>>>>>>>> +{
>>>>>>>> +    MemoryRegion *region, *old_region = s->chain4_alias;
>>>>>>>> +    target_phys_addr_t base, offset, size;
>>>>>>>> +
>>>>>>>> +    s->chain4_alias = NULL;
>>>>>>>> +
>>>>>>>> +    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
>>>>>>>> +        offset = 0;
>>>>>>>> +        switch ((s->gr[6] >> 2) & 3) {
>>>>>>>> +        case 0:
>>>>>>>> +            base = 0xa0000;
>>>>>>>> +            size = 0x20000;
>>>>>>>> +            break;
>>>>>>>> +        case 1:
>>>>>>>> +            base = 0xa0000;
>>>>>>>> +            size = 0x10000;
>>>>>>>> +            offset = s->bank_offset;
>>>>>>>> +            break;
>>>>>>>> +        case 2:
>>>>>>>> +            base = 0xb0000;
>>>>>>>> +            size = 0x8000;
>>>>>>>> +            break;
>>>>>>>> +        case 3:
>>>>>>>> +            base = 0xb8000;
>>>>>>>> +            size = 0x8000;
>>>>>>>> +            break;
>>>>>>>> +        }
>>>>>>>> +        region = g_malloc(sizeof(*region));
>>>>>>>> +        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>>>>> +        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>>>>> +                                            region, 2);
>>>>>>>> 
>>>>>>> This one eventually gives me the following in info mtree with -M g3beige
>>>>>>> on qemu-system-ppc:
>>>>>>> 
>>>>>>> (qemu) info mtree
>>>>>>> memory
>>>>>>> system addr 00000000 off 00000000 size 7fffffffffffffff
>>>>>>> -vga.chain4 addr 000a0000 off 00000000 size 10000
>>>>>>> -macio addr 80880000 off 00000000 size 80000
>>>>>>> --macio-nvram addr 00060000 off 00000000 size 20000
>>>>>>> --pmac-ide addr 00020000 off 00000000 size 1000
>>>>>>> --cuda addr 00016000 off 00000000 size 2000
>>>>>>> --escc-bar addr 00013000 off 00000000 size 40
>>>>>>> --dbdma addr 00008000 off 00000000 size 1000
>>>>>>> --heathrow-pic addr 00000000 off 00000000 size 1000
>>>>>>> -vga.rom addr 80800000 off 00000000 size 10000
>>>>>>> -vga.vram addr 80000000 off 00000000 size 800000
>>>>>>> -vga-lowmem addr 800a0000 off 00000000 size 20000
>>>>>>> -escc addr 80013000 off 00000000 size 40
>>>>>>> -isa-mmio addr fe000000 off 00000000 size 200000
>>>>>>> I/O
>>>>>>> io addr 00000000 off 00000000 size 10000
>>>>>>> -cmd646-bmdma addr 00000700 off 00000000 size 10
>>>>>>> --cmd646-bmdma-ioport addr 0000000c off 00000000 size 4
>>>>>>> --cmd646-bmdma-bus addr 00000008 off 00000000 size 4
>>>>>>> --cmd646-bmdma-ioport addr 00000004 off 00000000 size 4
>>>>>>> --cmd646-bmdma-bus addr 00000000 off 00000000 size 4
>>>>>>> -cmd646-cmd addr 00000680 off 00000000 size 4
>>>>>>> -cmd646-data addr 00000600 off 00000000 size 8
>>>>>>> -cmd646-cmd addr 00000580 off 00000000 size 4
>>>>>>> -cmd646-data addr 00000500 off 00000000 size 8
>>>>>>> -ne2000 addr 00000400 off 00000000 size 100
>>>>>>> 
>>>>>>> This ends up overmapping 0xa0000, effectively overwriting kernel data.
>>>>>>> If I #if 0 the offending chunk out, everything is fine. I would assume
>>>>>>> that chain4 really needs to be inside of lowmem? No idea about VGA, but
>>>>>>> I'm sure you know what's going on :).
>>>>>> Does this help?
>>>>>> 
>>>>>> diff --git a/hw/vga.c b/hw/vga.c
>>>>>> index 125fb29..0a0c5a6 100644
>>>>>> --- a/hw/vga.c
>>>>>> +++ b/hw/vga.c
>>>>>> @@ -181,6 +181,7 @@ static void vga_update_memory_access(VGACommonState *s)
>>>>>>            size = 0x8000;
>>>>>>            break;
>>>>>>        }
>>>>>> +        base += isa_mem_base;
>>>>>>        region = g_malloc(sizeof(*region));
>>>>>>        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
>>>>>>        memory_region_add_subregion_overlap(s->legacy_address_space, base,
>>>>> 
>>>>> No longer oopses, but the screen looks chaotic now (black bar at bottom,
>>>>> part of contents at top etc.).
>>>> 
>>>> Does this PPC machine map the ISA range and forward VGA accesses to the
>>>> adapter in general?
>>> 
>>> If it does, please post a dump of the VGACommonState while the screen is
>>> corrupted (gdb or via device_show [1]. Maybe I missed some condition
>>> that prevents chain4 optimizations, and your guest triggers this.
>> 
>> Picture: http://dl.dropbox.com/u/8976842/qemu/Screen%20shot%202011-09-13%20at%2009.37.15.png
>> 
>> (qemu) info qtree 
>> bus: main-system-bus
>>  type System
>>  dev: fw_cfg, id "#8"
>>    dev-prop: ctl_iobase = 0x0
>>    dev-prop: data_iobase = 0x0
>>    irq 0
>>    mmio f0000510/00000002
>>    mmio f0000512/00000002
>>  dev: escc, id "#4"
>>    dev-prop: frequency = 3686400
>>    dev-prop: it_shift = 4
>>    dev-prop: disabled = 0
>>    dev-prop: disabled = 0
>>    dev-prop: chnBtype = 0
>>    dev-prop: chnAtype = 0
>>    dev-prop: chrB = <null>
>>    dev-prop: chrA = serial0
>>    irq 2
>>    mmio 80013000/00000040
>>  dev: grackle, id "#1"
>>    irq 0
>>    mmio fec00000/00001000
>>    mmio fee00000/00001000
>>    bus: pci
>>      type PCI
>>      dev: cmd646-ide, id "#6"
>>        dev-prop: secondary = 0
>>        bus-prop: addr = 03.0
>>        bus-prop: romfile = <null>
>>        bus-prop: rombar = 1
>>        bus-prop: multifunction = off
>>        bus-prop: command_serr_enable = on
>>        class IDE controller, addr 00:03.0, pci id 1095:0646 (sub 1af4:1100)
>>        bar 0: i/o at 0x500 [0x507]
>>        bar 1: i/o at 0x580 [0x583]
>>        bar 2: i/o at 0x600 [0x607]
>>        bar 3: i/o at 0x680 [0x683]
>>        bar 4: i/o at 0x700 [0x70f]
>>        bus: ide.1
>>          type IDE
>>        bus: ide.0
>>          type IDE
>>          dev: ide-cd, id "#7"
>>            dev-prop: drive = ide1-cd0
>>            dev-prop: logical_block_size = 512
>>            dev-prop: physical_block_size = 512
>>            dev-prop: min_io_size = 0
>>            dev-prop: opt_io_size = 0
>>            dev-prop: bootindex = -1
>>            dev-prop: discard_granularity = 0
>>            dev-prop: ver = "0.15.50"
>>            dev-prop: serial = "QM00003"
>>            bus-prop: unit = 0
>>      dev: ne2k_pci, id "#5"
>>        dev-prop: mac = 52:54:00:12:34:56
>>        dev-prop: vlan = 0
>>        dev-prop: netdev = <null>
>>        dev-prop: bootindex = -1
>>        bus-prop: addr = 02.0
>>        bus-prop: romfile = <null>
>>        bus-prop: rombar = 1
>>        bus-prop: multifunction = off
>>        bus-prop: command_serr_enable = on
>>        class Ethernet controller, addr 00:02.0, pci id 10ec:8029 (sub 1af4:1100)
>>        bar 0: i/o at 0x400 [0x4ff]
>>      dev: VGA, id "#3"
>>        bus-prop: addr = 01.0
>>        bus-prop: romfile = "vgabios-stdvga.bin"
>>        bus-prop: rombar = 1
>>        bus-prop: multifunction = off
>>        bus-prop: command_serr_enable = on
>>        class VGA controller, addr 00:01.0, pci id 1234:1111 (sub 1af4:1100)
>>        bar 0: mem at 0x80000000 [0x807fffff]
>>        bar 6: mem at 0x80800000 [0x8080ffff]
>>      dev: grackle, id "#2"
>>        bus-prop: addr = 00.0
>>        bus-prop: romfile = <null>
>>        bus-prop: rombar = 1
>>        bus-prop: multifunction = off
>>        bus-prop: command_serr_enable = on
>>        class Host bridge, addr 00:00.0, pci id 1057:0002 (sub 1af4:1100)
>> 
>> 
>> 
>> (qemu) device_show #3
>> dev: VGA, id "#3", version 2
>>  dev.
>>    version_id:         00000002
>>    config:             00 00 00 00 10 d1 cf 20 - 00 00 00 00 10 d1 d0 30
>>                        ...
>>    irq_state:          00 00 00 00 00 00 00 10 - 00 00 00 00 00 00 00 00
>>  vga.
>>    latch:              00000000
>>    sr_index:           00
>>    sr:                 00 00 0f 00 08 00 00 00
>>    gr_index:           00
>>    gr:                 00 00 00 00 00 40 05 00 - 00 00 00 00 00 00 00 00
>>    ar_index:           20
>>    ar:                 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
>>                        ...
>>    ar_flip_flop:       00000001
>>    cr_index:           00
>>    cr:                 00 63 00 00 00 00 00 50 - 00 40 00 00 00 00 00 00
>>                        ...
>>    msr:                00
>>    fcr:                00
>>    st00:               00
>>    st01:               00
>>    dac_state:          00
>>    dac_sub_index:      00
>>    dac_read_index:     00
>>    dac_write_index:    10
>>    dac_cache:          3f 3f 3f
>>    palette:            00 00 00 00 00 2a 00 2a - 00 00 2a 2a 2a 00 00 2a
>>                        ...
>>    bank_offset:        00000000
>>    is_vbe_vmstate:     01
>>    vbe_index:          0004
>>    vbe_regs[00]:       b0c5
>>    vbe_regs[01]:       0320
>>    vbe_regs[02]:       0258
>>    vbe_regs[03]:       000f
>>    vbe_regs[04]:       0001
>>    vbe_regs[05]:       0000
>>    vbe_regs[06]:       0320
>>    vbe_regs[07]:       0258
>>    vbe_regs[08]:       0000
>>    vbe_regs[09]:       0000
>>    vbe_start_addr:     00000000
>>    vbe_line_offset:    00000640
>>    vbe_bank_mask:      0000007f
>> 
> 
> Makes no sense, must work with this setup. Maybe it's dynamic effect
> when switching modes of bank offsets. Do you have some test image for me?

No need for an image - the black bar already occurs in firmware. If you want to check that everything really does work, Aurelien has a great collection of QEMU Debian images:

  http://people.debian.org/~aurel32/qemu/powerpc/


Thanks for looking into this :)

Alex
Andreas Färber - Sept. 13, 2011, 8:19 a.m.
Am 13.09.2011 um 10:14 schrieb Jan Kiszka:

> On 2011-09-13 09:39, Alexander Graf wrote:
>> (qemu) device_show #3
>> dev: VGA, id "#3", version 2
>>  dev.
>>    version_id:         00000002
>>    config:             00 00 00 00 10 d1 cf 20 - 00 00 00 00 10 d1  
>> d0 30
>>                        ...
>>    irq_state:          00 00 00 00 00 00 00 10 - 00 00 00 00 00 00  
>> 00 00
>>  vga.
>>    latch:              00000000
>>    sr_index:           00
>>    sr:                 00 00 0f 00 08 00 00 00
>>    gr_index:           00
>>    gr:                 00 00 00 00 00 40 05 00 - 00 00 00 00 00 00  
>> 00 00
>>    ar_index:           20
>>    ar:                 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00  
>> 00 00
>>                        ...
>>    ar_flip_flop:       00000001
>>    cr_index:           00
>>    cr:                 00 63 00 00 00 00 00 50 - 00 40 00 00 00 00  
>> 00 00
>>                        ...
>>    msr:                00
>>    fcr:                00
>>    st00:               00
>>    st01:               00
>>    dac_state:          00
>>    dac_sub_index:      00
>>    dac_read_index:     00
>>    dac_write_index:    10
>>    dac_cache:          3f 3f 3f
>>    palette:            00 00 00 00 00 2a 00 2a - 00 00 2a 2a 2a 00  
>> 00 2a
>>                        ...
>>    bank_offset:        00000000
>>    is_vbe_vmstate:     01
>>    vbe_index:          0004
>>    vbe_regs[00]:       b0c5
>>    vbe_regs[01]:       0320
>>    vbe_regs[02]:       0258
>>    vbe_regs[03]:       000f
>>    vbe_regs[04]:       0001
>>    vbe_regs[05]:       0000
>>    vbe_regs[06]:       0320
>>    vbe_regs[07]:       0258
>>    vbe_regs[08]:       0000
>>    vbe_regs[09]:       0000
>>    vbe_start_addr:     00000000
>>    vbe_line_offset:    00000640
>>    vbe_bank_mask:      0000007f
>>
>
> Makes no sense, must work with this setup. Maybe it's dynamic effect
> when switching modes of bank offsets. Do you have some test image  
> for me?

I've been using a Debian netinst image, but businesscard should do as  
well:
http://cdimage.debian.org/debian-cd/6.0.2.1/powerpc/iso-cd/debian-6.0.2.1-powerpc-businesscard.iso

qemu-system-ppc -boot d -cdrom path/to.iso # at yaboot prompt type:  
install

Then in addition to the black bar in Alex' image, the penguin gets  
beheaded.

Andreas

Patch

diff --git a/hw/vga.c b/hw/vga.c
index 125fb29..0a0c5a6 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -181,6 +181,7 @@  static void vga_update_memory_access(VGACommonState *s)
             size = 0x8000;
             break;
         }
+        base += isa_mem_base;
         region = g_malloc(sizeof(*region));
         memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
         memory_region_add_subregion_overlap(s->legacy_address_space, base,