]> git.baikalelectronics.ru Git - kernel.git/commitdiff
irqchip/gic-v3: Detect GICv4.1 supporting RVPEID
authorMarc Zyngier <maz@kernel.org>
Tue, 24 Dec 2019 11:10:24 +0000 (11:10 +0000)
committerMarc Zyngier <maz@kernel.org>
Wed, 22 Jan 2020 14:22:19 +0000 (14:22 +0000)
GICv4.1 supports the RVPEID ("Residency per vPE ID"), which allows for
a much efficient way of making virtual CPUs resident (to allow direct
injection of interrupts).

The functionnality needs to be discovered on each and every redistributor
in the system, and disabled if the settings are inconsistent.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
Link: https://lore.kernel.org/r/20191224111055.11836-2-maz@kernel.org
drivers/irqchip/irq-gic-v3.c
include/linux/irqchip/arm-gic-v3.h

index d6218012097b42901e2d727c2b4ca207574cff1c..ffcb018395edb2c8ea136241d3740c42940b98f7 100644 (file)
@@ -858,8 +858,21 @@ static int __gic_update_rdist_properties(struct redist_region *region,
                                         void __iomem *ptr)
 {
        u64 typer = gic_read_typer(ptr + GICR_TYPER);
+
        gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
-       gic_data.rdists.has_direct_lpi &= !!(typer & GICR_TYPER_DirectLPIS);
+
+       /* RVPEID implies some form of DirectLPI, no matter what the doc says... :-/ */
+       gic_data.rdists.has_rvpeid &= !!(typer & GICR_TYPER_RVPEID);
+       gic_data.rdists.has_direct_lpi &= (!!(typer & GICR_TYPER_DirectLPIS) |
+                                          gic_data.rdists.has_rvpeid);
+
+       /* Detect non-sensical configurations */
+       if (WARN_ON_ONCE(gic_data.rdists.has_rvpeid && !gic_data.rdists.has_vlpis)) {
+               gic_data.rdists.has_direct_lpi = false;
+               gic_data.rdists.has_vlpis = false;
+               gic_data.rdists.has_rvpeid = false;
+       }
+
        gic_data.ppi_nr = min(GICR_TYPER_NR_PPIS(typer), gic_data.ppi_nr);
 
        return 1;
@@ -872,9 +885,10 @@ static void gic_update_rdist_properties(void)
        if (WARN_ON(gic_data.ppi_nr == UINT_MAX))
                gic_data.ppi_nr = 0;
        pr_info("%d PPIs implemented\n", gic_data.ppi_nr);
-       pr_info("%sVLPI support, %sdirect LPI support\n",
+       pr_info("%sVLPI support, %sdirect LPI support, %sRVPEID support\n",
                !gic_data.rdists.has_vlpis ? "no " : "",
-               !gic_data.rdists.has_direct_lpi ? "no " : "");
+               !gic_data.rdists.has_direct_lpi ? "no " : "",
+               !gic_data.rdists.has_rvpeid ? "no " : "");
 }
 
 /* Check whether it's single security state view */
@@ -1566,6 +1580,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
                                                 &gic_data);
        irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
        gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+       gic_data.rdists.has_rvpeid = true;
        gic_data.rdists.has_vlpis = true;
        gic_data.rdists.has_direct_lpi = true;
 
index de991d6633a5f99e929ca191506c87855a165e13..9a5f85d3070157646d1ce4858b0f5b6d6b24df48 100644 (file)
 #define GICR_TYPER_VLPIS               (1U << 1)
 #define GICR_TYPER_DirectLPIS          (1U << 3)
 #define GICR_TYPER_LAST                        (1U << 4)
+#define GICR_TYPER_RVPEID              (1U << 7)
 
 #define GIC_V3_REDIST_SIZE             0x20000
 
@@ -615,6 +616,7 @@ struct rdists {
        u64                     flags;
        u32                     gicd_typer;
        bool                    has_vlpis;
+       bool                    has_rvpeid;
        bool                    has_direct_lpi;
 };