[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1548071508-11846-1-git-send-email-guoheyi@huawei.com>
Date: Mon, 21 Jan 2019 19:51:48 +0800
From: Heyi Guo <guoheyi@...wei.com>
To: <linux-kernel@...r.kernel.org>
CC: Thomas Gleixner <tglx@...utronix.de>,
Jason Cooper <jason@...edaemon.net>,
Marc Zyngier <marc.zyngier@....com>,
<wanghaibin.wang@...wei.com>
Subject: [RFC] irq-gic-v3-its: fix occasional VLPI drop
Every VLPI will temporarily be mapped to the first CPU in system
(normally CPU0) and then moved to the real scheduled CPU later. There
is a time window so a VLPI may be sent to CPU0 instead of the real
scheduled vCPU, in a multi-CPU virtual machine. However, CPU0 may have
not been scheduled as a virtual CPU after system boots up, so the
value of GICR_VPROPBASER still be the reset value. According to GIC
spec, the reset value of IDbits in GICR_VPROPBASER is architecturally
UNKNOWN, and the GIC will behave as if all virtual LPIs are out of
range if it is less than 0b1101. On our platform the GICR will simply
drop the incoming VLPI, which results in interrupt missing in Guest.
As no code will clear GICR_VPROPBASER at runtime, we can safely
initialize the IDbits field at boot time for each CPU to get rid of
this issue.
Signed-off-by: Heyi Guo <guoheyi@...wei.com>
Signed-off-by: Heyi Guo <heyi.guo@...aro.org>
---
drivers/irqchip/irq-gic-v3-its.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index db20e99..6116215 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2144,6 +2144,20 @@ static void its_cpu_init_lpis(void)
val |= GICR_CTLR_ENABLE_LPIS;
writel_relaxed(val, rbase + GICR_CTLR);
+ /*
+ * Temporary workaround for vlpi drop on Hi1620.
+ * IDbits must be set before any VLPI is sent to this CPU, or else the
+ * VLPI will be considered as out of range and dropped.
+ */
+ if (gic_rdists->has_vlpis) {
+ void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
+
+ val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
+ pr_info("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n",
+ smp_processor_id(), val);
+ gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+ }
+
/* Make sure the GIC has seen the above */
dsb(sy);
out:
--
1.8.3.1
Powered by blists - more mailing lists