linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges
@ 2019-08-06 10:01 Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base Marc Zyngier
                   ` (11 more replies)
  0 siblings, 12 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Apparently, having ~1000 wired interrupts is not enough, and some
people need more. Fear not! The GIC Achitecture Department hereby
grants you another 1024 SPIs, together with 64 PPIs, provided that you
implement GICv3.1 (see [1] for the details)

This series implements the required support, which requires a bit of
infrastructure rework in order to make the thing less horrible...

This has been tested on a FastModel. If there is no additional issue being
reported, I plan to put this into -next toward the end of this week and
let it simmer there for a bit.

[1] https://developer.arm.com/docs/ihi0069/latest (version E)

* From v1:
  - Tighten ESPI range matching
  - Added a warning to detect inconsistent distributor/cpu interface
    configurations
  - Added quirks to handle HIP06/07 erratum 161010803 which unexpectedly
    advertise ESPI support

Marc Zyngier (12):
  irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
  irqchip/gic-v3: Add INTID range and convertion primitives
  dt-bindings: interrupt-controller: arm,gic-v3: Describe ESPI range
    support
  irqchip/gic-v3: Add ESPI range support
  irqchip/gic: Prepare for more than 16 PPIs
  irqchip/gic-v3: Dynamically allocate PPI NMI refcounts
  irqchip/gic-v3: Dynamically allocate PPI partition descriptors
  dt-bindings: interrupt-controller: arm,gic-v3: Describe EPPI range
    support
  irqchip/gic-v3: Add EPPI range support
  irqchip/gic-v3: Warn about inconsistent implementations of extended
    ranges
  irqchip/gic: Skip DT quirks when evaluating IIDR-based quirks
  irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum
    161010803

 Documentation/arm64/silicon-errata.rst        |   2 +
 .../interrupt-controller/arm,gic-v3.yaml      |   6 +-
 drivers/irqchip/irq-gic-common.c              |  35 +-
 drivers/irqchip/irq-gic-common.h              |   2 +-
 drivers/irqchip/irq-gic-v3.c                  | 380 ++++++++++++++----
 drivers/irqchip/irq-gic.c                     |  12 +-
 drivers/irqchip/irq-hip04.c                   |   9 +-
 include/linux/irqchip/arm-gic-v3.h            |  30 +-
 8 files changed, 372 insertions(+), 104 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-19 14:26   ` Zenghui Yu
  2019-08-06 10:01 ` [PATCH v2 02/12] irqchip/gic-v3: Add INTID range and convertion primitives Marc Zyngier
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

gic_configure_irq is currently passed the (re)distributor address,
to which it applies an a fixed offset to get to the configuration
registers. This offset is constant across all GICs, or rather it was
until to v3.1...

An easy way out is for the individual drivers to pass the base
address of the configuration register for the considered interrupt.
At the same time, move part of the error handling back to the
individual drivers, as things are about to change on that front.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-common.c | 14 +++++---------
 drivers/irqchip/irq-gic-v3.c     | 11 ++++++++++-
 drivers/irqchip/irq-gic.c        | 10 +++++++++-
 drivers/irqchip/irq-hip04.c      |  7 ++++++-
 4 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index b0a8215a13fc..6900b6f0921c 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -63,7 +63,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
 	 * for "irq", depending on "type".
 	 */
 	raw_spin_lock_irqsave(&irq_controller_lock, flags);
-	val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+	val = oldval = readl_relaxed(base + confoff);
 	if (type & IRQ_TYPE_LEVEL_MASK)
 		val &= ~confmask;
 	else if (type & IRQ_TYPE_EDGE_BOTH)
@@ -83,14 +83,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
 	 * does not allow us to set the configuration or we are in a
 	 * non-secure mode, and hence it may not be catastrophic.
 	 */
-	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
-	if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
-		if (WARN_ON(irq >= 32))
-			ret = -EINVAL;
-		else
-			pr_warn("GIC: PPI%d is secure or misconfigured\n",
-				irq - 16);
-	}
+	writel_relaxed(val, base + confoff);
+	if (readl_relaxed(base + confoff) != val)
+		ret = -EINVAL;
+
 	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 
 	if (sync_access)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 96d927f0f91a..b250e69908f8 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -407,6 +407,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	unsigned int irq = gic_irq(d);
 	void (*rwp_wait)(void);
 	void __iomem *base;
+	int ret;
 
 	/* Interrupt configuration for SGIs can't be changed */
 	if (irq < 16)
@@ -425,7 +426,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 		rwp_wait = gic_dist_wait_for_rwp;
 	}
 
-	return gic_configure_irq(irq, type, base, rwp_wait);
+
+	ret = gic_configure_irq(irq, type, base + GICD_ICFGR, rwp_wait);
+	if (ret && irq < 32) {
+		/* Misconfigured PPIs are usually not fatal */
+		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
+		ret = 0;
+	}
+
+	return ret;
 }
 
 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index e45f45e68720..ab48760acabb 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -291,6 +291,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 {
 	void __iomem *base = gic_dist_base(d);
 	unsigned int gicirq = gic_irq(d);
+	int ret;
 
 	/* Interrupt configuration for SGIs can't be changed */
 	if (gicirq < 16)
@@ -301,7 +302,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 			    type != IRQ_TYPE_EDGE_RISING)
 		return -EINVAL;
 
-	return gic_configure_irq(gicirq, type, base, NULL);
+	ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
+	if (ret && gicirq < 32) {
+		/* Misconfigured PPIs are usually not fatal */
+		pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
+		ret = 0;
+	}
+
+	return ret;
 }
 
 static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index cf705827599c..1626131834a6 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -130,7 +130,12 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
 
 	raw_spin_lock(&irq_controller_lock);
 
-	ret = gic_configure_irq(irq, type, base, NULL);
+	ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL);
+	if (ret && irq < 32) {
+		/* Misconfigured PPIs are usually not fatal */
+		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
+		ret = 0;
+	}
 
 	raw_spin_unlock(&irq_controller_lock);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 02/12] irqchip/gic-v3: Add INTID range and convertion primitives
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 03/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe ESPI range support Marc Zyngier
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

In the beginning, life was simple. The GIC driver mostly cared about
PPIs, SPIs and LPIs, all with nicely layed out ranges.

We're about to change all that, with new ranges such as EPPI and ESPI
interleaved in the middle of the no-irq-land between the "special IDs"
and the LPI range. Boo.

In order to make our life less hellish, let's introduce a set of primitives
that will allow ranges to be identified easily and offsets to be remapped.

So far, there is no functionnal change.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c | 112 ++++++++++++++++++++++++++---------
 1 file changed, 83 insertions(+), 29 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index b250e69908f8..db3bdedd7241 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -97,6 +97,32 @@ static DEFINE_PER_CPU(bool, has_rss);
 /* Our default, arbitrary priority value. Linux only uses one anyway. */
 #define DEFAULT_PMR_VALUE	0xf0
 
+enum gic_intid_range {
+	PPI_RANGE,
+	SPI_RANGE,
+	LPI_RANGE,
+	__INVALID_RANGE__
+};
+
+static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq)
+{
+	switch (hwirq) {
+	case 16 ... 31:
+		return PPI_RANGE;
+	case 32 ... 1019:
+		return SPI_RANGE;
+	case 8192 ... GENMASK(23, 0):
+		return LPI_RANGE;
+	default:
+		return __INVALID_RANGE__;
+	}
+}
+
+static enum gic_intid_range get_intid_range(struct irq_data *d)
+{
+	return __get_intid_range(d->hwirq);
+}
+
 static inline unsigned int gic_irq(struct irq_data *d)
 {
 	return d->hwirq;
@@ -104,18 +130,23 @@ static inline unsigned int gic_irq(struct irq_data *d)
 
 static inline int gic_irq_in_rdist(struct irq_data *d)
 {
-	return gic_irq(d) < 32;
+	return get_intid_range(d) == PPI_RANGE;
 }
 
 static inline void __iomem *gic_dist_base(struct irq_data *d)
 {
-	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
+	switch (get_intid_range(d)) {
+	case PPI_RANGE:
+		/* SGI+PPI -> SGI_base for this CPU */
 		return gic_data_rdist_sgi_base();
 
-	if (d->hwirq <= 1023)		/* SPI -> dist_base */
+	case SPI_RANGE:
+		/* SPI -> dist_base */
 		return gic_data.dist_base;
 
-	return NULL;
+	default:
+		return NULL;
+	}
 }
 
 static void gic_do_wait_for_rwp(void __iomem *base)
@@ -196,24 +227,46 @@ static void gic_enable_redist(bool enable)
 /*
  * Routines to disable, enable, EOI and route interrupts
  */
+static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index)
+{
+	switch (get_intid_range(d)) {
+	case PPI_RANGE:
+	case SPI_RANGE:
+		*index = d->hwirq;
+		return offset;
+	default:
+		break;
+	}
+
+	WARN_ON(1);
+	*index = d->hwirq;
+	return offset;
+}
+
 static int gic_peek_irq(struct irq_data *d, u32 offset)
 {
-	u32 mask = 1 << (gic_irq(d) % 32);
 	void __iomem *base;
+	u32 index, mask;
+
+	offset = convert_offset_index(d, offset, &index);
+	mask = 1 << (index % 32);
 
 	if (gic_irq_in_rdist(d))
 		base = gic_data_rdist_sgi_base();
 	else
 		base = gic_data.dist_base;
 
-	return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask);
+	return !!(readl_relaxed(base + offset + (index / 32) * 4) & mask);
 }
 
 static void gic_poke_irq(struct irq_data *d, u32 offset)
 {
-	u32 mask = 1 << (gic_irq(d) % 32);
 	void (*rwp_wait)(void);
 	void __iomem *base;
+	u32 index, mask;
+
+	offset = convert_offset_index(d, offset, &index);
+	mask = 1 << (index % 32);
 
 	if (gic_irq_in_rdist(d)) {
 		base = gic_data_rdist_sgi_base();
@@ -223,7 +276,7 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
 		rwp_wait = gic_dist_wait_for_rwp;
 	}
 
-	writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4);
+	writel_relaxed(mask, base + offset + (index / 32) * 4);
 	rwp_wait();
 }
 
@@ -316,8 +369,11 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
 static void gic_irq_set_prio(struct irq_data *d, u8 prio)
 {
 	void __iomem *base = gic_dist_base(d);
+	u32 offset, index;
 
-	writeb_relaxed(prio, base + GICD_IPRIORITYR + gic_irq(d));
+	offset = convert_offset_index(d, GICD_IPRIORITYR, &index);
+
+	writeb_relaxed(prio, base + offset + index);
 }
 
 static int gic_irq_nmi_setup(struct irq_data *d)
@@ -407,6 +463,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	unsigned int irq = gic_irq(d);
 	void (*rwp_wait)(void);
 	void __iomem *base;
+	u32 offset, index;
 	int ret;
 
 	/* Interrupt configuration for SGIs can't be changed */
@@ -426,8 +483,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 		rwp_wait = gic_dist_wait_for_rwp;
 	}
 
+	offset = convert_offset_index(d, GICD_ICFGR, &index);
 
-	ret = gic_configure_irq(irq, type, base + GICD_ICFGR, rwp_wait);
+	ret = gic_configure_irq(index, type, base + offset, rwp_wait);
 	if (ret && irq < 32) {
 		/* Misconfigured PPIs are usually not fatal */
 		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
@@ -970,6 +1028,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
 	unsigned int cpu;
+	u32 offset, index;
 	void __iomem *reg;
 	int enabled;
 	u64 val;
@@ -990,7 +1049,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 	if (enabled)
 		gic_mask_irq(d);
 
-	reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8);
+	offset = convert_offset_index(d, GICD_IROUTER, &index);
+	reg = gic_dist_base(d) + offset + (index * 8);
 	val = gic_mpidr_to_affinity(cpu_logical_map(cpu));
 
 	gic_write_irouter(val, reg);
@@ -1084,36 +1144,30 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 	if (static_branch_likely(&supports_deactivate_key))
 		chip = &gic_eoimode1_chip;
 
-	/* SGIs are private to the core kernel */
-	if (hw < 16)
-		return -EPERM;
-	/* Nothing here */
-	if (hw >= gic_data.irq_nr && hw < 8192)
-		return -EPERM;
-	/* Off limits */
-	if (hw >= GIC_ID_NR)
-		return -EPERM;
-
-	/* PPIs */
-	if (hw < 32) {
+	switch (__get_intid_range(hw)) {
+	case PPI_RANGE:
 		irq_set_percpu_devid(irq);
 		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
 		irq_set_status_flags(irq, IRQ_NOAUTOEN);
-	}
-	/* SPIs */
-	if (hw >= 32 && hw < gic_data.irq_nr) {
+		break;
+
+	case SPI_RANGE:
 		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
 		irq_set_probe(irq);
 		irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
-	}
-	/* LPIs */
-	if (hw >= 8192 && hw < GIC_ID_NR) {
+		break;
+
+	case LPI_RANGE:
 		if (!gic_dist_supports_lpis())
 			return -EPERM;
 		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
+		break;
+
+	default:
+		return -EPERM;
 	}
 
 	return 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 03/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe ESPI range support
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 02/12] irqchip/gic-v3: Add INTID range and convertion primitives Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 04/12] irqchip/gic-v3: Add " Marc Zyngier
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

GICv3.1 introduces support for new interrupt ranges, one of them being
the Extended SPI range (ESPI). The DT binding is extended to deal with
it as a new interrupt class.

Reviewed-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 .../devicetree/bindings/interrupt-controller/arm,gic-v3.yaml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
index c34df35a25fc..98a3ecda8e07 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
@@ -44,11 +44,12 @@ properties:
       be at least 4.
 
       The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
-      interrupts. Other values are reserved for future use.
+      interrupts, 2 for interrupts in the Extended SPI range. Other values
+      are reserved for future use.
 
       The 2nd cell contains the interrupt number for the interrupt type.
       SPI interrupts are in the range [0-987]. PPI interrupts are in the
-      range [0-15].
+      range [0-15]. Extented SPI interrupts are in the range [0-1023].
 
       The 3rd cell is the flags, encoded as follows:
       bits[3:0] trigger type and level flags.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 04/12] irqchip/gic-v3: Add ESPI range support
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (2 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 03/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe ESPI range support Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-19 14:25   ` Zenghui Yu
  2019-08-06 10:01 ` [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs Marc Zyngier
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Add the required support for the ESPI range, which behave exactly like
the SPIs of old, only with new funky INTIDs.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c       | 85 ++++++++++++++++++++++++------
 include/linux/irqchip/arm-gic-v3.h | 17 +++++-
 2 files changed, 85 insertions(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index db3bdedd7241..1ca4dde32034 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -51,13 +51,16 @@ struct gic_chip_data {
 	u32			nr_redist_regions;
 	u64			flags;
 	bool			has_rss;
-	unsigned int		irq_nr;
 	struct partition_desc	*ppi_descs[16];
 };
 
 static struct gic_chip_data gic_data __read_mostly;
 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
 
+#define GIC_ID_NR	(1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
+#define GIC_LINE_NR	GICD_TYPER_SPIS(gic_data.rdists.gicd_typer)
+#define GIC_ESPI_NR	GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
+
 /*
  * The behaviours of RPR and PMR registers differ depending on the value of
  * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
@@ -100,6 +103,7 @@ static DEFINE_PER_CPU(bool, has_rss);
 enum gic_intid_range {
 	PPI_RANGE,
 	SPI_RANGE,
+	ESPI_RANGE,
 	LPI_RANGE,
 	__INVALID_RANGE__
 };
@@ -111,6 +115,8 @@ static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq)
 		return PPI_RANGE;
 	case 32 ... 1019:
 		return SPI_RANGE;
+	case ESPI_BASE_INTID ... (ESPI_BASE_INTID + 1023):
+		return ESPI_RANGE;
 	case 8192 ... GENMASK(23, 0):
 		return LPI_RANGE;
 	default:
@@ -141,6 +147,7 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
 		return gic_data_rdist_sgi_base();
 
 	case SPI_RANGE:
+	case ESPI_RANGE:
 		/* SPI -> dist_base */
 		return gic_data.dist_base;
 
@@ -234,6 +241,31 @@ static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index)
 	case SPI_RANGE:
 		*index = d->hwirq;
 		return offset;
+	case ESPI_RANGE:
+		*index = d->hwirq - ESPI_BASE_INTID;
+		switch (offset) {
+		case GICD_ISENABLER:
+			return GICD_ISENABLERnE;
+		case GICD_ICENABLER:
+			return GICD_ICENABLERnE;
+		case GICD_ISPENDR:
+			return GICD_ISPENDRnE;
+		case GICD_ICPENDR:
+			return GICD_ICPENDRnE;
+		case GICD_ISACTIVER:
+			return GICD_ISACTIVERnE;
+		case GICD_ICACTIVER:
+			return GICD_ICACTIVERnE;
+		case GICD_IPRIORITYR:
+			return GICD_IPRIORITYRnE;
+		case GICD_ICFGR:
+			return GICD_ICFGRnE;
+		case GICD_IROUTER:
+			return GICD_IROUTERnE;
+		default:
+			break;
+		}
+		break;
 	default:
 		break;
 	}
@@ -316,7 +348,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d,
 {
 	u32 reg;
 
-	if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
+	if (d->hwirq >= 8192) /* PPI/SPI only */
 		return -EINVAL;
 
 	switch (which) {
@@ -343,7 +375,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d,
 static int gic_irq_get_irqchip_state(struct irq_data *d,
 				     enum irqchip_irq_state which, bool *val)
 {
-	if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */
+	if (d->hwirq >= 8192) /* PPI/SPI only */
 		return -EINVAL;
 
 	switch (which) {
@@ -567,7 +599,12 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 		gic_arch_enable_irqs();
 	}
 
-	if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
+	/* Check for special IDs first */
+	if ((irqnr >= 1020 && irqnr <= 1023))
+		return;
+
+	/* Treat anything but SGIs in a uniform way */
+	if (likely(irqnr > 15)) {
 		int err;
 
 		if (static_branch_likely(&supports_deactivate_key))
@@ -655,10 +692,26 @@ static void __init gic_dist_init(void)
 	 * do the right thing if the kernel is running in secure mode,
 	 * but that's not the intended use case anyway.
 	 */
-	for (i = 32; i < gic_data.irq_nr; i += 32)
+	for (i = 32; i < GIC_LINE_NR; i += 32)
 		writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
 
-	gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
+	/* Extended SPI range, not handled by the GICv2/GICv3 common code */
+	for (i = 0; i < GIC_ESPI_NR; i += 32) {
+		writel_relaxed(~0U, base + GICD_ICENABLERnE + i / 8);
+		writel_relaxed(~0U, base + GICD_ICACTIVERnE + i / 8);
+	}
+
+	for (i = 0; i < GIC_ESPI_NR; i += 32)
+		writel_relaxed(~0U, base + GICD_IGROUPRnE + i / 8);
+
+	for (i = 0; i < GIC_ESPI_NR; i += 16)
+		writel_relaxed(0, base + GICD_ICFGRnE + i / 4);
+
+	for (i = 0; i < GIC_ESPI_NR; i += 4)
+		writel_relaxed(GICD_INT_DEF_PRI_X4, base + GICD_IPRIORITYRnE + i);
+
+	/* Now do the common stuff, and wait for the distributor to drain */
+	gic_dist_config(base, GIC_LINE_NR, gic_dist_wait_for_rwp);
 
 	/* Enable distributor with ARE, Group1 */
 	writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
@@ -669,8 +722,11 @@ static void __init gic_dist_init(void)
 	 * enabled.
 	 */
 	affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id()));
-	for (i = 32; i < gic_data.irq_nr; i++)
+	for (i = 32; i < GIC_LINE_NR; i++)
 		gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
+
+	for (i = 0; i < GIC_ESPI_NR; i++)
+		gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8);
 }
 
 static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *))
@@ -1134,8 +1190,6 @@ static struct irq_chip gic_eoimode1_chip = {
 				  IRQCHIP_MASK_ON_SUSPEND,
 };
 
-#define GIC_ID_NR	(1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
-
 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
@@ -1153,6 +1207,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 		break;
 
 	case SPI_RANGE:
+	case ESPI_RANGE:
 		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
 		irq_set_probe(irq);
@@ -1192,6 +1247,9 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 		case GIC_IRQ_TYPE_PARTITION:
 			*hwirq = fwspec->param[1] + 16;
 			break;
+		case 2:			/* ESPI */
+			*hwirq = fwspec->param[1] + ESPI_BASE_INTID;
+			break;
 		case GIC_IRQ_TYPE_LPI:	/* LPI */
 			*hwirq = fwspec->param[1];
 			break;
@@ -1346,7 +1404,6 @@ static int __init gic_init_bases(void __iomem *dist_base,
 				 struct fwnode_handle *handle)
 {
 	u32 typer;
-	int gic_irqs;
 	int err;
 
 	if (!is_hyp_mode_available())
@@ -1363,15 +1420,11 @@ static int __init gic_init_bases(void __iomem *dist_base,
 
 	/*
 	 * Find out how many interrupts are supported.
-	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
 	 */
 	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
 	gic_data.rdists.gicd_typer = typer;
-	gic_irqs = GICD_TYPER_IRQS(typer);
-	if (gic_irqs > 1020)
-		gic_irqs = 1020;
-	gic_data.irq_nr = gic_irqs;
-
+	pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
+	pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
 	gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
 						 &gic_data);
 	irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 67c4b9806d43..c523bf1faa55 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -30,10 +30,22 @@
 #define GICD_ICFGR			0x0C00
 #define GICD_IGRPMODR			0x0D00
 #define GICD_NSACR			0x0E00
+#define GICD_IGROUPRnE			0x1000
+#define GICD_ISENABLERnE		0x1200
+#define GICD_ICENABLERnE		0x1400
+#define GICD_ISPENDRnE			0x1600
+#define GICD_ICPENDRnE			0x1800
+#define GICD_ISACTIVERnE		0x1A00
+#define GICD_ICACTIVERnE		0x1C00
+#define GICD_IPRIORITYRnE		0x2000
+#define GICD_ICFGRnE			0x3000
 #define GICD_IROUTER			0x6000
+#define GICD_IROUTERnE			0x8000
 #define GICD_IDREGS			0xFFD0
 #define GICD_PIDR2			0xFFE8
 
+#define ESPI_BASE_INTID			4096
+
 /*
  * Those registers are actually from GICv2, but the spec demands that they
  * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3).
@@ -69,10 +81,13 @@
 #define GICD_TYPER_RSS			(1U << 26)
 #define GICD_TYPER_LPIS			(1U << 17)
 #define GICD_TYPER_MBIS			(1U << 16)
+#define GICD_TYPER_ESPI			(1U << 8)
 
 #define GICD_TYPER_ID_BITS(typer)	((((typer) >> 19) & 0x1f) + 1)
 #define GICD_TYPER_NUM_LPIS(typer)	((((typer) >> 11) & 0x1f) + 1)
-#define GICD_TYPER_IRQS(typer)		((((typer) & 0x1f) + 1) * 32)
+#define GICD_TYPER_SPIS(typer)		((((typer) & 0x1f) + 1) * 32)
+#define GICD_TYPER_ESPIS(typer)						\
+	(((typer) & GICD_TYPER_ESPI) ? GICD_TYPER_SPIS((typer) >> 27) : 0)
 
 #define GICD_IROUTER_SPI_MODE_ONE	(0U << 31)
 #define GICD_IROUTER_SPI_MODE_ANY	(1U << 31)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (3 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 04/12] irqchip/gic-v3: Add " Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-21 18:40   ` Zenghui Yu
  2019-08-22 16:11   ` Julien
  2019-08-06 10:01 ` [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts Marc Zyngier
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

GICv3.1 allows up to 80 PPIs (16 legaci PPIs and 64 Extended PPIs),
meaning we can't just leave the old 16 hardcoded everywhere.

We also need to add the infrastructure to discover the number of PPIs
on a per redistributor basis, although we still pretend there is only
16 of them for now.

No functional change.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-common.c | 19 ++++++++++++-------
 drivers/irqchip/irq-gic-common.h |  2 +-
 drivers/irqchip/irq-gic-v3.c     | 22 +++++++++++++++-------
 drivers/irqchip/irq-gic.c        |  2 +-
 drivers/irqchip/irq-hip04.c      |  2 +-
 5 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 6900b6f0921c..14110db01c05 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -128,26 +128,31 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
 		sync_access();
 }
 
-void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
+void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
 {
 	int i;
 
 	/*
 	 * Deal with the banked PPI and SGI interrupts - disable all
-	 * PPI interrupts, ensure all SGI interrupts are enabled.
-	 * Make sure everything is deactivated.
+	 * private interrupts. Make sure everything is deactivated.
 	 */
-	writel_relaxed(GICD_INT_EN_CLR_X32, base + GIC_DIST_ACTIVE_CLEAR);
-	writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR);
-	writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
+	for (i = 0; i < nr; i += 32) {
+		writel_relaxed(GICD_INT_EN_CLR_X32,
+			       base + GIC_DIST_ACTIVE_CLEAR + i / 8);
+		writel_relaxed(GICD_INT_EN_CLR_X32,
+			       base + GIC_DIST_ENABLE_CLEAR + i / 8);
+	}
 
 	/*
 	 * Set priority on PPI and SGI interrupts
 	 */
-	for (i = 0; i < 32; i += 4)
+	for (i = 0; i < nr; i += 4)
 		writel_relaxed(GICD_INT_DEF_PRI_X4,
 					base + GIC_DIST_PRI + i * 4 / 4);
 
+	/* Ensure all SGI interrupts are now enabled */
+	writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
+
 	if (sync_access)
 		sync_access();
 }
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index 5a46b6b57750..ccba8b0fe0f5 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -22,7 +22,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
                        void __iomem *base, void (*sync_access)(void));
 void gic_dist_config(void __iomem *base, int gic_irqs,
 		     void (*sync_access)(void));
-void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void));
 void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
 		void *data);
 void gic_enable_of_quirks(const struct device_node *np,
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 1ca4dde32034..e03fb6d7c2ce 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -51,6 +51,7 @@ struct gic_chip_data {
 	u32			nr_redist_regions;
 	u64			flags;
 	bool			has_rss;
+	unsigned int		ppi_nr;
 	struct partition_desc	*ppi_descs[16];
 };
 
@@ -812,19 +813,24 @@ static int gic_populate_rdist(void)
 	return -ENODEV;
 }
 
-static int __gic_update_vlpi_properties(struct redist_region *region,
-					void __iomem *ptr)
+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);
+	gic_data.ppi_nr = 16;
 
 	return 1;
 }
 
-static void gic_update_vlpi_properties(void)
+static void gic_update_rdist_properties(void)
 {
-	gic_iterate_rdists(__gic_update_vlpi_properties);
+	gic_data.ppi_nr = UINT_MAX;
+	gic_iterate_rdists(__gic_update_rdist_properties);
+	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",
 		!gic_data.rdists.has_vlpis ? "no " : "",
 		!gic_data.rdists.has_direct_lpi ? "no " : "");
@@ -968,6 +974,7 @@ static int gic_dist_supports_lpis(void)
 static void gic_cpu_init(void)
 {
 	void __iomem *rbase;
+	int i;
 
 	/* Register ourselves with the rest of the world */
 	if (gic_populate_rdist())
@@ -978,9 +985,10 @@ static void gic_cpu_init(void)
 	rbase = gic_data_rdist_sgi_base();
 
 	/* Configure SGIs/PPIs as non-secure Group-1 */
-	writel_relaxed(~0, rbase + GICR_IGROUPR0);
+	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
+		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
 
-	gic_cpu_config(rbase, gic_redist_wait_for_rwp);
+	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
 
 	/* initialise system registers */
 	gic_cpu_sys_reg_init();
@@ -1449,7 +1457,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
 
 	set_handle_irq(gic_handle_irq);
 
-	gic_update_vlpi_properties();
+	gic_update_rdist_properties();
 
 	gic_smp_init();
 	gic_dist_init();
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index ab48760acabb..25c1ae69db30 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -543,7 +543,7 @@ static int gic_cpu_init(struct gic_chip_data *gic)
 				gic_cpu_map[i] &= ~cpu_mask;
 	}
 
-	gic_cpu_config(dist_base, NULL);
+	gic_cpu_config(dist_base, 32, NULL);
 
 	writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
 	gic_cpu_if_up(gic);
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 1626131834a6..130caa1c9d93 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -273,7 +273,7 @@ static void hip04_irq_cpu_init(struct hip04_irq_data *intc)
 		if (i != cpu)
 			hip04_cpu_map[i] &= ~cpu_mask;
 
-	gic_cpu_config(dist_base, NULL);
+	gic_cpu_config(dist_base, 32, NULL);
 
 	writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
 	writel_relaxed(1, base + GIC_CPU_CTRL);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (4 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-22 15:05   ` Julien
  2019-08-06 10:01 ` [PATCH v2 07/12] irqchip/gic-v3: Dynamically allocate PPI partition descriptors Marc Zyngier
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

As we're about to have a variable number of PPIs, let's make the
allocation of the NMI refcounts dynamic. Also apply some minor
cleanups (moving things around).

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c | 47 ++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e03fb6d7c2ce..4253c7f67c86 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -88,7 +88,7 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
 static DEFINE_STATIC_KEY_FALSE(supports_pseudo_nmis);
 
 /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
-static refcount_t ppi_nmi_refs[16];
+static refcount_t *ppi_nmi_refs;
 
 static struct gic_kvm_info gic_v3_kvm_info;
 static DEFINE_PER_CPU(bool, has_rss);
@@ -409,6 +409,16 @@ static void gic_irq_set_prio(struct irq_data *d, u8 prio)
 	writeb_relaxed(prio, base + offset + index);
 }
 
+static u32 gic_get_ppi_index(struct irq_data *d)
+{
+	switch (get_intid_range(d)) {
+	case PPI_RANGE:
+		return d->hwirq - 16;
+	default:
+		unreachable();
+	}
+}
+
 static int gic_irq_nmi_setup(struct irq_data *d)
 {
 	struct irq_desc *desc = irq_to_desc(d->irq);
@@ -429,10 +439,12 @@ static int gic_irq_nmi_setup(struct irq_data *d)
 		return -EINVAL;
 
 	/* desc lock should already be held */
-	if (gic_irq(d) < 32) {
+	if (gic_irq_in_rdist(d)) {
+		u32 idx = gic_get_ppi_index(d);
+
 		/* Setting up PPI as NMI, only switch handler for first NMI */
-		if (!refcount_inc_not_zero(&ppi_nmi_refs[gic_irq(d) - 16])) {
-			refcount_set(&ppi_nmi_refs[gic_irq(d) - 16], 1);
+		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
+			refcount_set(&ppi_nmi_refs[idx], 1);
 			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
 		}
 	} else {
@@ -464,9 +476,11 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
 		return;
 
 	/* desc lock should already be held */
-	if (gic_irq(d) < 32) {
+	if (gic_irq_in_rdist(d)) {
+		u32 idx = gic_get_ppi_index(d);
+
 		/* Tearing down NMI, only switch handler for last NMI */
-		if (refcount_dec_and_test(&ppi_nmi_refs[gic_irq(d) - 16]))
+		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
 			desc->handle_irq = handle_percpu_devid_irq;
 	} else {
 		desc->handle_irq = handle_fasteoi_irq;
@@ -1394,7 +1408,19 @@ static void gic_enable_nmi_support(void)
 {
 	int i;
 
-	for (i = 0; i < 16; i++)
+	if (!gic_prio_masking_enabled())
+		return;
+
+	if (gic_has_group0() && !gic_dist_security_disabled()) {
+		pr_warn("SCR_EL3.FIQ is cleared, cannot enable use of pseudo-NMIs\n");
+		return;
+	}
+
+	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
+	if (!ppi_nmi_refs)
+		return;
+
+	for (i = 0; i < gic_data.ppi_nr; i++)
 		refcount_set(&ppi_nmi_refs[i], 0);
 
 	static_branch_enable(&supports_pseudo_nmis);
@@ -1472,12 +1498,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
 			gicv2m_init(handle, gic_data.domain);
 	}
 
-	if (gic_prio_masking_enabled()) {
-		if (!gic_has_group0() || gic_dist_security_disabled())
-			gic_enable_nmi_support();
-		else
-			pr_warn("SCR_EL3.FIQ is cleared, cannot enable use of pseudo-NMIs\n");
-	}
+	gic_enable_nmi_support();
 
 	return 0;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 07/12] irqchip/gic-v3: Dynamically allocate PPI partition descriptors
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (5 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 08/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe EPPI range support Marc Zyngier
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Again, PPIs are becoming a variable set. Let's hack the PPI partition
code to make the top-level array dynamically allocated.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 4253c7f67c86..34f8a96bd747 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -52,7 +52,7 @@ struct gic_chip_data {
 	u64			flags;
 	bool			has_rss;
 	unsigned int		ppi_nr;
-	struct partition_desc	*ppi_descs[16];
+	struct partition_desc	**ppi_descs;
 };
 
 static struct gic_chip_data gic_data __read_mostly;
@@ -1354,7 +1354,8 @@ static int gic_irq_domain_select(struct irq_domain *d,
 	 * then we need to match the partition domain.
 	 */
 	if (fwspec->param_count >= 4 &&
-	    fwspec->param[0] == 1 && fwspec->param[3] != 0)
+	    fwspec->param[0] == 1 && fwspec->param[3] != 0 &&
+	    gic_data.ppi_descs)
 		return d == partition_get_domain(gic_data.ppi_descs[fwspec->param[1]]);
 
 	return d == gic_data.domain;
@@ -1375,6 +1376,9 @@ static int partition_domain_translate(struct irq_domain *d,
 	struct device_node *np;
 	int ret;
 
+	if (!gic_data.ppi_descs)
+		return -ENOMEM;
+
 	np = of_find_node_by_phandle(fwspec->param[3]);
 	if (WARN_ON(!np))
 		return -EINVAL;
@@ -1531,6 +1535,10 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
 	if (!parts_node)
 		return;
 
+	gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL);
+	if (!gic_data.ppi_descs)
+		return;
+
 	nr_parts = of_get_child_count(parts_node);
 
 	if (!nr_parts)
@@ -1582,7 +1590,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
 		part_idx++;
 	}
 
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < gic_data.ppi_nr; i++) {
 		unsigned int irq;
 		struct partition_desc *desc;
 		struct irq_fwspec ppi_fwspec = {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 08/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe EPPI range support
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (6 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 07/12] irqchip/gic-v3: Dynamically allocate PPI partition descriptors Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 09/12] irqchip/gic-v3: Add " Marc Zyngier
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Update the GICv3 binding to allow interrupts in the EPPI range.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 .../devicetree/bindings/interrupt-controller/arm,gic-v3.yaml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
index 98a3ecda8e07..1fe147daca4c 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
@@ -44,12 +44,13 @@ properties:
       be at least 4.
 
       The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
-      interrupts, 2 for interrupts in the Extended SPI range. Other values
-      are reserved for future use.
+      interrupts, 2 for interrupts in the Extended SPI range, 3 for the
+      Extended PPI range. Other values are reserved for future use.
 
       The 2nd cell contains the interrupt number for the interrupt type.
       SPI interrupts are in the range [0-987]. PPI interrupts are in the
       range [0-15]. Extented SPI interrupts are in the range [0-1023].
+      Extended PPI interrupts are in the range [0-127].
 
       The 3rd cell is the flags, encoded as follows:
       bits[3:0] trigger type and level flags.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 09/12] irqchip/gic-v3: Add EPPI range support
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (7 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 08/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe EPPI range support Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges Marc Zyngier
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Expand the pre-existing PPI support to be able to deal with the
Extended PPI range (EPPI). This includes obtaining the number of PPIs
from each individual redistributor, and compute the minimum set
(just in case someone builds something really clever...).

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c       | 42 +++++++++++++++++++++++++-----
 include/linux/irqchip/arm-gic-v3.h | 12 +++++++++
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 34f8a96bd747..f53e58d398ba 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -104,6 +104,7 @@ static DEFINE_PER_CPU(bool, has_rss);
 enum gic_intid_range {
 	PPI_RANGE,
 	SPI_RANGE,
+	EPPI_RANGE,
 	ESPI_RANGE,
 	LPI_RANGE,
 	__INVALID_RANGE__
@@ -116,6 +117,8 @@ static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq)
 		return PPI_RANGE;
 	case 32 ... 1019:
 		return SPI_RANGE;
+	case EPPI_BASE_INTID ... (EPPI_BASE_INTID + 63):
+		return EPPI_RANGE;
 	case ESPI_BASE_INTID ... (ESPI_BASE_INTID + 1023):
 		return ESPI_RANGE;
 	case 8192 ... GENMASK(23, 0):
@@ -137,13 +140,15 @@ static inline unsigned int gic_irq(struct irq_data *d)
 
 static inline int gic_irq_in_rdist(struct irq_data *d)
 {
-	return get_intid_range(d) == PPI_RANGE;
+	enum gic_intid_range range = get_intid_range(d);
+	return range == PPI_RANGE || range == EPPI_RANGE;
 }
 
 static inline void __iomem *gic_dist_base(struct irq_data *d)
 {
 	switch (get_intid_range(d)) {
 	case PPI_RANGE:
+	case EPPI_RANGE:
 		/* SGI+PPI -> SGI_base for this CPU */
 		return gic_data_rdist_sgi_base();
 
@@ -242,6 +247,14 @@ static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index)
 	case SPI_RANGE:
 		*index = d->hwirq;
 		return offset;
+	case EPPI_RANGE:
+		/*
+		 * Contrary to the ESPI range, the EPPI range is contiguous
+		 * to the PPI range in the registers, so let's adjust the
+		 * displacement accordingly. Consistency is overrated.
+		 */
+		*index = d->hwirq - EPPI_BASE_INTID + 32;
+		return offset;
 	case ESPI_RANGE:
 		*index = d->hwirq - ESPI_BASE_INTID;
 		switch (offset) {
@@ -414,6 +427,8 @@ static u32 gic_get_ppi_index(struct irq_data *d)
 	switch (get_intid_range(d)) {
 	case PPI_RANGE:
 		return d->hwirq - 16;
+	case EPPI_RANGE:
+		return d->hwirq - EPPI_BASE_INTID + 16;
 	default:
 		unreachable();
 	}
@@ -507,6 +522,7 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d)
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
 {
+	enum gic_intid_range range;
 	unsigned int irq = gic_irq(d);
 	void (*rwp_wait)(void);
 	void __iomem *base;
@@ -517,9 +533,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	if (irq < 16)
 		return -EINVAL;
 
+	range = get_intid_range(d);
+
 	/* SPIs have restrictions on the supported types */
-	if (irq >= 32 && type != IRQ_TYPE_LEVEL_HIGH &&
-			 type != IRQ_TYPE_EDGE_RISING)
+	if ((range == SPI_RANGE || range == ESPI_RANGE) &&
+	    type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
 		return -EINVAL;
 
 	if (gic_irq_in_rdist(d)) {
@@ -533,9 +551,9 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	offset = convert_offset_index(d, GICD_ICFGR, &index);
 
 	ret = gic_configure_irq(index, type, base + offset, rwp_wait);
-	if (ret && irq < 32) {
+	if (ret && (range == PPI_RANGE || range == EPPI_RANGE)) {
 		/* Misconfigured PPIs are usually not fatal */
-		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
+		pr_warn("GIC: PPI INTID%d is secure or misconfigured\n", irq);
 		ret = 0;
 	}
 
@@ -833,7 +851,7 @@ static int __gic_update_rdist_properties(struct redist_region *region,
 	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);
-	gic_data.ppi_nr = 16;
+	gic_data.ppi_nr = min(GICR_TYPER_NR_PPIS(typer), gic_data.ppi_nr);
 
 	return 1;
 }
@@ -1222,6 +1240,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 
 	switch (__get_intid_range(hw)) {
 	case PPI_RANGE:
+	case EPPI_RANGE:
 		irq_set_percpu_devid(irq);
 		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
@@ -1266,15 +1285,24 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 			*hwirq = fwspec->param[1] + 32;
 			break;
 		case 1:			/* PPI */
-		case GIC_IRQ_TYPE_PARTITION:
 			*hwirq = fwspec->param[1] + 16;
 			break;
 		case 2:			/* ESPI */
 			*hwirq = fwspec->param[1] + ESPI_BASE_INTID;
 			break;
+		case 3:			/* EPPI */
+			*hwirq = fwspec->param[1] + EPPI_BASE_INTID;
+			break;
 		case GIC_IRQ_TYPE_LPI:	/* LPI */
 			*hwirq = fwspec->param[1];
 			break;
+		case GIC_IRQ_TYPE_PARTITION:
+			*hwirq = fwspec->param[1];
+			if (fwspec->param[1] >= 16)
+				*hwirq += EPPI_BASE_INTID - 16;
+			else
+				*hwirq += 16;
+			break;
 		default:
 			return -EINVAL;
 		}
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index c523bf1faa55..9ec3349dee04 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -124,6 +124,18 @@
 
 #define GICR_TYPER_CPU_NUMBER(r)	(((r) >> 8) & 0xffff)
 
+#define EPPI_BASE_INTID			1056
+
+#define GICR_TYPER_NR_PPIS(r)						\
+	({								\
+		unsigned int __ppinum = ((r) >> 27) & 0x1f;		\
+		unsigned int __nr_ppis = 16;				\
+		if (__ppinum == 1 || __ppinum == 2)			\
+			__nr_ppis +=  __ppinum * 32;			\
+									\
+		__nr_ppis;						\
+	 })
+
 #define GICR_WAKER_ProcessorSleep	(1U << 1)
 #define GICR_WAKER_ChildrenAsleep	(1U << 2)
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (8 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 09/12] irqchip/gic-v3: Add " Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:15   ` Vladimir Murzin
  2019-08-06 10:01 ` [PATCH v2 11/12] irqchip/gic: Skip DT quirks when evaluating IIDR-based quirks Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803 Marc Zyngier
  11 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

As is it usual for the GIC, it isn't disallowed to put together a system
that is majorly inconsistent, with a distributor supporting the
extended ranges while some of the CPUs don't.

Kindly tell the user that things are sailing isn't going to be smooth.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-v3.c       | 5 +++++
 include/linux/irqchip/arm-gic-v3.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index f53e58d398ba..334a10d9dbfb 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1014,6 +1014,11 @@ static void gic_cpu_init(void)
 
 	gic_enable_redist(true);
 
+	WARN((gic_data.ppi_nr > 16 || GIC_ESPI_NR != 0) &&
+	     !(gic_read_ctlr() & ICC_CTLR_EL1_ExtRange),
+	     "Distributor has extended ranges, but CPU%d doesn't\n",
+	     smp_processor_id());
+
 	rbase = gic_data_rdist_sgi_base();
 
 	/* Configure SGIs/PPIs as non-secure Group-1 */
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 9ec3349dee04..5cc10cf7cb3e 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -496,6 +496,7 @@
 #define ICC_CTLR_EL1_A3V_SHIFT		15
 #define ICC_CTLR_EL1_A3V_MASK		(0x1 << ICC_CTLR_EL1_A3V_SHIFT)
 #define ICC_CTLR_EL1_RSS		(0x1 << 18)
+#define ICC_CTLR_EL1_ExtRange		(0x1 << 19)
 #define ICC_PMR_EL1_SHIFT		0
 #define ICC_PMR_EL1_MASK		(0xff << ICC_PMR_EL1_SHIFT)
 #define ICC_BPR0_EL1_SHIFT		0
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 11/12] irqchip/gic: Skip DT quirks when evaluating IIDR-based quirks
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (9 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 10:01 ` [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803 Marc Zyngier
  11 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

When evaluating potential quirks matched by reads of the IIDR
register, skip the quirk entries that use a "compatible"
property attached to them, as these are DT based.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-gic-common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 14110db01c05..82520006195d 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -41,6 +41,8 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
 		void *data)
 {
 	for (; quirks->desc; quirks++) {
+		if (quirks->compatible)
+			continue;
 		if (quirks->iidr != (quirks->mask & iidr))
 			continue;
 		if (quirks->init(data))
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803
  2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
                   ` (10 preceding siblings ...)
  2019-08-06 10:01 ` [PATCH v2 11/12] irqchip/gic: Skip DT quirks when evaluating IIDR-based quirks Marc Zyngier
@ 2019-08-06 10:01 ` Marc Zyngier
  2019-08-06 11:07   ` John Garry
  11 siblings, 1 reply; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 10:01 UTC (permalink / raw)
  To: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

It looks like the HIP06/07 SoCs have extra bits in their GICD_TYPER
registers, which confuse the GICv3.1 code (these systems appear to
expose ESPIs while they actually don't).

Detect these systems as early as possible and wipe the fields that
should be RES0 in the register.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 Documentation/arm64/silicon-errata.rst |  2 +
 drivers/irqchip/irq-gic-v3.c           | 54 +++++++++++++++++++++-----
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 3e57d09246e6..17ea3fecddaa 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -115,6 +115,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip0{6,7}       | #161010701      | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| Hisilicon      | Hip0{6,7}       | #161010803      | N/A                         |
++----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip07           | #161600802      | HISILICON_ERRATUM_161600802 |
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 334a10d9dbfb..bee141613b67 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1441,6 +1441,46 @@ static bool gic_enable_quirk_msm8996(void *data)
 	return true;
 }
 
+static bool gic_enable_quirk_hip06_07(void *data)
+{
+	struct gic_chip_data *d = data;
+
+	/*
+	 * HIP06 GICD_IIDR clashes with GIC-600 product number (despite
+	 * not being an actual ARM implementation). The saving grace is
+	 * that GIC-600 doesn't have ESPI, so nothing to do in that case.
+	 * HIP07 doesn't even have a proper IIDR, and still pretends to
+	 * have ESPI. In both cases, put them right.
+	 */
+	if (d->rdists.gicd_typer & GICD_TYPER_ESPI) {
+		/* Zero both ESPI and the RES0 field next to it... */
+		d->rdists.gicd_typer &= ~GENMASK(9, 8);
+		return true;
+	}
+
+	return false;
+}
+
+static const struct gic_quirk gic_quirks[] = {
+	{
+		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
+		.compatible = "qcom,msm8996-gic-v3",
+		.init	= gic_enable_quirk_msm8996,
+	},
+	{
+		.desc	= "GICv3: HIP06 erratum 161010803",
+		.iidr	= 0x0204043b,
+		.init	= gic_enable_quirk_hip06_07,
+	},
+	{
+		.desc	= "GICv3: HIP07 erratum 161010803",
+		.iidr	= 0x00000000,
+		.init	= gic_enable_quirk_hip06_07,
+	},
+	{
+	}
+};
+
 static void gic_enable_nmi_support(void)
 {
 	int i;
@@ -1494,6 +1534,10 @@ static int __init gic_init_bases(void __iomem *dist_base,
 	 */
 	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
 	gic_data.rdists.gicd_typer = typer;
+
+	gic_enable_quirks(readl_relaxed(gic_data.dist_base + GICD_IIDR),
+			  gic_quirks, &gic_data);
+
 	pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
 	pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
 	gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
@@ -1676,16 +1720,6 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
 	gic_set_kvm_info(&gic_v3_kvm_info);
 }
 
-static const struct gic_quirk gic_quirks[] = {
-	{
-		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
-		.compatible = "qcom,msm8996-gic-v3",
-		.init	= gic_enable_quirk_msm8996,
-	},
-	{
-	}
-};
-
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges
  2019-08-06 10:01 ` [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges Marc Zyngier
@ 2019-08-06 10:15   ` Vladimir Murzin
  2019-08-06 11:15     ` Marc Zyngier
  0 siblings, 1 reply; 24+ messages in thread
From: Vladimir Murzin @ 2019-08-06 10:15 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

Hi Marc,

On 8/6/19 11:01 AM, Marc Zyngier wrote:
> As is it usual for the GIC, it isn't disallowed to put together a system
> that is majorly inconsistent, with a distributor supporting the
> extended ranges while some of the CPUs don't.
> 
> Kindly tell the user that things are sailing isn't going to be smooth.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/irqchip/irq-gic-v3.c       | 5 +++++
>  include/linux/irqchip/arm-gic-v3.h | 1 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index f53e58d398ba..334a10d9dbfb 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -1014,6 +1014,11 @@ static void gic_cpu_init(void)
>  
>  	gic_enable_redist(true);
>  
> +	WARN((gic_data.ppi_nr > 16 || GIC_ESPI_NR != 0) &&
> +	     !(gic_read_ctlr() & ICC_CTLR_EL1_ExtRange),
> +	     "Distributor has extended ranges, but CPU%d doesn't\n",
> +	     smp_processor_id());
> +

Should such setup be tainted?

Cheers
Vladimir

>  	rbase = gic_data_rdist_sgi_base();
>  
>  	/* Configure SGIs/PPIs as non-secure Group-1 */
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 9ec3349dee04..5cc10cf7cb3e 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -496,6 +496,7 @@
>  #define ICC_CTLR_EL1_A3V_SHIFT		15
>  #define ICC_CTLR_EL1_A3V_MASK		(0x1 << ICC_CTLR_EL1_A3V_SHIFT)
>  #define ICC_CTLR_EL1_RSS		(0x1 << 18)
> +#define ICC_CTLR_EL1_ExtRange		(0x1 << 19)
>  #define ICC_PMR_EL1_SHIFT		0
>  #define ICC_PMR_EL1_MASK		(0xff << ICC_PMR_EL1_SHIFT)
>  #define ICC_BPR0_EL1_SHIFT		0
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803
  2019-08-06 10:01 ` [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803 Marc Zyngier
@ 2019-08-06 11:07   ` John Garry
  0 siblings, 0 replies; 24+ messages in thread
From: John Garry @ 2019-08-06 11:07 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: Shameerali Kolothum Thodi, Lokesh Vutla, linux-kernel, linux-arm-kernel

On 06/08/2019 11:01, Marc Zyngier wrote:
> It looks like the HIP06/07 SoCs have extra bits in their GICD_TYPER
> registers, which confuse the GICv3.1 code (these systems appear to
> expose ESPIs while they actually don't).
>
> Detect these systems as early as possible and wipe the fields that
> should be RES0 in the register.
>

thanks,

Tested-by: John Garry <john.garry@huawei.com>

> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  Documentation/arm64/silicon-errata.rst |  2 +
>  drivers/irqchip/irq-gic-v3.c           | 54 +++++++++++++++++++++-----
>  2 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 3e57d09246e6..17ea3fecddaa 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -115,6 +115,8 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | Hisilicon      | Hip0{6,7}       | #161010701      | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| Hisilicon      | Hip0{6,7}       | #161010803      | N/A                         |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | Hisilicon      | Hip07           | #161600802      | HISILICON_ERRATUM_161600802 |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 334a10d9dbfb..bee141613b67 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -1441,6 +1441,46 @@ static bool gic_enable_quirk_msm8996(void *data)
>  	return true;
>  }
>
> +static bool gic_enable_quirk_hip06_07(void *data)
> +{
> +	struct gic_chip_data *d = data;
> +
> +	/*
> +	 * HIP06 GICD_IIDR clashes with GIC-600 product number (despite
> +	 * not being an actual ARM implementation). The saving grace is
> +	 * that GIC-600 doesn't have ESPI, so nothing to do in that case.
> +	 * HIP07 doesn't even have a proper IIDR, and still pretends to
> +	 * have ESPI. In both cases, put them right.
> +	 */
> +	if (d->rdists.gicd_typer & GICD_TYPER_ESPI) {
> +		/* Zero both ESPI and the RES0 field next to it... */
> +		d->rdists.gicd_typer &= ~GENMASK(9, 8);
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +static const struct gic_quirk gic_quirks[] = {
> +	{
> +		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
> +		.compatible = "qcom,msm8996-gic-v3",
> +		.init	= gic_enable_quirk_msm8996,
> +	},
> +	{
> +		.desc	= "GICv3: HIP06 erratum 161010803",
> +		.iidr	= 0x0204043b,
> +		.init	= gic_enable_quirk_hip06_07,
> +	},
> +	{
> +		.desc	= "GICv3: HIP07 erratum 161010803",
> +		.iidr	= 0x00000000,
> +		.init	= gic_enable_quirk_hip06_07,
> +	},
> +	{
> +	}
> +};
> +
>  static void gic_enable_nmi_support(void)
>  {
>  	int i;
> @@ -1494,6 +1534,10 @@ static int __init gic_init_bases(void __iomem *dist_base,
>  	 */
>  	typer = readl_relaxed(gic_data.dist_base + GICD_TYPER);
>  	gic_data.rdists.gicd_typer = typer;
> +
> +	gic_enable_quirks(readl_relaxed(gic_data.dist_base + GICD_IIDR),
> +			  gic_quirks, &gic_data);
> +
>  	pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
>  	pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
>  	gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
> @@ -1676,16 +1720,6 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
>  	gic_set_kvm_info(&gic_v3_kvm_info);
>  }
>
> -static const struct gic_quirk gic_quirks[] = {
> -	{
> -		.desc	= "GICv3: Qualcomm MSM8996 broken firmware",
> -		.compatible = "qcom,msm8996-gic-v3",
> -		.init	= gic_enable_quirk_msm8996,
> -	},
> -	{
> -	}
> -};
> -
>  static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *dist_base;
>



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges
  2019-08-06 10:15   ` Vladimir Murzin
@ 2019-08-06 11:15     ` Marc Zyngier
  0 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-06 11:15 UTC (permalink / raw)
  To: Vladimir Murzin, Thomas Gleixner, Jason Cooper, Julien Thierry,
	Rob Herring
  Cc: Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

Hi Vladimir,

On 06/08/2019 11:15, Vladimir Murzin wrote:
> Hi Marc,
> 
> On 8/6/19 11:01 AM, Marc Zyngier wrote:
>> As is it usual for the GIC, it isn't disallowed to put together a system
>> that is majorly inconsistent, with a distributor supporting the
>> extended ranges while some of the CPUs don't.
>>
>> Kindly tell the user that things are sailing isn't going to be smooth.
>>
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> ---
>>  drivers/irqchip/irq-gic-v3.c       | 5 +++++
>>  include/linux/irqchip/arm-gic-v3.h | 1 +
>>  2 files changed, 6 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index f53e58d398ba..334a10d9dbfb 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -1014,6 +1014,11 @@ static void gic_cpu_init(void)
>>  
>>  	gic_enable_redist(true);
>>  
>> +	WARN((gic_data.ppi_nr > 16 || GIC_ESPI_NR != 0) &&
>> +	     !(gic_read_ctlr() & ICC_CTLR_EL1_ExtRange),
>> +	     "Distributor has extended ranges, but CPU%d doesn't\n",
>> +	     smp_processor_id());
>> +
> 
> Should such setup be tainted?

I'm not completely sure. The system isn't really dead, but a whole range
of interrupts will not be able to make it to the CPU. It won't be less
reliable though.

I expect this to be more for system integration purposes (simulation
setup, for example), where something hasn't been setup correctly. Or to
spot implementation creativity, such as in the last patch.

I'm happy either way, TBH.

Thanks,

	M.
-- 
Jazz is not dead, it just smells funny...

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] irqchip/gic-v3: Add ESPI range support
  2019-08-06 10:01 ` [PATCH v2 04/12] irqchip/gic-v3: Add " Marc Zyngier
@ 2019-08-19 14:25   ` Zenghui Yu
  2019-08-20  9:18     ` Marc Zyngier
  0 siblings, 1 reply; 24+ messages in thread
From: Zenghui Yu @ 2019-08-19 14:25 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring,
	Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

Hi Marc,

On 2019/8/6 18:01, Marc Zyngier wrote:
> Add the required support for the ESPI range, which behave exactly like
> the SPIs of old, only with new funky INTIDs.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>   drivers/irqchip/irq-gic-v3.c       | 85 ++++++++++++++++++++++++------
>   include/linux/irqchip/arm-gic-v3.h | 17 +++++-
>   2 files changed, 85 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index db3bdedd7241..1ca4dde32034 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -51,13 +51,16 @@ struct gic_chip_data {
>   	u32			nr_redist_regions;
>   	u64			flags;
>   	bool			has_rss;
> -	unsigned int		irq_nr;
>   	struct partition_desc	*ppi_descs[16];
>   };
>   
>   static struct gic_chip_data gic_data __read_mostly;
>   static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>   
> +#define GIC_ID_NR	(1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
> +#define GIC_LINE_NR	GICD_TYPER_SPIS(gic_data.rdists.gicd_typer)

This indicates the maximum SPI INTID that the GIC implementation
supports, should we restrict it to no more than 1020?

ITLinesNumber can be '11111', and I saw the following info on my host:
     "GICv3: 992 SPIs implemented"


Thanks,
zenghui


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
  2019-08-06 10:01 ` [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base Marc Zyngier
@ 2019-08-19 14:26   ` Zenghui Yu
  2019-08-19 14:53     ` Marc Zyngier
  0 siblings, 1 reply; 24+ messages in thread
From: Zenghui Yu @ 2019-08-19 14:26 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring,
	Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

Hi Marc,

On 2019/8/6 18:01, Marc Zyngier wrote:
> gic_configure_irq is currently passed the (re)distributor address,
> to which it applies an a fixed offset to get to the configuration
> registers. This offset is constant across all GICs, or rather it was
> until to v3.1...
> 
> An easy way out is for the individual drivers to pass the base
> address of the configuration register for the considered interrupt.
> At the same time, move part of the error handling back to the
> individual drivers, as things are about to change on that front.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>   drivers/irqchip/irq-gic-common.c | 14 +++++---------
>   drivers/irqchip/irq-gic-v3.c     | 11 ++++++++++-
>   drivers/irqchip/irq-gic.c        | 10 +++++++++-
>   drivers/irqchip/irq-hip04.c      |  7 ++++++-
>   4 files changed, 30 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
> index b0a8215a13fc..6900b6f0921c 100644
> --- a/drivers/irqchip/irq-gic-common.c
> +++ b/drivers/irqchip/irq-gic-common.c
> @@ -63,7 +63,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
>   	 * for "irq", depending on "type".
>   	 */
>   	raw_spin_lock_irqsave(&irq_controller_lock, flags);
> -	val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
> +	val = oldval = readl_relaxed(base + confoff);
>   	if (type & IRQ_TYPE_LEVEL_MASK)
>   		val &= ~confmask;
>   	else if (type & IRQ_TYPE_EDGE_BOTH)
> @@ -83,14 +83,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
>   	 * does not allow us to set the configuration or we are in a
>   	 * non-secure mode, and hence it may not be catastrophic.
>   	 */
> -	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
> -	if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
> -		if (WARN_ON(irq >= 32))
> -			ret = -EINVAL;

Since this WARN_ON is dropped, the comment above should also be updated.
But what is the reason for deleting it?  (It may give us some points
when we fail to set type for SPIs.)


Thanks,
zenghui

> -		else
> -			pr_warn("GIC: PPI%d is secure or misconfigured\n",
> -				irq - 16);
> -	}
> +	writel_relaxed(val, base + confoff);
> +	if (readl_relaxed(base + confoff) != val)
> +		ret = -EINVAL;
> +
>   	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
>   
>   	if (sync_access)
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 96d927f0f91a..b250e69908f8 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -407,6 +407,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>   	unsigned int irq = gic_irq(d);
>   	void (*rwp_wait)(void);
>   	void __iomem *base;
> +	int ret;
>   
>   	/* Interrupt configuration for SGIs can't be changed */
>   	if (irq < 16)
> @@ -425,7 +426,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>   		rwp_wait = gic_dist_wait_for_rwp;
>   	}
>   
> -	return gic_configure_irq(irq, type, base, rwp_wait);
> +
> +	ret = gic_configure_irq(irq, type, base + GICD_ICFGR, rwp_wait);
> +	if (ret && irq < 32) {
> +		/* Misconfigured PPIs are usually not fatal */
> +		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
> +		ret = 0;
> +	}
> +
> +	return ret;
>   }
>   
>   static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index e45f45e68720..ab48760acabb 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -291,6 +291,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>   {
>   	void __iomem *base = gic_dist_base(d);
>   	unsigned int gicirq = gic_irq(d);
> +	int ret;
>   
>   	/* Interrupt configuration for SGIs can't be changed */
>   	if (gicirq < 16)
> @@ -301,7 +302,14 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>   			    type != IRQ_TYPE_EDGE_RISING)
>   		return -EINVAL;
>   
> -	return gic_configure_irq(gicirq, type, base, NULL);
> +	ret = gic_configure_irq(gicirq, type, base + GIC_DIST_CONFIG, NULL);
> +	if (ret && gicirq < 32) {
> +		/* Misconfigured PPIs are usually not fatal */
> +		pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16);
> +		ret = 0;
> +	}
> +
> +	return ret;
>   }
>   
>   static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
> diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
> index cf705827599c..1626131834a6 100644
> --- a/drivers/irqchip/irq-hip04.c
> +++ b/drivers/irqchip/irq-hip04.c
> @@ -130,7 +130,12 @@ static int hip04_irq_set_type(struct irq_data *d, unsigned int type)
>   
>   	raw_spin_lock(&irq_controller_lock);
>   
> -	ret = gic_configure_irq(irq, type, base, NULL);
> +	ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL);
> +	if (ret && irq < 32) {
> +		/* Misconfigured PPIs are usually not fatal */
> +		pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
> +		ret = 0;
> +	}
>   
>   	raw_spin_unlock(&irq_controller_lock);
>   
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base
  2019-08-19 14:26   ` Zenghui Yu
@ 2019-08-19 14:53     ` Marc Zyngier
  0 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-19 14:53 UTC (permalink / raw)
  To: Zenghui Yu
  Cc: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring,
	Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

On 19/08/2019 15:26, Zenghui Yu wrote:
> Hi Marc,
> 
> On 2019/8/6 18:01, Marc Zyngier wrote:
>> gic_configure_irq is currently passed the (re)distributor address,
>> to which it applies an a fixed offset to get to the configuration
>> registers. This offset is constant across all GICs, or rather it was
>> until to v3.1...
>>
>> An easy way out is for the individual drivers to pass the base
>> address of the configuration register for the considered interrupt.
>> At the same time, move part of the error handling back to the
>> individual drivers, as things are about to change on that front.
>>
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> ---
>>   drivers/irqchip/irq-gic-common.c | 14 +++++---------
>>   drivers/irqchip/irq-gic-v3.c     | 11 ++++++++++-
>>   drivers/irqchip/irq-gic.c        | 10 +++++++++-
>>   drivers/irqchip/irq-hip04.c      |  7 ++++++-
>>   4 files changed, 30 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
>> index b0a8215a13fc..6900b6f0921c 100644
>> --- a/drivers/irqchip/irq-gic-common.c
>> +++ b/drivers/irqchip/irq-gic-common.c
>> @@ -63,7 +63,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
>>   	 * for "irq", depending on "type".
>>   	 */
>>   	raw_spin_lock_irqsave(&irq_controller_lock, flags);
>> -	val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
>> +	val = oldval = readl_relaxed(base + confoff);
>>   	if (type & IRQ_TYPE_LEVEL_MASK)
>>   		val &= ~confmask;
>>   	else if (type & IRQ_TYPE_EDGE_BOTH)
>> @@ -83,14 +83,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
>>   	 * does not allow us to set the configuration or we are in a
>>   	 * non-secure mode, and hence it may not be catastrophic.
>>   	 */
>> -	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
>> -	if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
>> -		if (WARN_ON(irq >= 32))
>> -			ret = -EINVAL;
> 
> Since this WARN_ON is dropped, the comment above should also be updated.
> But what is the reason for deleting it?  (It may give us some points
> when we fail to set type for SPIs.)

The core code already warns in the case where irq_set_type() fails, and
the duplication of warnings is pretty superfluous.

Thanks,

	M.
-- 
Jazz is not dead, it just smells funny...

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] irqchip/gic-v3: Add ESPI range support
  2019-08-19 14:25   ` Zenghui Yu
@ 2019-08-20  9:18     ` Marc Zyngier
  0 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-20  9:18 UTC (permalink / raw)
  To: Zenghui Yu
  Cc: Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring,
	Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

On 19/08/2019 15:25, Zenghui Yu wrote:
> Hi Marc,
> 
> On 2019/8/6 18:01, Marc Zyngier wrote:
>> Add the required support for the ESPI range, which behave exactly like
>> the SPIs of old, only with new funky INTIDs.
>>
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> ---
>>   drivers/irqchip/irq-gic-v3.c       | 85 ++++++++++++++++++++++++------
>>   include/linux/irqchip/arm-gic-v3.h | 17 +++++-
>>   2 files changed, 85 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index db3bdedd7241..1ca4dde32034 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -51,13 +51,16 @@ struct gic_chip_data {
>>   	u32			nr_redist_regions;
>>   	u64			flags;
>>   	bool			has_rss;
>> -	unsigned int		irq_nr;
>>   	struct partition_desc	*ppi_descs[16];
>>   };
>>   
>>   static struct gic_chip_data gic_data __read_mostly;
>>   static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>>   
>> +#define GIC_ID_NR	(1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
>> +#define GIC_LINE_NR	GICD_TYPER_SPIS(gic_data.rdists.gicd_typer)
> 
> This indicates the maximum SPI INTID that the GIC implementation
> supports, should we restrict it to no more than 1020?

I guess we could write it as max(GICD_TYPER_SPIS(...), 1020), but that's
not a material change (the registers backing the special range do exist).

> ITLinesNumber can be '11111', and I saw the following info on my host:
>      "GICv3: 992 SPIs implemented"

Yeah, the above should fix the print.

Thanks,

	M.
-- 
Jazz is not dead, it just smells funny...

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs
  2019-08-06 10:01 ` [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs Marc Zyngier
@ 2019-08-21 18:40   ` Zenghui Yu
  2019-08-22 16:11   ` Julien
  1 sibling, 0 replies; 24+ messages in thread
From: Zenghui Yu @ 2019-08-21 18:40 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Julien Thierry, Rob Herring
  Cc: Lokesh Vutla, John Garry, linux-kernel,
	Shameerali Kolothum Thodi, linux-arm-kernel

On 2019/8/6 18:01, Marc Zyngier wrote:
> GICv3.1 allows up to 80 PPIs (16 legaci PPIs and 64 Extended PPIs),
                                   ^^^^^^
legacy?


Zenghui

> meaning we can't just leave the old 16 hardcoded everywhere.
> 
> We also need to add the infrastructure to discover the number of PPIs
> on a per redistributor basis, although we still pretend there is only
> 16 of them for now.
> 
> No functional change.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts
  2019-08-06 10:01 ` [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts Marc Zyngier
@ 2019-08-22 15:05   ` Julien
  0 siblings, 0 replies; 24+ messages in thread
From: Julien @ 2019-08-22 15:05 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Hi Marc,

On 06/08/19 11:01, Marc Zyngier wrote:
> As we're about to have a variable number of PPIs, let's make the
> allocation of the NMI refcounts dynamic. Also apply some minor
> cleanups (moving things around).
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Reviewed-by: Julien Thierry <julien.thierry.kdev@gmail.com>

Thanks,

> ---
>   drivers/irqchip/irq-gic-v3.c | 47 ++++++++++++++++++++++++++----------
>   1 file changed, 34 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index e03fb6d7c2ce..4253c7f67c86 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -88,7 +88,7 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>   static DEFINE_STATIC_KEY_FALSE(supports_pseudo_nmis);
>   
>   /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> -static refcount_t ppi_nmi_refs[16];
> +static refcount_t *ppi_nmi_refs;
>   
>   static struct gic_kvm_info gic_v3_kvm_info;
>   static DEFINE_PER_CPU(bool, has_rss);
> @@ -409,6 +409,16 @@ static void gic_irq_set_prio(struct irq_data *d, u8 prio)
>   	writeb_relaxed(prio, base + offset + index);
>   }
>   
> +static u32 gic_get_ppi_index(struct irq_data *d)
> +{
> +	switch (get_intid_range(d)) {
> +	case PPI_RANGE:
> +		return d->hwirq - 16;
> +	default:
> +		unreachable();
> +	}
> +}
> +
>   static int gic_irq_nmi_setup(struct irq_data *d)
>   {
>   	struct irq_desc *desc = irq_to_desc(d->irq);
> @@ -429,10 +439,12 @@ static int gic_irq_nmi_setup(struct irq_data *d)
>   		return -EINVAL;
>   
>   	/* desc lock should already be held */
> -	if (gic_irq(d) < 32) {
> +	if (gic_irq_in_rdist(d)) {
> +		u32 idx = gic_get_ppi_index(d);
> +
>   		/* Setting up PPI as NMI, only switch handler for first NMI */
> -		if (!refcount_inc_not_zero(&ppi_nmi_refs[gic_irq(d) - 16])) {
> -			refcount_set(&ppi_nmi_refs[gic_irq(d) - 16], 1);
> +		if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
> +			refcount_set(&ppi_nmi_refs[idx], 1);
>   			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
>   		}
>   	} else {
> @@ -464,9 +476,11 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
>   		return;
>   
>   	/* desc lock should already be held */
> -	if (gic_irq(d) < 32) {
> +	if (gic_irq_in_rdist(d)) {
> +		u32 idx = gic_get_ppi_index(d);
> +
>   		/* Tearing down NMI, only switch handler for last NMI */
> -		if (refcount_dec_and_test(&ppi_nmi_refs[gic_irq(d) - 16]))
> +		if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
>   			desc->handle_irq = handle_percpu_devid_irq;
>   	} else {
>   		desc->handle_irq = handle_fasteoi_irq;
> @@ -1394,7 +1408,19 @@ static void gic_enable_nmi_support(void)
>   {
>   	int i;
>   
> -	for (i = 0; i < 16; i++)
> +	if (!gic_prio_masking_enabled())
> +		return;
> +
> +	if (gic_has_group0() && !gic_dist_security_disabled()) {
> +		pr_warn("SCR_EL3.FIQ is cleared, cannot enable use of pseudo-NMIs\n");
> +		return;
> +	}
> +
> +	ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
> +	if (!ppi_nmi_refs)
> +		return;
> +
> +	for (i = 0; i < gic_data.ppi_nr; i++)
>   		refcount_set(&ppi_nmi_refs[i], 0);
>   
>   	static_branch_enable(&supports_pseudo_nmis);
> @@ -1472,12 +1498,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
>   			gicv2m_init(handle, gic_data.domain);
>   	}
>   
> -	if (gic_prio_masking_enabled()) {
> -		if (!gic_has_group0() || gic_dist_security_disabled())
> -			gic_enable_nmi_support();
> -		else
> -			pr_warn("SCR_EL3.FIQ is cleared, cannot enable use of pseudo-NMIs\n");
> -	}
> +	gic_enable_nmi_support();
>   
>   	return 0;
>   
> 

-- 
Julien Thierry

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs
  2019-08-06 10:01 ` [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs Marc Zyngier
  2019-08-21 18:40   ` Zenghui Yu
@ 2019-08-22 16:11   ` Julien
  2019-08-22 16:32     ` Marc Zyngier
  1 sibling, 1 reply; 24+ messages in thread
From: Julien @ 2019-08-22 16:11 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Jason Cooper, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Hi Marc,

On 06/08/19 11:01, Marc Zyngier wrote:
> GICv3.1 allows up to 80 PPIs (16 legaci PPIs and 64 Extended PPIs),
> meaning we can't just leave the old 16 hardcoded everywhere.
> 
> We also need to add the infrastructure to discover the number of PPIs
> on a per redistributor basis, although we still pretend there is only
> 16 of them for now.
> 
> No functional change.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>   drivers/irqchip/irq-gic-common.c | 19 ++++++++++++-------
>   drivers/irqchip/irq-gic-common.h |  2 +-
>   drivers/irqchip/irq-gic-v3.c     | 22 +++++++++++++++-------
>   drivers/irqchip/irq-gic.c        |  2 +-
>   drivers/irqchip/irq-hip04.c      |  2 +-
>   5 files changed, 30 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
> index 6900b6f0921c..14110db01c05 100644
> --- a/drivers/irqchip/irq-gic-common.c
> +++ b/drivers/irqchip/irq-gic-common.c
> @@ -128,26 +128,31 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
>   		sync_access();
>   }
>   
> -void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
> +void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
>   {
>   	int i;
>   
>   	/*
>   	 * Deal with the banked PPI and SGI interrupts - disable all
> -	 * PPI interrupts, ensure all SGI interrupts are enabled.
> -	 * Make sure everything is deactivated.
> +	 * private interrupts. Make sure everything is deactivated.
>   	 */
> -	writel_relaxed(GICD_INT_EN_CLR_X32, base + GIC_DIST_ACTIVE_CLEAR);
> -	writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR);
> -	writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
> +	for (i = 0; i < nr; i += 32) {

You added "nr" as argument but if "nr" isn't a multiple of 32 weird 
things might happen, no?

It would be worth specifying that somewhere, and checking it with a WARN().

Maybe it might be worth reducing the granularity to manipulating 16 irqs 
since there are 16 SGI + 16 PPI + 64 EPPI, but that might not be very 
useful right now.

Cheers,

Julien

> +		writel_relaxed(GICD_INT_EN_CLR_X32,
> +			       base + GIC_DIST_ACTIVE_CLEAR + i / 8);
> +		writel_relaxed(GICD_INT_EN_CLR_X32,
> +			       base + GIC_DIST_ENABLE_CLEAR + i / 8);
> +	}
>   
>   	/*
>   	 * Set priority on PPI and SGI interrupts
>   	 */
> -	for (i = 0; i < 32; i += 4)
> +	for (i = 0; i < nr; i += 4)
>   		writel_relaxed(GICD_INT_DEF_PRI_X4,
>   					base + GIC_DIST_PRI + i * 4 / 4);
>   
> +	/* Ensure all SGI interrupts are now enabled */
> +	writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
> +
>   	if (sync_access)
>   		sync_access();
>   }
> diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
> index 5a46b6b57750..ccba8b0fe0f5 100644
> --- a/drivers/irqchip/irq-gic-common.h
> +++ b/drivers/irqchip/irq-gic-common.h
> @@ -22,7 +22,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
>                          void __iomem *base, void (*sync_access)(void));
>   void gic_dist_config(void __iomem *base, int gic_irqs,
>   		     void (*sync_access)(void));
> -void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
> +void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void));
>   void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
>   		void *data);
>   void gic_enable_of_quirks(const struct device_node *np,
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 1ca4dde32034..e03fb6d7c2ce 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -51,6 +51,7 @@ struct gic_chip_data {
>   	u32			nr_redist_regions;
>   	u64			flags;
>   	bool			has_rss;
> +	unsigned int		ppi_nr;
>   	struct partition_desc	*ppi_descs[16];
>   };
>   
> @@ -812,19 +813,24 @@ static int gic_populate_rdist(void)
>   	return -ENODEV;
>   }
>   
> -static int __gic_update_vlpi_properties(struct redist_region *region,
> -					void __iomem *ptr)
> +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);
> +	gic_data.ppi_nr = 16;
>   
>   	return 1;
>   }
>   
> -static void gic_update_vlpi_properties(void)
> +static void gic_update_rdist_properties(void)
>   {
> -	gic_iterate_rdists(__gic_update_vlpi_properties);
> +	gic_data.ppi_nr = UINT_MAX;
> +	gic_iterate_rdists(__gic_update_rdist_properties);
> +	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",
>   		!gic_data.rdists.has_vlpis ? "no " : "",
>   		!gic_data.rdists.has_direct_lpi ? "no " : "");
> @@ -968,6 +974,7 @@ static int gic_dist_supports_lpis(void)
>   static void gic_cpu_init(void)
>   {
>   	void __iomem *rbase;
> +	int i;
>   
>   	/* Register ourselves with the rest of the world */
>   	if (gic_populate_rdist())
> @@ -978,9 +985,10 @@ static void gic_cpu_init(void)
>   	rbase = gic_data_rdist_sgi_base();
>   
>   	/* Configure SGIs/PPIs as non-secure Group-1 */
> -	writel_relaxed(~0, rbase + GICR_IGROUPR0);
> +	for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
> +		writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
>   
> -	gic_cpu_config(rbase, gic_redist_wait_for_rwp);
> +	gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
>   
>   	/* initialise system registers */
>   	gic_cpu_sys_reg_init();
> @@ -1449,7 +1457,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
>   
>   	set_handle_irq(gic_handle_irq);
>   
> -	gic_update_vlpi_properties();
> +	gic_update_rdist_properties();
>   
>   	gic_smp_init();
>   	gic_dist_init();
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index ab48760acabb..25c1ae69db30 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -543,7 +543,7 @@ static int gic_cpu_init(struct gic_chip_data *gic)
>   				gic_cpu_map[i] &= ~cpu_mask;
>   	}
>   
> -	gic_cpu_config(dist_base, NULL);
> +	gic_cpu_config(dist_base, 32, NULL);
>   
>   	writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
>   	gic_cpu_if_up(gic);
> diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
> index 1626131834a6..130caa1c9d93 100644
> --- a/drivers/irqchip/irq-hip04.c
> +++ b/drivers/irqchip/irq-hip04.c
> @@ -273,7 +273,7 @@ static void hip04_irq_cpu_init(struct hip04_irq_data *intc)
>   		if (i != cpu)
>   			hip04_cpu_map[i] &= ~cpu_mask;
>   
> -	gic_cpu_config(dist_base, NULL);
> +	gic_cpu_config(dist_base, 32, NULL);
>   
>   	writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
>   	writel_relaxed(1, base + GIC_CPU_CTRL);
> 

-- 
Julien Thierry

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs
  2019-08-22 16:11   ` Julien
@ 2019-08-22 16:32     ` Marc Zyngier
  0 siblings, 0 replies; 24+ messages in thread
From: Marc Zyngier @ 2019-08-22 16:32 UTC (permalink / raw)
  To: Julien, Thomas Gleixner, Jason Cooper, Rob Herring
  Cc: John Garry, Shameerali Kolothum Thodi, Lokesh Vutla,
	linux-kernel, linux-arm-kernel

Hi Julien,

On 22/08/2019 17:11, Julien wrote:
> Hi Marc,
> 
> On 06/08/19 11:01, Marc Zyngier wrote:
>> GICv3.1 allows up to 80 PPIs (16 legaci PPIs and 64 Extended PPIs),
>> meaning we can't just leave the old 16 hardcoded everywhere.
>>
>> We also need to add the infrastructure to discover the number of PPIs
>> on a per redistributor basis, although we still pretend there is only
>> 16 of them for now.
>>
>> No functional change.
>>
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> ---
>>   drivers/irqchip/irq-gic-common.c | 19 ++++++++++++-------
>>   drivers/irqchip/irq-gic-common.h |  2 +-
>>   drivers/irqchip/irq-gic-v3.c     | 22 +++++++++++++++-------
>>   drivers/irqchip/irq-gic.c        |  2 +-
>>   drivers/irqchip/irq-hip04.c      |  2 +-
>>   5 files changed, 30 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
>> index 6900b6f0921c..14110db01c05 100644
>> --- a/drivers/irqchip/irq-gic-common.c
>> +++ b/drivers/irqchip/irq-gic-common.c
>> @@ -128,26 +128,31 @@ void gic_dist_config(void __iomem *base, int gic_irqs,
>>   		sync_access();
>>   }
>>   
>> -void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
>> +void gic_cpu_config(void __iomem *base, int nr, void (*sync_access)(void))
>>   {
>>   	int i;
>>   
>>   	/*
>>   	 * Deal with the banked PPI and SGI interrupts - disable all
>> -	 * PPI interrupts, ensure all SGI interrupts are enabled.
>> -	 * Make sure everything is deactivated.
>> +	 * private interrupts. Make sure everything is deactivated.
>>   	 */
>> -	writel_relaxed(GICD_INT_EN_CLR_X32, base + GIC_DIST_ACTIVE_CLEAR);
>> -	writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR);
>> -	writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET);
>> +	for (i = 0; i < nr; i += 32) {
> 
> You added "nr" as argument but if "nr" isn't a multiple of 32 weird 
> things might happen, no?
>
> It would be worth specifying that somewhere, and checking it with a WARN().

TBH, I'm unsure whether that's worth it. The architecture is completely
built around having the private interrupts in blocks of 32, and you can
only get something wrong if you misdecode the number of interrupts from
the registers.

> Maybe it might be worth reducing the granularity to manipulating 16 irqs 
> since there are 16 SGI + 16 PPI + 64 EPPI, but that might not be very 
> useful right now.

I don't see what this brings us at this point. The architecture doesn't
seem to go in the direction of adding more SGIs, so we're pretty safe on
that front...

Thanks,

	M.
-- 
Jazz is not dead, it just smells funny...

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2019-08-22 16:32 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-06 10:01 [PATCH v2 00/12] irqchip/gic-v3: Add support for GICv3.1 extended PPI/SPI ranges Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 01/12] irqchip/gic: Rework gic_configure_irq to take the full ICFGR base Marc Zyngier
2019-08-19 14:26   ` Zenghui Yu
2019-08-19 14:53     ` Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 02/12] irqchip/gic-v3: Add INTID range and convertion primitives Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 03/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe ESPI range support Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 04/12] irqchip/gic-v3: Add " Marc Zyngier
2019-08-19 14:25   ` Zenghui Yu
2019-08-20  9:18     ` Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 05/12] irqchip/gic: Prepare for more than 16 PPIs Marc Zyngier
2019-08-21 18:40   ` Zenghui Yu
2019-08-22 16:11   ` Julien
2019-08-22 16:32     ` Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 06/12] irqchip/gic-v3: Dynamically allocate PPI NMI refcounts Marc Zyngier
2019-08-22 15:05   ` Julien
2019-08-06 10:01 ` [PATCH v2 07/12] irqchip/gic-v3: Dynamically allocate PPI partition descriptors Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 08/12] dt-bindings: interrupt-controller: arm,gic-v3: Describe EPPI range support Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 09/12] irqchip/gic-v3: Add " Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 10/12] irqchip/gic-v3: Warn about inconsistent implementations of extended ranges Marc Zyngier
2019-08-06 10:15   ` Vladimir Murzin
2019-08-06 11:15     ` Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 11/12] irqchip/gic: Skip DT quirks when evaluating IIDR-based quirks Marc Zyngier
2019-08-06 10:01 ` [PATCH v2 12/12] irqchip/gic-v3: Add quirks for HIP06/07 invalid GICD_TYPER erratum 161010803 Marc Zyngier
2019-08-06 11:07   ` John Garry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).