qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Fix guest OS hangs on boot when 64bit PCI BAR p


From: Alexey Korolev
Subject: Re: [Qemu-devel] [PATCH] Fix guest OS hangs on boot when 64bit PCI BAR present
Date: Thu, 14 Feb 2013 13:55:01 +1300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2

On 13/02/13 23:26, Michael S. Tsirkin wrote:
> On Wed, Feb 13, 2013 at 06:14:33PM +1300, Alexey Korolev wrote:
>> At the moment may_overlap flag of MemoryRegion structure
>> is ignored by the address range assignment process.
>> This may lead to guest OS hangs if critical qemu
>> resources are overlapped by PCI BARs. For example
>> ivshmem 64bit PCI BAR may overlap kvm-apic-msi under
>> certain conditions. This patch adds a rule that the
>> regions which should not be overlapped are added to the
>> view first (i.e. having highest priority). The patch
>> also corrects ivshmem bar resource to be overlapable
>> which is the default for PCI BARs
>>
>> Signed-off-by: Alexey Korolev <address@hidden>
> Since overlap is currently used inconsistently, it's hard to
> know what this will do. Maybe we should just drop the overlap
> flag and use priorities instead?
It sounds like a good idea.
>
>> ---
>>  hw/ivshmem.c |    2 +-
>>  memory.c     |   15 ++++++++++-----
>>  2 files changed, 11 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
>> index afaf9b3..1770fa3 100644
>> --- a/hw/ivshmem.c
>> +++ b/hw/ivshmem.c
>> @@ -341,7 +341,7 @@ static void create_shared_memory_BAR(IVShmemState *s, 
>> int fd) {
>>      memory_region_init_ram_ptr(&s->ivshmem, "ivshmem.bar2",
>>                                 s->ivshmem_size, ptr);
>>      vmstate_register_ram(&s->ivshmem, &s->dev.qdev);
>> -    memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
>> +    memory_region_add_subregion_overlap(&s->bar, 0, &s->ivshmem, 1);
>>  
>>      /* region for shared memory */
>>      pci_register_bar(&s->dev, 2, s->ivshmem_attr, &s->bar);
> So why this change, exactly?
memory_region_add_subregion adds a non-overlappable memory region, this is 
incorrect, becauase rest PCI bars by default are overlappable.
I replaced memory_region_add_subregion with memory_region_add_subregion_overlap 
to make the region overlappable so it doesn't  compete with
kvm-apic-msi for address range.

In other words without this change ivshmem.bar2 will occupy address range of 
kvm-apic-msi because they have same priority and flags.

>
>> diff --git a/memory.c b/memory.c
>> index cd7d5e0..f1119e7 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -475,7 +475,8 @@ static void render_memory_region(FlatView *view,
>>                                   MemoryRegion *mr,
>>                                   Int128 base,
>>                                   AddrRange clip,
>> -                                 bool readonly)
>> +                                 bool readonly,
>> +                                 bool overlap)
>>  {
>>      MemoryRegion *subregion;
>>      unsigned i;
>> @@ -503,16 +504,16 @@ static void render_memory_region(FlatView *view,
>>      if (mr->alias) {
>>          int128_subfrom(&base, int128_make64(mr->alias->addr));
>>          int128_subfrom(&base, int128_make64(mr->alias_offset));
>> -        render_memory_region(view, mr->alias, base, clip, readonly);
>> +        render_memory_region(view, mr->alias, base, clip, readonly, 
>> overlap);
>>          return;
>>      }
>>  
>>      /* Render subregions in priority order. */
>>      QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
>> -        render_memory_region(view, subregion, base, clip, readonly);
>> +        render_memory_region(view, subregion, base, clip, readonly, 
>> overlap);
>>      }
>>  
>> -    if (!mr->terminates) {
>> +    if (mr->may_overlap != overlap || !mr->terminates) {
>>          return;
>>      }
>>  
>> @@ -567,7 +568,11 @@ static FlatView generate_memory_topology(MemoryRegion 
>> *mr)
>>  
>>      if (mr) {
>>          render_memory_region(&view, mr, int128_zero(),
>> -                             addrrange_make(int128_zero(), int128_2_64()), 
>> false);
>> +                             addrrange_make(int128_zero(), int128_2_64()),
>> +                             false, false);
>> +        render_memory_region(&view, mr, int128_zero(),
>> +                             addrrange_make(int128_zero(), int128_2_64()),
>> +                             false, true);
>>      }
>>      flatview_simplify(&view);
>>  
>> -- 
>> 1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]