#ifdef CONFIG_OF
 static int gic_cnt __initdata;
+static bool gicv2_force_probe;
+
+static int __init gicv2_force_probe_cfg(char *buf)
+{
+       return strtobool(buf, &gicv2_force_probe);
+}
+early_param("irqchip.gicv2_force_probe", gicv2_force_probe_cfg);
+
+static bool gic_check_gicv2(void __iomem *base)
+{
+       u32 val = readl_relaxed(base + GIC_CPU_IDENT);
+       return (val & 0xff0fff) == 0x02043B;
+}
 
 static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
 {
 
        if (!is_hyp_mode_available())
                return false;
-       if (resource_size(&cpuif_res) < SZ_8K)
-               return false;
-       if (resource_size(&cpuif_res) == SZ_128K) {
-               u32 val_low, val_high;
+       if (resource_size(&cpuif_res) < SZ_8K) {
+               void __iomem *alt;
+               /*
+                * Check for a stupid firmware that only exposes the
+                * first page of a GICv2.
+                */
+               if (!gic_check_gicv2(*base))
+                       return false;
 
+               if (!gicv2_force_probe) {
+                       pr_warn("GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set\n");
+                       return false;
+               }
+
+               alt = ioremap(cpuif_res.start, SZ_8K);
+               if (!alt)
+                       return false;
+               if (!gic_check_gicv2(alt + SZ_4K)) {
+                       /*
+                        * The first page was that of a GICv2, and
+                        * the second was *something*. Let's trust it
+                        * to be a GICv2, and update the mapping.
+                        */
+                       pr_warn("GIC: GICv2 at %pa, but range is too small (broken DT?), assuming 8kB\n",
+                               &cpuif_res.start);
+                       iounmap(*base);
+                       *base = alt;
+                       return true;
+               }
+
+               /*
+                * We detected *two* initial GICv2 pages in a
+                * row. Could be a GICv2 aliased over two 64kB
+                * pages. Update the resource, map the iospace, and
+                * pray.
+                */
+               iounmap(alt);
+               alt = ioremap(cpuif_res.start, SZ_128K);
+               if (!alt)
+                       return false;
+               pr_warn("GIC: Aliased GICv2 at %pa, trying to find the canonical range over 128kB\n",
+                       &cpuif_res.start);
+               cpuif_res.end = cpuif_res.start + SZ_128K -1;
+               iounmap(*base);
+               *base = alt;
+       }
+       if (resource_size(&cpuif_res) == SZ_128K) {
                /*
-                * Verify that we have the first 4kB of a GIC400
+                * Verify that we have the first 4kB of a GICv2
                 * aliased over the first 64kB by checking the
                 * GICC_IIDR register on both ends.
                 */
-               val_low = readl_relaxed(*base + GIC_CPU_IDENT);
-               val_high = readl_relaxed(*base + GIC_CPU_IDENT + 0xf000);
-               if ((val_low & 0xffff0fff) != 0x0202043B ||
-                   val_low != val_high)
+               if (!gic_check_gicv2(*base) ||
+                   !gic_check_gicv2(*base + 0xf000))
                        return false;
 
                /*