mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: gic-v3: Wait for redistributor RWP using the right bit
gicv3_do_wait_for_rwp() is used for both distributor and redistributor writes. The CTLR register is at offset 0 for both, but the RWP bit is not in the same position. For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP, while RWP is bit 3. The redistributor wait path was therefore polling UWP instead of RWP. UWP covers upstream writes, including Generate SGI packets, and is not a substitute for redistributor register write completion. The existing redistributor callers need RWP semantics for redistributor register writes such as GICR_ICENABLER0 and GICR_CTLR updates. Add GICR_CTLR_RWP and pass the expected RWP bit to the shared helper. Fixes:bc183a0235("xen/arm: Add support for GIC v3") Reported-by: Luca Fancellu <luca.fancellu@arm.com> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com> Reviewed-by: Luca Fancellu <luca.fancellu@arm.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org> (cherry picked from commitd86cf3cbd4)
This commit is contained in:
1 parent
9b88e852ef
commit
4f3dbd9ee0
2 files changed
+10
-5
No files matched your search
@@ -274,16 +274,20 @@ static void gicv3_enable_sre(void)
|
||||
isb();
|
||||
}
|
||||
|
||||
/* Wait for completion of a distributor change */
|
||||
static void gicv3_do_wait_for_rwp(void __iomem *base)
|
||||
/* Wait for completion of a distributor/redistributor change */
|
||||
static void gicv3_do_wait_for_rwp(void __iomem *base, uint32_t rwp_bit)
|
||||
{
|
||||
uint32_t val;
|
||||
bool timeout = false;
|
||||
s_time_t deadline = NOW() + MILLISECS(1000);
|
||||
|
||||
do {
|
||||
/*
|
||||
* GICD_CTLR and GICR_CTLR are both at offset 0, so this is
|
||||
* valid for either a distributor or redistributor base.
|
||||
*/
|
||||
val = readl_relaxed(base + GICD_CTLR);
|
||||
if ( !(val & GICD_CTLR_RWP) )
|
||||
if ( !(val & rwp_bit) )
|
||||
break;
|
||||
if ( NOW() > deadline )
|
||||
{
|
||||
@@ -300,12 +304,12 @@ static void gicv3_do_wait_for_rwp(void __iomem *base)
|
||||
|
||||
static void gicv3_dist_wait_for_rwp(void)
|
||||
{
|
||||
gicv3_do_wait_for_rwp(GICD);
|
||||
gicv3_do_wait_for_rwp(GICD, GICD_CTLR_RWP);
|
||||
}
|
||||
|
||||
static void gicv3_redist_wait_for_rwp(void)
|
||||
{
|
||||
gicv3_do_wait_for_rwp(GICD_RDIST_BASE);
|
||||
gicv3_do_wait_for_rwp(GICD_RDIST_BASE, GICR_CTLR_RWP);
|
||||
}
|
||||
|
||||
static void gicv3_wait_for_rwp(int irq)
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
#define GICR_NSACR (0x0E00)
|
||||
|
||||
#define GICR_CTLR_ENABLE_LPIS (1U << 0)
|
||||
#define GICR_CTLR_RWP (1U << 3)
|
||||
|
||||
#define GICR_TYPER_PLPIS (1U << 0)
|
||||
#define GICR_TYPER_VLPIS (1U << 1)
|
||||
|
||||