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

[Xen-changelog] [xen staging-4.9] xen/arm: vgic-v3: Don't create empty re-distributor regions



commit 0437ba0e578d089eb24fc493575cd0e8f2584ec7
Author:     Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Mon Jan 28 14:54:52 2019 -0800
Commit:     Stefano Stabellini <sstabellini@xxxxxxxxxx>
CommitDate: Tue Jan 29 09:14:43 2019 -0800

    xen/arm: vgic-v3: Don't create empty re-distributor regions
    
    At the moment, Xen is assuming the hardware domain will have the same
    number of re-distributor regions as the host. However, as the
    number of CPUs or the stride (e.g on GICv4) may be different we end up
    exposing regions which does not contain any re-distributors.
    
    When booting, Linux will go through all the re-distributor region to
    check whether a property (e.g vPLIs) is available accross all the
    re-distributors. This will result to a data abort on empty regions
    because there are no underlying re-distributor.
    
    So we need to limit the number of regions exposed to the hardware
    domain. The code reworked to only expose the minimun number of regions
    required by the hardware domain. It is assumed the regions will be
    populated starting from the first one.
    
    Lastly, rename vgic_v3_rdist_count to reflect the value return by the
    helper.
    
    Reported-by: Shameerali Kolothum Thodi 
<shameerali.kolothum.thodi@xxxxxxxxxx>
    Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
    Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@xxxxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    (cherry picked from commit 54ec59f6b0b363c34cf1864d5214a05e35ea75ee)
---
 xen/arch/arm/gic-v3.c  |  6 ++++++
 xen/arch/arm/vgic-v3.c | 21 ++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index d2b0b1e5b3..6d7243131b 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1151,6 +1151,8 @@ static int gicv3_make_hwdom_dt_node(const struct domain 
*d,
      * GIC has two memory regions: Distributor + rdist regions
      * CPU interface and virtual cpu interfaces accessesed as System registers
      * So cells are created only for Distributor and rdist regions
+     * The hardware domain may not use all the regions. So only copy
+     * what is necessary.
      */
     len = len * (d->arch.vgic.nr_regions + 1);
     new_cells = xzalloc_bytes(len);
@@ -1383,6 +1385,10 @@ static int gicv3_make_hwdom_madt(const struct domain *d, 
u32 offset)
 
     /* Add Generic Redistributor */
     size = sizeof(struct acpi_madt_generic_redistributor);
+    /*
+     * The hardware domain may not used all the regions. So only copy
+     * what is necessary.
+     */
     for ( i = 0; i < d->arch.vgic.nr_regions; i++ )
     {
         gicr = (struct acpi_madt_generic_redistributor *)(base_ptr + 
table_len);
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 4d4c3d1f49..257e7fd4f8 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -1448,7 +1448,11 @@ static int vgic_v3_vcpu_init(struct vcpu *v)
     return 0;
 }
 
-static inline unsigned int vgic_v3_rdist_count(struct domain *d)
+/*
+ * Return the maximum number possible of re-distributor regions for
+ * a given domain.
+ */
+static inline unsigned int vgic_v3_max_rdist_count(struct domain *d)
 {
     return is_hardware_domain(d) ? vgic_v3_hw.nr_rdist_regions :
                GUEST_GICV3_RDIST_REGIONS;
@@ -1460,7 +1464,7 @@ static int vgic_v3_real_domain_init(struct domain *d)
     int rdist_count, i, ret;
 
     /* Allocate memory for Re-distributor regions */
-    rdist_count = vgic_v3_rdist_count(d);
+    rdist_count = vgic_v3_max_rdist_count(d);
 
     rdist_regions = xzalloc_array(struct vgic_rdist_region, rdist_count);
     if ( !rdist_regions )
@@ -1499,7 +1503,18 @@ static int vgic_v3_real_domain_init(struct domain *d)
             d->arch.vgic.rdist_regions[i].first_cpu = first_cpu;
 
             first_cpu += size / d->arch.vgic.rdist_stride;
+
+            if ( first_cpu >= d->max_vcpus )
+                break;
         }
+
+        /*
+         * The hardware domain may not use all the re-distributors
+         * regions (e.g when the number of vCPUs does not match the
+         * number of pCPUs). Update the number of regions to avoid
+         * exposing unused region as they will not get emulated.
+         */
+        d->arch.vgic.nr_regions = i + 1;
     }
     else
     {
@@ -1582,7 +1597,7 @@ int vgic_v3_init(struct domain *d, int *mmio_count)
     }
 
     /* GICD region + number of Redistributors */
-    *mmio_count = vgic_v3_rdist_count(d) + 1;
+    *mmio_count = vgic_v3_max_rdist_count(d) + 1;
 
     register_vgic_ops(d, &v3_ops);
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.9

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.