[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250918141557.1791041-1-tangnianyao@huawei.com>
Date: Thu, 18 Sep 2025 22:15:57 +0800
From: Nianyao Tang <tangnianyao@...wei.com>
To: <maz@...nel.org>, <tglx@...utronix.de>,
<linux-arm-kernel@...ts.infradead.org>, <linux-kernel@...r.kernel.org>
CC: <guoyang2@...wei.com>, <wangwudi@...ilicon.com>, <tangnianyao@...wei.com>,
<wangzhou1@...ilicon.com>, <jiangkunkun@...wei.com>,
<guozicheng3@...ilicon.com>
Subject: [PATCH V2] irqchip/gic-v4.1:Check whether indirect table is supported in allocate_vpe_l1_table
In allocate_vpe_l1_table, it allocates a new vpe table without checking
whether indirect table is supported.
ARM allows vendors to support only flat tables. Let's first check if
indirect tables are supported before using it.
Signed-off-by: Nianyao Tang <tangnianyao@...wei.com>
---
drivers/irqchip/irq-gic-v3-its.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 467cb78435a9..a4d719720e61 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2903,6 +2903,7 @@ static int allocate_vpe_l1_table(void)
unsigned int psz = SZ_64K;
unsigned int np, epp, esz;
struct page *page;
+ bool indirect;
if (!gic_rdists->has_rvpeid)
return 0;
@@ -2937,10 +2938,12 @@ 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);
+ val |= GICR_VPROPBASER_4_1_INDIRECT;
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);
+ indirect = !!(val & GICR_VPROPBASER_4_1_INDIRECT);
switch (gpsz) {
default:
@@ -2973,7 +2976,7 @@ static int allocate_vpe_l1_table(void)
* If we need more than just a single L1 page, flag the table
* as indirect and compute the number of required L1 pages.
*/
- if (epp < ITS_MAX_VPEID) {
+ if (epp < ITS_MAX_VPEID && indirect) {
int nl2;
val |= GICR_VPROPBASER_4_1_INDIRECT;
@@ -2984,7 +2987,8 @@ static int allocate_vpe_l1_table(void)
/* Number of L1 pages to point to the L2 pages */
npg = DIV_ROUND_UP(nl2 * SZ_8, psz);
} else {
- npg = 1;
+ npg = DIV_ROUND_UP(ITS_MAX_VPEID, epp);
+ npg = clamp_val(npg, 1, (GICR_VPROPBASER_4_1_SIZE + 1));
}
val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg - 1);
--
2.33.0
Powered by blists - more mailing lists