diff mbox

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

Message ID 4E6E2631.4060300@siemens.com
State New
Headers show

Commit Message

Jan Kiszka Sept. 12, 2011, 3:33 p.m. UTC
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

Comments

Andreas Färber Sept. 12, 2011, 3:45 p.m. UTC | #1
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. UTC | #2
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. UTC | #3
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. UTC | #4
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. UTC | #5
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. UTC | #6
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. UTC | #7
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
diff mbox

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,