2020-02-06 08:09:23

by Zenghui Yu

[permalink] [raw]
Subject: [PATCH v2 0/6] irqchip/gic-v4.1: Cleanup and fixes for GICv4.1

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



2020-02-06 08:10:12

by Zenghui Yu

[permalink] [raw]
Subject: [PATCH v2 1/6] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE

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 <[email protected]>
---
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


2020-02-06 08:10:37

by Zenghui Yu

[permalink] [raw]
Subject: [PATCH v2 5/6] irqchip/gic-v3-its: Remove superfluous WARN_ON

"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 <[email protected]>
---
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


2020-02-06 08:52:40

by Zenghui Yu

[permalink] [raw]
Subject: [PATCH v2 2/6] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors

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 <[email protected]>
---
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


Subject: [tip: irq/urgent] irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE

The following commit has been merged into the irq/urgent branch of tip:

Commit-ID: e88bd316e5971fe78884ad1f466b9fc576575e5f
Gitweb: https://git.kernel.org/tip/e88bd316e5971fe78884ad1f466b9fc576575e5f
Author: Zenghui Yu <[email protected]>
AuthorDate: Thu, 06 Feb 2020 15:57:06 +08:00
Committer: Marc Zyngier <[email protected]>
CommitterDate: Sat, 08 Feb 2020 10:01:33

irqchip/gic-v4.1: Fix programming of GICR_VPROPBASER_4_1_SIZE

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 <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
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 e5a25d9..992bc72 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);

Subject: [tip: irq/urgent] irqchip/gic-v4.1: Set vpe_l1_base for all redistributors

The following commit has been merged into the irq/urgent branch of tip:

Commit-ID: 8b718d403c5cdc7f0ea492c33ec88169f3e76462
Gitweb: https://git.kernel.org/tip/8b718d403c5cdc7f0ea492c33ec88169f3e76462
Author: Zenghui Yu <[email protected]>
AuthorDate: Thu, 06 Feb 2020 15:57:07 +08:00
Committer: Marc Zyngier <[email protected]>
CommitterDate: Sat, 08 Feb 2020 10:01:33

irqchip/gic-v4.1: Set vpe_l1_base for all redistributors

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 <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
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 992bc72..0f1fe56 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 f0b8ca7..83439bf 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;

Subject: [tip: irq/urgent] irqchip/gic-v3-its: Remove superfluous WARN_ON

The following commit has been merged into the irq/urgent branch of tip:

Commit-ID: b46353250ba3b4946adcbbabead23546fcb758b0
Gitweb: https://git.kernel.org/tip/b46353250ba3b4946adcbbabead23546fcb758b0
Author: Zenghui Yu <[email protected]>
AuthorDate: Thu, 06 Feb 2020 15:57:10 +08:00
Committer: Marc Zyngier <[email protected]>
CommitterDate: Sat, 08 Feb 2020 10:01:33

irqchip/gic-v3-its: Remove superfluous WARN_ON

"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 <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
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 8405ebd..811875b 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()) {