KVM ARM Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1
@ 2020-02-06  7:57 Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE Zenghui Yu
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

Hi,

This series contains some cleanups, VPROPBASER field programming fix
and level2 vPE table allocation enhancement, collected while looking
through the GICv4.1 driver one more time.

Hope they will help, thanks!

v1 -> v2:
 - Take into account Marc's comments on patch#3
 - Add one more patch to rename V{PEND,PROP}BASER accessors

Zenghui Yu (6):
  irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE
  irqchip/gic-v4.1: Set vpe_l1_base for all redistributors
  irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level
  irqchip/gic-v4.1: Drop 'tmp' in inherit_vpe_l1_table_from_rd()
  irqchip/gic-v3-its: Remove superfluous WARN_ON
  irqchip/gic-v3-its: Rename VPENDBASER/VPROPBASER accessors

 arch/arm/include/asm/arch_gicv3.h   |  12 +--
 arch/arm64/include/asm/arch_gicv3.h |   8 +-
 drivers/irqchip/irq-gic-v3-its.c    | 118 +++++++++++++++++++++++-----
 include/linux/irqchip/arm-gic-v3.h  |   2 +-
 4 files changed, 110 insertions(+), 30 deletions(-)

-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 2/6] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors Zenghui Yu
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

The Size field of GICv4.1 VPROPBASER register indicates number of
pages minus one and together Page_Size and Size control the vPEID
width. Let's respect this requirement of the architecture.

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index e5a25d97f8db..992bc72cab6f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2531,7 +2531,7 @@ static int allocate_vpe_l1_table(void)
 		npg = 1;
 	}
 
-	val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg);
+	val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg - 1);
 
 	/* Right, that's the number of CPU pages we need for L1 */
 	np = DIV_ROUND_UP(npg * psz, PAGE_SIZE);
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 2/6] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level Zenghui Yu
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

Currently, we will not set vpe_l1_page for the current RD if we can
inherit the vPE configuration table from another RD (or ITS), which
results in an inconsistency between RDs within the same CommonLPIAff
group.

Let's rename it to vpe_l1_base to indicate the base address of the
vPE configuration table of this RD, and set it properly for *all*
v4.1 redistributors.

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 5 ++++-
 include/linux/irqchip/arm-gic-v3.h | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 992bc72cab6f..0f1fe56ce0af 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2376,6 +2376,8 @@ static u64 inherit_vpe_l1_table_from_its(void)
 			continue;
 
 		/* We have a winner! */
+		gic_data_rdist()->vpe_l1_base = its->tables[2].base;
+
 		val  = GICR_VPROPBASER_4_1_VALID;
 		if (baser & GITS_BASER_INDIRECT)
 			val |= GICR_VPROPBASER_4_1_INDIRECT;
@@ -2432,6 +2434,7 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
 		val = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
 		val &= ~GICR_VPROPBASER_4_1_Z;
 
+		gic_data_rdist()->vpe_l1_base = gic_data_rdist_cpu(cpu)->vpe_l1_base;
 		*mask = gic_data_rdist_cpu(cpu)->vpe_table_mask;
 
 		return val;
@@ -2542,7 +2545,7 @@ static int allocate_vpe_l1_table(void)
 	if (!page)
 		return -ENOMEM;
 
-	gic_data_rdist()->vpe_l1_page = page;
+	gic_data_rdist()->vpe_l1_base = page_address(page);
 	pa = virt_to_phys(page_address(page));
 	WARN_ON(!IS_ALIGNED(pa, psz));
 
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index f0b8ca766e7d..83439bfb6c5b 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -652,10 +652,10 @@ struct rdists {
 	struct {
 		void __iomem	*rd_base;
 		struct page	*pend_page;
-		struct page	*vpe_l1_page;
 		phys_addr_t	phys_base;
 		bool		lpi_enabled;
 		cpumask_t	*vpe_table_mask;
+		void		*vpe_l1_base;
 	} __percpu		*rdist;
 	phys_addr_t		prop_table_pa;
 	void			*prop_table_va;
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 2/6] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  2020-02-13 14:22   ` Marc Zyngier
  2020-02-06  7:57 ` [PATCH v2 4/6] irqchip/gic-v4.1: Drop 'tmp' in inherit_vpe_l1_table_from_rd() Zenghui Yu
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

In GICv4, we will ensure that level2 vPE table memory is allocated
for the specified vpe_id on all v4 ITS, in its_alloc_vpe_table().
This still works well for the typical GICv4.1 implementation, where
the new vPE table is shared between the ITSs and the RDs.

To make it explicit, let us introduce allocate_vpe_l2_table() to
make sure that the L2 tables are allocated on all v4.1 RDs. We're
likely not need to allocate memory in it because the vPE table is
shared and (L2 table is) already allocated at ITS level, except
for the case where the ITS doesn't share anything (say SVPET == 0,
practically unlikely but architecturally allowed).

The implementation of allocate_vpe_l2_table() is mostly copied from
its_alloc_table_entry().

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 80 ++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0f1fe56ce0af..ae4e7b355b46 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2443,6 +2443,72 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
 	return 0;
 }
 
+static bool allocate_vpe_l2_table(int cpu, u32 id)
+{
+	void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
+	u64 val, gpsz, npg;
+	unsigned int psz, esz, idx;
+	struct page *page;
+	__le64 *table;
+
+	if (!gic_rdists->has_rvpeid)
+		return true;
+
+	val  = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
+
+	esz  = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val) + 1;
+	gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
+	npg  = FIELD_GET(GICR_VPROPBASER_4_1_SIZE, val) + 1;
+
+	switch (gpsz) {
+	default:
+		WARN_ON(1);
+		/* fall through */
+	case GIC_PAGE_SIZE_4K:
+		psz = SZ_4K;
+		break;
+	case GIC_PAGE_SIZE_16K:
+		psz = SZ_16K;
+		break;
+	case GIC_PAGE_SIZE_64K:
+		psz = SZ_64K;
+		break;
+	}
+
+	/* Don't allow vpe_id that exceeds single, flat table limit */
+	if (!(val & GICR_VPROPBASER_4_1_INDIRECT))
+		return (id < (npg * psz / (esz * SZ_8)));
+
+	/* Compute 1st level table index & check if that exceeds table limit */
+	idx = id >> ilog2(psz / (esz * SZ_8));
+	if (idx >= (npg * psz / GITS_LVL1_ENTRY_SIZE))
+		return false;
+
+	table = gic_data_rdist_cpu(cpu)->vpe_l1_base;
+
+	/* Allocate memory for 2nd level table */
+	if (!table[idx]) {
+		page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
+		if (!page)
+			return false;
+
+		/* Flush Lvl2 table to PoC if hw doesn't support coherency */
+		if (!(val & GICR_VPROPBASER_SHAREABILITY_MASK))
+			gic_flush_dcache_to_poc(page_address(page), psz);
+
+		table[idx] = cpu_to_le64(page_to_phys(page) | GITS_BASER_VALID);
+
+		/* Flush Lvl1 entry to PoC if hw doesn't support coherency */
+		if (!(val & GICR_VPROPBASER_SHAREABILITY_MASK))
+			gic_flush_dcache_to_poc(table + idx, GITS_LVL1_ENTRY_SIZE);
+
+		/* Ensure updated table contents are visible to RD hardware */
+		dsb(sy);
+	}
+
+	return true;
+}
+
 static int allocate_vpe_l1_table(void)
 {
 	void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
@@ -2957,6 +3023,7 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 static bool its_alloc_vpe_table(u32 vpe_id)
 {
 	struct its_node *its;
+	int cpu;
 
 	/*
 	 * Make sure the L2 tables are allocated on *all* v4 ITSs. We
@@ -2979,6 +3046,19 @@ static bool its_alloc_vpe_table(u32 vpe_id)
 			return false;
 	}
 
+	/* Non v4.1? No need to iterate RDs and go back early. */
+	if (!gic_rdists->has_rvpeid)
+		return true;
+
+	/*
+	 * Make sure the L2 tables are allocated for all copies of
+	 * the L1 table on *all* v4.1 RDs.
+	 */
+	for_each_possible_cpu(cpu) {
+		if (!allocate_vpe_l2_table(cpu, vpe_id))
+			return false;
+	}
+
 	return true;
 }
 
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 4/6] irqchip/gic-v4.1: Drop 'tmp' in inherit_vpe_l1_table_from_rd()
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
                   ` (2 preceding siblings ...)
  2020-02-06  7:57 ` [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 5/6] irqchip/gic-v3-its: Remove superfluous WARN_ON Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 6/6] irqchip/gic-v3-its: Rename VPENDBASER/VPROPBASER accessors Zenghui Yu
  5 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

The variable 'tmp' in inherit_vpe_l1_table_from_rd() is actually
not needed, drop it.

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index ae4e7b355b46..8405ebdd9ffb 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2415,14 +2415,12 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
 
 	for_each_possible_cpu(cpu) {
 		void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
-		u32 tmp;
 
 		if (!base || cpu == smp_processor_id())
 			continue;
 
 		val = gic_read_typer(base + GICR_TYPER);
-		tmp = compute_common_aff(val);
-		if (tmp != aff)
+		if (aff != compute_common_aff(val))
 			continue;
 
 		/*
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 5/6] irqchip/gic-v3-its: Remove superfluous WARN_ON
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
                   ` (3 preceding siblings ...)
  2020-02-06  7:57 ` [PATCH v2 4/6] irqchip/gic-v4.1: Drop 'tmp' in inherit_vpe_l1_table_from_rd() Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  2020-02-06  7:57 ` [PATCH v2 6/6] irqchip/gic-v3-its: Rename VPENDBASER/VPROPBASER accessors Zenghui Yu
  5 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

"ITS virtual pending table not cleaning" is already complained inside
its_clear_vpend_valid(), there's no need to trigger a WARN_ON again.

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 8405ebdd9ffb..811875bf3abb 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2857,7 +2857,6 @@ static void its_cpu_init_lpis(void)
 		 * corrupting memory.
 		 */
 		val = its_clear_vpend_valid(vlpi_base, 0, 0);
-		WARN_ON(val & GICR_VPENDBASER_Dirty);
 	}
 
 	if (allocate_vpe_l1_table()) {
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v2 6/6] irqchip/gic-v3-its: Rename VPENDBASER/VPROPBASER accessors
  2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
                   ` (4 preceding siblings ...)
  2020-02-06  7:57 ` [PATCH v2 5/6] irqchip/gic-v3-its: Remove superfluous WARN_ON Zenghui Yu
@ 2020-02-06  7:57 ` Zenghui Yu
  5 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-06  7:57 UTC (permalink / raw)
  To: linux-kernel, maz; +Cc: jason, tglx, kvmarm, linux-arm-kernel

V{PEND,PROP}BASER registers are actually located in VLPI_base frame
of the *redistributor*. Rename their accessors to reflect this fact.

No functional changes.

Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
 arch/arm/include/asm/arch_gicv3.h   | 12 ++++++------
 arch/arm64/include/asm/arch_gicv3.h |  8 ++++----
 drivers/irqchip/irq-gic-v3-its.c    | 28 ++++++++++++++--------------
 3 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index b5752f0e8936..c815477b4303 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -326,16 +326,16 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
 #define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
 
 /*
- * GITS_VPROPBASER - hi and lo bits may be accessed independently.
+ * GICR_VPROPBASER - hi and lo bits may be accessed independently.
  */
-#define gits_read_vpropbaser(c)		__gic_readq_nonatomic(c)
-#define gits_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
+#define gicr_read_vpropbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
 
 /*
- * GITS_VPENDBASER - the Valid bit must be cleared before changing
+ * GICR_VPENDBASER - the Valid bit must be cleared before changing
  * anything else.
  */
-static inline void gits_write_vpendbaser(u64 val, void __iomem *addr)
+static inline void gicr_write_vpendbaser(u64 val, void __iomem *addr)
 {
 	u32 tmp;
 
@@ -352,7 +352,7 @@ static inline void gits_write_vpendbaser(u64 val, void __iomem *addr)
 	__gic_writeq_nonatomic(val, addr);
 }
 
-#define gits_read_vpendbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_read_vpendbaser(c)		__gic_readq_nonatomic(c)
 
 static inline bool gic_prio_masking_enabled(void)
 {
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 4750fc8030c3..25fec4bde43a 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -140,11 +140,11 @@ static inline u32 gic_read_rpr(void)
 #define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
 #define gicr_read_pendbaser(c)		readq_relaxed(c)
 
-#define gits_write_vpropbaser(v, c)	writeq_relaxed(v, c)
-#define gits_read_vpropbaser(c)		readq_relaxed(c)
+#define gicr_write_vpropbaser(v, c)	writeq_relaxed(v, c)
+#define gicr_read_vpropbaser(c)		readq_relaxed(c)
 
-#define gits_write_vpendbaser(v, c)	writeq_relaxed(v, c)
-#define gits_read_vpendbaser(c)		readq_relaxed(c)
+#define gicr_write_vpendbaser(v, c)	writeq_relaxed(v, c)
+#define gicr_read_vpendbaser(c)		readq_relaxed(c)
 
 static inline bool gic_prio_masking_enabled(void)
 {
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 811875bf3abb..1ee95f546cb0 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2429,7 +2429,7 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
 		 * ours wrt CommonLPIAff. Let's use its own VPROPBASER.
 		 * Make sure we don't write the Z bit in that case.
 		 */
-		val = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
+		val = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
 		val &= ~GICR_VPROPBASER_4_1_Z;
 
 		gic_data_rdist()->vpe_l1_base = gic_data_rdist_cpu(cpu)->vpe_l1_base;
@@ -2452,7 +2452,7 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
 	if (!gic_rdists->has_rvpeid)
 		return true;
 
-	val  = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
+	val  = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
 
 	esz  = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val) + 1;
 	gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
@@ -2524,8 +2524,8 @@ static int allocate_vpe_l1_table(void)
 	 * effect of making sure no doorbell will be generated and we can
 	 * then safely clear VPROPBASER.Valid.
 	 */
-	if (gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER) & GICR_VPENDBASER_Valid)
-		gits_write_vpendbaser(GICR_VPENDBASER_PendingLast,
+	if (gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER) & GICR_VPENDBASER_Valid)
+		gicr_write_vpendbaser(GICR_VPENDBASER_PendingLast,
 				      vlpi_base + GICR_VPENDBASER);
 
 	/*
@@ -2548,8 +2548,8 @@ static int allocate_vpe_l1_table(void)
 
 	/* First probe the page size */
 	val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
-	gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
-	val = gits_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
+	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+	val = gicr_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
 	gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
 	esz = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val);
 
@@ -2620,7 +2620,7 @@ static int allocate_vpe_l1_table(void)
 	val |= GICR_VPROPBASER_4_1_VALID;
 
 out:
-	gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 	cpumask_set_cpu(smp_processor_id(), gic_data_rdist()->vpe_table_mask);
 
 	pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
@@ -2727,14 +2727,14 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
 	bool clean;
 	u64 val;
 
-	val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+	val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
 	val &= ~GICR_VPENDBASER_Valid;
 	val &= ~clr;
 	val |= set;
-	gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+	gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 
 	do {
-		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+		val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
 		clean = !(val & GICR_VPENDBASER_Dirty);
 		if (!clean) {
 			count--;
@@ -2849,7 +2849,7 @@ static void its_cpu_init_lpis(void)
 		val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
 		pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n",
 			smp_processor_id(), val);
-		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+		gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 
 		/*
 		 * Also clear Valid bit of GICR_VPENDBASER, in case some
@@ -3523,7 +3523,7 @@ static void its_vpe_schedule(struct its_vpe *vpe)
 	val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
 	val |= GICR_VPROPBASER_RaWb;
 	val |= GICR_VPROPBASER_InnerShareable;
-	gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+	gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 
 	val  = virt_to_phys(page_address(vpe->vpt_page)) &
 		GENMASK_ULL(51, 16);
@@ -3541,7 +3541,7 @@ static void its_vpe_schedule(struct its_vpe *vpe)
 	val |= GICR_VPENDBASER_PendingLast;
 	val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
 	val |= GICR_VPENDBASER_Valid;
-	gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+	gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 }
 
 static void its_vpe_deschedule(struct its_vpe *vpe)
@@ -3741,7 +3741,7 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
 	val |= info->g1en ? GICR_VPENDBASER_4_1_VGRP1EN : 0;
 	val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
 
-	gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+	gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 }
 
 static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
-- 
2.19.1


_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level
  2020-02-06  7:57 ` [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level Zenghui Yu
@ 2020-02-13 14:22   ` Marc Zyngier
  2020-02-13 15:11     ` Zenghui Yu
  0 siblings, 1 reply; 9+ messages in thread
From: Marc Zyngier @ 2020-02-13 14:22 UTC (permalink / raw)
  To: Zenghui Yu; +Cc: jason, linux-kernel, tglx, kvmarm, linux-arm-kernel

Hi Zenghui,

On 2020-02-06 07:57, Zenghui Yu wrote:
> In GICv4, we will ensure that level2 vPE table memory is allocated
> for the specified vpe_id on all v4 ITS, in its_alloc_vpe_table().
> This still works well for the typical GICv4.1 implementation, where
> the new vPE table is shared between the ITSs and the RDs.
> 
> To make it explicit, let us introduce allocate_vpe_l2_table() to
> make sure that the L2 tables are allocated on all v4.1 RDs. We're
> likely not need to allocate memory in it because the vPE table is
> shared and (L2 table is) already allocated at ITS level, except
> for the case where the ITS doesn't share anything (say SVPET == 0,
> practically unlikely but architecturally allowed).
> 
> The implementation of allocate_vpe_l2_table() is mostly copied from
> its_alloc_table_entry().
> 
> Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 80 ++++++++++++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
> b/drivers/irqchip/irq-gic-v3-its.c
> index 0f1fe56ce0af..ae4e7b355b46 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -2443,6 +2443,72 @@ static u64 
> inherit_vpe_l1_table_from_rd(cpumask_t **mask)
>  	return 0;
>  }
> 
> +static bool allocate_vpe_l2_table(int cpu, u32 id)
> +{
> +	void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
> +	u64 val, gpsz, npg;
> +	unsigned int psz, esz, idx;
> +	struct page *page;
> +	__le64 *table;
> +
> +	if (!gic_rdists->has_rvpeid)
> +		return true;
> +
> +	val  = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);

Having rebased the rest of the GICv4.1 series on top of -rc1, I've hit a 
small
issue right here. I run a FVP model that only spawns 4 CPUs, while the 
DT has
8 of them. This means that online_cpus = 4, and possible_cpus = 8.

So in my case, half of the RDs have base == NULL, and things stop 
quickly.

I plan to queue the following:

diff --git a/drivers/irqchip/irq-gic-v3-its.c 
b/drivers/irqchip/irq-gic-v3-its.c
index d85dc8dcb0ad..7656b353a95f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2526,6 +2526,10 @@ static bool allocate_vpe_l2_table(int cpu, u32 
id)
  	if (!gic_rdists->has_rvpeid)
  		return true;

+	/* Skip non-present CPUs */
+	if (!base)
+		return true;
+
  	val  = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);

  	esz  = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val) + 1;


Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level
  2020-02-13 14:22   ` Marc Zyngier
@ 2020-02-13 15:11     ` Zenghui Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Zenghui Yu @ 2020-02-13 15:11 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: jason, linux-kernel, tglx, kvmarm, linux-arm-kernel

Hi Marc,

On 2020/2/13 22:22, Marc Zyngier wrote:
> Hi Zenghui,
> 
> On 2020-02-06 07:57, Zenghui Yu wrote:
>> In GICv4, we will ensure that level2 vPE table memory is allocated
>> for the specified vpe_id on all v4 ITS, in its_alloc_vpe_table().
>> This still works well for the typical GICv4.1 implementation, where
>> the new vPE table is shared between the ITSs and the RDs.
>>
>> To make it explicit, let us introduce allocate_vpe_l2_table() to
>> make sure that the L2 tables are allocated on all v4.1 RDs. We're
>> likely not need to allocate memory in it because the vPE table is
>> shared and (L2 table is) already allocated at ITS level, except
>> for the case where the ITS doesn't share anything (say SVPET == 0,
>> practically unlikely but architecturally allowed).
>>
>> The implementation of allocate_vpe_l2_table() is mostly copied from
>> its_alloc_table_entry().
>>
>> Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c | 80 ++++++++++++++++++++++++++++++++
>>  1 file changed, 80 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
>> b/drivers/irqchip/irq-gic-v3-its.c
>> index 0f1fe56ce0af..ae4e7b355b46 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -2443,6 +2443,72 @@ static u64 
>> inherit_vpe_l1_table_from_rd(cpumask_t **mask)
>>      return 0;
>>  }
>>
>> +static bool allocate_vpe_l2_table(int cpu, u32 id)
>> +{
>> +    void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
>> +    u64 val, gpsz, npg;
>> +    unsigned int psz, esz, idx;
>> +    struct page *page;
>> +    __le64 *table;
>> +
>> +    if (!gic_rdists->has_rvpeid)
>> +        return true;
>> +
>> +    val  = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
> 
> Having rebased the rest of the GICv4.1 series on top of -rc1, I've hit a 
> small
> issue right here. I run a FVP model that only spawns 4 CPUs, while the 
> DT has
> 8 of them. This means that online_cpus = 4, and possible_cpus = 8.
> 
> So in my case, half of the RDs have base == NULL, and things stop quickly.

Ah, so this may also be why we check '!base' for each possible CPU in
inherit_vpe_l1_table_from_rd(). I didn't think about it at that time.

> 
> I plan to queue the following:
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c 
> b/drivers/irqchip/irq-gic-v3-its.c
> index d85dc8dcb0ad..7656b353a95f 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -2526,6 +2526,10 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
>       if (!gic_rdists->has_rvpeid)
>           return true;
> 
> +    /* Skip non-present CPUs */
> +    if (!base)
> +        return true;
> +
>       val  = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
> 
>       esz  = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val) + 1;

Thanks for fixing the second bug for this patch :-)


Zenghui

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-06  7:57 [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1 Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 2/6] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 3/6] irqchip/gic-v4.1: Ensure L2 vPE table is allocated at RD level Zenghui Yu
2020-02-13 14:22   ` Marc Zyngier
2020-02-13 15:11     ` Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 4/6] irqchip/gic-v4.1: Drop 'tmp' in inherit_vpe_l1_table_from_rd() Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 5/6] irqchip/gic-v3-its: Remove superfluous WARN_ON Zenghui Yu
2020-02-06  7:57 ` [PATCH v2 6/6] irqchip/gic-v3-its: Rename VPENDBASER/VPROPBASER accessors Zenghui Yu

KVM ARM Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/kvmarm/0 kvmarm/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kvmarm kvmarm/ https://lore.kernel.org/kvmarm \
		kvmarm@lists.cs.columbia.edu
	public-inbox-index kvmarm

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/edu.columbia.cs.lists.kvmarm


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git