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

[Xen-devel] [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT



The size of the CPU interface will used in a follow-up patch to map the
region in Xen memory.

Based on GICv2 spec, the CPU interface should at least be 8KB, although
most of the platform we are supporting use incorrectly the GICv1 size
(i.e 4KB) in their DT. Only warn and update the size to avoid any
breakage on these platforms.

Furthermore, Xen is relying on the fact that the Virtual CPU interface
been at least 8KB. As in reality the Virtual CPU interface matches the CPU
interface, check that the 2 interfaces have the same size. Also only warn,
to avoid any breakage with buggy DT.

For GICv3, only allow GICv2 compatibility when the Virtual CPU interface
and CPU interface are 8KB.

Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
---
Cc: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx>

I haven't done any change in the gic-hip04 driver. I will let the
maintainers doing it if they feel it's necessary.

The check on the CPU interface size has not been modified because if we
really want to check the validity of it, we would have to check at least
SZ_4K, SZ_8K and SZ_128K. Although I'm not sure if there is other
possible values.

    Changes in v3:
        - Shorten the error messages
        - Typo

    Changes in v2:
        - Fix typoes in the commit message
        - Fix typoes in warning messages
        - Avoid to split string literally in the middle of the sentence, so
        grep still works.
        - csize should be checked against vsize and not vbase!
---
 xen/arch/arm/gic-v2.c | 32 ++++++++++++++++++++++++++++----
 xen/arch/arm/gic-v3.c | 21 ++++++++++++++++++---
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 5841e59..96c4b9b 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -617,14 +617,16 @@ static hw_irq_controller gicv2_guest_irq_type = {
 static int __init gicv2_init(void)
 {
     int res;
-    paddr_t hbase, dbase, cbase, vbase;
+    paddr_t hbase, dbase;
+    paddr_t cbase, csize;
+    paddr_t vbase, vsize;
     const struct dt_device_node *node = gicv2_info.node;
 
     res = dt_device_get_address(node, 0, &dbase, NULL);
     if ( res )
         panic("GICv2: Cannot find a valid address for the distributor");
 
-    res = dt_device_get_address(node, 1, &cbase, NULL);
+    res = dt_device_get_address(node, 1, &cbase, &csize);
     if ( res )
         panic("GICv2: Cannot find a valid address for the CPU");
 
@@ -632,7 +634,7 @@ static int __init gicv2_init(void)
     if ( res )
         panic("GICv2: Cannot find a valid address for the hypervisor");
 
-    res = dt_device_get_address(node, 3, &vbase, NULL);
+    res = dt_device_get_address(node, 3, &vbase, &vsize);
     if ( res )
         panic("GICv2: Cannot find a valid address for the virtual CPU");
 
@@ -641,7 +643,29 @@ static int __init gicv2_init(void)
         panic("GICv2: Cannot find the maintenance IRQ");
     gicv2_info.maintenance_irq = res;
 
-    /* TODO: Add check on distributor, cpu size */
+    /* TODO: Add check on distributor */
+
+    /*
+     * The GICv2 CPU interface should at least be 8KB. Although, most of the DT
+     * doesn't correctly set it and use the GICv1 CPU interface size (i.e 4KB).
+     * Warn and then fixup.
+     */
+    if ( csize < SZ_8K )
+    {
+        printk(XENLOG_WARNING "GICv2: WARNING: "
+               "The GICC size is wrong: %#"PRIx64" expected %#x\n",
+               csize, SZ_8K);
+        csize = SZ_8K;
+    }
+
+    /*
+     * Check if the CPU interface and virtual CPU interface have the
+     * same size.
+     */
+    if ( csize != vsize )
+        printk(XENLOG_WARNING "GICv2: WARNING: "
+               "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't 
match\n",
+               csize, vsize);
 
     printk("GICv2 initialization:\n"
               "        gic_dist_addr=%"PRIpaddr"\n"
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 957c6e0..0ee0886 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1143,22 +1143,37 @@ static void __init gicv3_init_v2(const struct 
dt_device_node *node,
                                  paddr_t dbase)
 {
     int res;
-    paddr_t cbase, vbase;
+    paddr_t cbase, csize;
+    paddr_t vbase, vsize;
 
     /*
      * For GICv3 supporting GICv2, GICC and GICV base address will be
      * provided.
      */
     res = dt_device_get_address(node, 1 + gicv3.rdist_count,
-                                &cbase, NULL);
+                                &cbase, &csize);
     if ( res )
         return;
 
     res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
-                                &vbase, NULL);
+                                &vbase, &vsize);
     if ( res )
         return;
 
+    /*
+     * Only allow support of GICv2 compatible when the CPU interface
+     * and virtual CPU interface are 8KB
+     * XXX: Handle other size?
+     */
+    if ( csize != SZ_8K && vsize != SZ_8K )
+    {
+        printk(XENLOG_WARNING
+               "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
+               "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") must both 
be 8KB.\n",
+               csize, vsize);
+        return;
+    }
+
     printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase 
%#"PRIpaddr"\n",
            cbase, vbase);
 
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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