[Skiboot] [PATCH 60/60] xive: Fix logic in opal_xive_get_xirr()
Benjamin Herrenschmidt
benh at kernel.crashing.org
Thu Dec 22 14:17:08 AEDT 2016
If we got a spurrious interrupt it would fail to bring the CPPR
back properly. Fix the logic to always adjust the CPPR and to
handle the absence of an interrupt correctly.
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
hw/xive.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/hw/xive.c b/hw/xive.c
index 9e80540..f558809 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -3046,6 +3046,10 @@ static int64_t opal_xive_get_xirr(uint32_t *out_xirr, bool just_poll)
* something in the queue, we must also raise CPPR back.
*/
+ xive_cpu_vdbg(c, "get_xirr W01=%016llx W2=%08x\n",
+ __in_be64(xs->tm_ring1 + TM_QW3_HV_PHYS),
+ __in_be32(xs->tm_ring1 + TM_QW3_HV_PHYS + 8));
+
/* Perform the HV Ack cycle */
if (just_poll)
ack = __in_be64(xs->tm_ring1 + TM_QW3_HV_PHYS) >> 48;
@@ -3103,23 +3107,23 @@ static int64_t opal_xive_get_xirr(uint32_t *out_xirr, bool just_poll)
*/
xs->pending &= ~(1 << prio);
- /* There should always be an interrupt here I think, unless
- * some race occurred, but let's be safe. If we don't find
- * anything, we just return.
- */
+ /* Spurrious IPB bit, nothing to fetch, bring CPPR back */
if (!val)
- goto skip;
-
- xive_cpu_vdbg(c, " found irq, prio=%d\n", prio);
+ prio = old_cppr;
/* We could have fetched a pending interrupt left over
* by a previous EOI, so the CPPR might need adjusting
+ * Also if we had a spurrious one as well.
*/
- if (xs->cppr > prio) {
+ if (xs->cppr != prio) {
xs->cppr = prio;
out_8(xs->tm_ring1 + TM_QW3_HV_PHYS + TM_CPPR, prio);
- xive_cpu_vdbg(c, " adjusted CPPR\n");
+ xive_cpu_vdbg(c, " adjusted CPPR to %d\n", prio);
}
+
+ if (val)
+ xive_cpu_vdbg(c, " found irq, prio=%d\n", prio);
+
}
skip:
--
2.9.3
More information about the Skiboot
mailing list