]> xenbits.xensource.com Git - people/pauldu/xen.git/commitdiff
xen/arm: gic: Make sure the number of interrupt lines is valid before using it
authorJulien Grall <julien.grall@arm.com>
Fri, 30 Nov 2018 17:15:33 +0000 (17:15 +0000)
committerJulien Grall <julien.grall@arm.com>
Wed, 23 Jan 2019 13:40:02 +0000 (13:40 +0000)
GICv2 and GICv3 supports up to 1020 interrupts. However, the value computed
from GICD_TYPER.ITLinesNumber can be up to 1024. On GICv3, we will end up to
write in reserved registers that are right after the IROUTERs one as the
value is not capped early enough.

Cap the number of interrupts as soon as we compute it so we know we can
safely using it afterwards.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reported-by: Jan-Peter Larsson <Jan-Peter.Larsson@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Release-Acked-by: Juergen Gross <jgross@suse.com>
xen/arch/arm/gic-v2.c
xen/arch/arm/gic-v3.c

index 1a744c576fca8e70109fa234fd0d52b8544ff5b9..e9fb8a01aba2a4c839552ab63adde78c4287c7bd 100644 (file)
@@ -353,6 +353,10 @@ static void __init gicv2_dist_init(void)
 
     type = readl_gicd(GICD_TYPER);
     nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
+    /* Only 1020 interrupts are supported */
+    nr_lines = min(1020U, nr_lines);
+    gicv2_info.nr_lines = nr_lines;
+
     gic_cpus = 1 + ((type & GICD_TYPE_CPUS) >> 5);
     printk("GICv2: %d lines, %d cpu%s%s (IID %8.8x).\n",
            nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
@@ -377,9 +381,6 @@ static void __init gicv2_dist_init(void)
     for ( i = 32; i < nr_lines; i += 32 )
         writel_gicd(~0x0, GICD_ICENABLER + (i / 32) * 4);
 
-    /* Only 1020 interrupts are supported */
-    gicv2_info.nr_lines = min(1020U, nr_lines);
-
     /* Turn on the distributor */
     writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
 }
index 6fbc1067577b9269b3fbb3e12ff91f08874b93c2..c9200d24e18f79a740e9c271a91a9e38c7afc353 100644 (file)
@@ -607,6 +607,10 @@ static void __init gicv3_dist_init(void)
     if ( type & GICD_TYPE_LPIS )
         gicv3_lpi_init_host_lpis(GICD_TYPE_ID_BITS(type));
 
+    /* Only 1020 interrupts are supported */
+    nr_lines = min(1020U, nr_lines);
+    gicv3_info.nr_lines = nr_lines;
+
     printk("GICv3: %d lines, (IID %8.8x).\n",
            nr_lines, readl_relaxed(GICD + GICD_IIDR));
 
@@ -646,9 +650,6 @@ static void __init gicv3_dist_init(void)
 
     for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i++ )
         writeq_relaxed(affinity, GICD + GICD_IROUTER + i * 8);
-
-    /* Only 1020 interrupts are supported */
-    gicv3_info.nr_lines = min(1020U, nr_lines);
 }
 
 static int gicv3_enable_redist(void)