> -----Original Message-----
> From: Alexander Graf [mailto:ag...@suse.de]
> Sent: Wednesday, September 10, 2014 4:56 PM
> To: Purcareata Bogdan-B43198; Wood Scott-B07421
> Cc: Caraman Mihai Claudiu-B02008; qemu-...@nongnu.org; qemu-devel@nongnu.org
> Subject: Re: [Qemu-ppc] [PATCH 2/2] PPC: openpic_kvm: Filter region callbacks
> based on memory region offset
> 
> 
> 
> On 10.09.14 13:40, bogdan.purcare...@freescale.com wrote:
> >> -----Original Message-----
> >> From: Wood Scott-B07421
> >> Sent: Friday, September 05, 2014 6:47 PM
> >> To: Purcareata Bogdan-B43198
> >> Cc: qemu-...@nongnu.org; Caraman Mihai Claudiu-B02008; qemu-
> de...@nongnu.org
> >> Subject: Re: [Qemu-ppc] [PATCH 2/2] PPC: openpic_kvm: Filter region
> callbacks
> >> based on memory region offset
> >>
> >> On Wed, 2014-09-03 at 14:36 -0400, Bogdan Purcareata wrote:
> >>> This is done due to the fact that the kvm-openpic region_{add,del}
> callbacks
> >>> can be invoked for sections generated from other memory regions as well.
> >> These
> >>> callbacks should handle only requests for the kvm-openpic memory region.
> >>>
> >>> The patch fixes a bug on target-ppc occuring when the "e500-pci-bar0"
> memory
> >>> region is added. This memory region registers an alias to the "e500-ccsr"
> >> memory
> >>> region, which further contains the "kvm-openpic" subregion. Due to this
> >> alias,
> >>> the kvm_openpic_region_add is called once more, with an offset within the
> >>> "e500-pci-bar" memory region. This generates the remapping of the
> >>> in-kernel MPIC at a wrong offset.
> >>
> >> OK, so the problem is that we really do have the MPIC mapped in two
> >> locations (and the kernel API only lets us map one of them).  It would
> >> be nice if the MemoryRegionSection struct indicated the alias being
> >> represented rather than needing to recalculate the non-aliased address.
> >
> > Not sure I fully understand the terminology of the alias being represented.
> In fact, out of the two mentioned in the previous mail, "e500-pci-bar0" and
> "e500-ccsr", I don't know which one is the "alias".
> >
> > If it's the former, thus "e500-pci-bar0" is an alias for "e500-ccsr", this
> information could be propagated down to the MemoryRegionSection. However,
> according to [1], "aliases may point to any type of region, including other
> aliases". So if the MemoryRegionSection has been built by going through a
> chain of aliases, all this information must be included in the structure.
> >
> > If it's the latter, thus "e500-ccsr" is an alias for "e500-pci-bar0", we can
> get to it in the current model as well. For our specific case, the
> MemoryRegionSection points to the "kvm-openpic" MemoryRegion, which in turn
> points to "e500-ccsr" as its parent (container).
> >
> > What do you think?
> 
> I don't think it matters whether a mapping is an alias or not. What your
> patch really does is it only allows for a single mapping to happen. The
> first one wins.
> 
> I think that's reasonable.
> 
> However, there's no need to extend the memory API with anything here.
> The only reason you need the additional call is because you need to
> figure out where you think you were mapped. But since we set up the map
> ourselves in an ioctl, we already know where we are mapped.
> 
> How about this patch?

Yes, this patch fixes the issue and follows a simpler approach.

Would you like to submit it or should I send a v2 with your changes?

Thanks,
Bogdan P.

> 
> Alex
> 
> diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
> index e3bce04..3e2cd18 100644
> --- a/hw/intc/openpic_kvm.c
> +++ b/hw/intc/openpic_kvm.c
> @@ -45,6 +45,7 @@ typedef struct KVMOpenPICState {
>      MemoryListener mem_listener;
>      uint32_t fd;
>      uint32_t model;
> +    hwaddr mapped;
>  } KVMOpenPICState;
> 
>  static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
> @@ -128,7 +129,16 @@ static void kvm_openpic_region_add(MemoryListener
> *listener,
>          return;
>      }
> 
> +    if (opp->mapped) {
> +        /*
> +         * We can only map the MPIC once. Since we are already mapped,
> +         * the best we can do is ignore new maps.
> +         */
> +        return;
> +    }
> +
>      reg_base = section->offset_within_address_space;
> +    opp->mapped = reg_base;
> 
>      attr.group = KVM_DEV_MPIC_GRP_MISC;
>      attr.attr = KVM_DEV_MPIC_BASE_ADDR;
> @@ -155,6 +165,15 @@ static void kvm_openpic_region_del(MemoryListener
> *listener,
>          return;
>      }
> 
> +    if (section->offset_within_address_space != opp->mapped) {
> +        /*
> +         * We can only map the MPIC once. This mapping was a secondary
> +         * one that we couldn't fulfill. Ignore it.
> +         */
> +        return;
> +    }
> +    opp->mapped = 0;
> +
>      attr.group = KVM_DEV_MPIC_GRP_MISC;
>      attr.attr = KVM_DEV_MPIC_BASE_ADDR;
>      attr.addr = (uint64_t)(unsigned long)&reg_base;

Reply via email to