|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/3] xen/arm: vgic-v3: Correctly retrieve the vCPU associated to a re-distributor
On Mon, 2015-09-28 at 21:31 +0100, Julien Grall wrote:
> When the guest is accessing the re-distributor, Xen retrieves the base
> of the re-distributor using a mask based on the stride.
>
> Although, when the stride contains multiple set, the corresponding mask
^bits?
(Also, drop the "Although, ").
> will be computed incorrectly [1] and therefore giving invalid vCPU and
> offset:
>
> (XEN) d0v0: vGICR: unknown gpa read address 000000008d130008
> (XEN) traps.c:2447:d0v1 HSR=0x93c08006 pc=0xffffffc00032362c
> gva=0xffffff80000b0008 gpa=0x0000008d130008
>
> For instance if the region of re-distributor is starting at 0x8d100000
> and the stride is 0x30000, an access to the address 0x8d130008 should
> be valid and use the re-distributor of vCPU1 with an offset of 0x8.
> Although, Xen is returning the vCPU0 and an offset of 0x20008.
>
> I didn't find a way to replace the current computation of the mask with
> a valid. The only solution I have found is to pass the region in private
^one
> data of the handler. So we can directly get the offset from the
> beginning of the region and find the corresponding vCPU/offset in the
> re-distributor.
>
> This is also make the code simpler and avoid fast/slow path.
>
> [1] http://lists.xen.org/archives/html/xen-devel/2015-09/msg03372.html
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
>
> ---
> Cc: shameerali.kolothum.thodi@xxxxxxxxxx
> Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
>
> This is technically a good candidate for Xen 4.6. Without it DOM0
> may not be able to bring secondary CPU on platform using a stride
> with multiple bit set [1]. Although, we don't support such platform
> right now. So I would rather defer this change to Xen 4.6.1 and
> avoid possible downside/bug in this patch.
Agreed.
Other than the text:
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
>
> Shamaeerali, I've only tested quickly on the foundation model. Can
> you give a try on your platform to check if it fixes DOM0 boot?
>
> [1]
> http://lists.xen.org/archives/html/xen-devel/2015-09/msg03372.html
> ---
> xen/arch/arm/vgic-v3.c | 58 +++++++++++++++++---------------------------
> ------
> 1 file changed, 20 insertions(+), 38 deletions(-)
>
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index 6a4feb2..0a14184 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -593,55 +593,34 @@ write_ignore_32:
> return 1;
> }
>
> -static inline struct vcpu *get_vcpu_from_rdist(paddr_t gpa,
> - struct vcpu *v,
> - uint32_t *offset)
> +static struct vcpu *get_vcpu_from_rdist(struct domain *d,
> + const struct vgic_rdist_region *region,
> + paddr_t gpa, uint32_t *offset)
> {
> - struct domain *d = v->domain;
> + struct vcpu *v;
> uint32_t stride = d->arch.vgic.rdist_stride;
> - paddr_t base;
> - int i, vcpu_id;
> - struct vgic_rdist_region *region;
> -
> - *offset = gpa & (stride - 1);
> - base = gpa & ~((paddr_t)stride - 1);
> -
> - /* Fast path: the VCPU is trying to access its re-distributor */
> - if ( likely(v->arch.vgic.rdist_base == base) )
> - return v;
> -
> - /* Slow path: the VCPU is trying to access another re-distributor */
> -
> - /*
> - * Find the region where the re-distributor lives. For this purpose,
> - * we look one region ahead as only MMIO range for redistributors
> - * traps here.
> - * Note: The region has been ordered during the GIC initialization
> - */
> - for ( i = 1; i < d->arch.vgic.nr_regions; i++ )
> - {
> - if ( base < d->arch.vgic.rdist_regions[i].base )
> - break;
> - }
> -
> - region = &d->arch.vgic.rdist_regions[i - 1];
> -
> - vcpu_id = region->first_cpu + ((base - region->base) / stride);
> + unsigned int vcpu_id;
>
> + vcpu_id = region->first_cpu + ((gpa - region->base) / stride);
> if ( unlikely(vcpu_id >= d->max_vcpus) )
> return NULL;
>
> - return d->vcpu[vcpu_id];
> + v = d->vcpu[vcpu_id];
> +
> + *offset = gpa - v->arch.vgic.rdist_base;
> +
> + return v;
> }
>
> static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info,
> void *priv)
> {
> uint32_t offset;
> + const struct vgic_rdist_region *region = priv;
>
> perfc_incr(vgicr_reads);
>
> - v = get_vcpu_from_rdist(info->gpa, v, &offset);
> + v = get_vcpu_from_rdist(v->domain, region, info->gpa, &offset);
> if ( unlikely(!v) )
> return 0;
>
> @@ -661,10 +640,11 @@ static int vgic_v3_rdistr_mmio_write(struct vcpu
> *v, mmio_info_t *info,
> void *priv)
> {
> uint32_t offset;
> + const struct vgic_rdist_region *region = priv;
>
> perfc_incr(vgicr_writes);
>
> - v = get_vcpu_from_rdist(info->gpa, v, &offset);
> + v = get_vcpu_from_rdist(v->domain, region, info->gpa, &offset);
> if ( unlikely(!v) )
> return 0;
>
> @@ -1212,10 +1192,12 @@ static int vgic_v3_domain_init(struct domain *d)
> * redistributor is targeted.
> */
> for ( i = 0; i < d->arch.vgic.nr_regions; i++ )
> + {
> + struct vgic_rdist_region *region = &d
> ->arch.vgic.rdist_regions[i];
> +
> register_mmio_handler(d, &vgic_rdistr_mmio_handler,
> - d->arch.vgic.rdist_regions[i].base,
> - d->arch.vgic.rdist_regions[i].size,
> - NULL);
> + region->base, region->size, region);
> + }
>
> d->arch.vgic.ctlr = VGICD_CTLR_DEFAULT;
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |