[Skiboot] [PATCH 51/60] xive: Don't touch ESB masks unless masking/unmasking
Benjamin Herrenschmidt
benh at kernel.crashing.org
Thu Dec 22 14:16:59 AEDT 2016
Otherwise this can have the side effect of losing a queued
interrupt.
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
hw/xive.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/hw/xive.c b/hw/xive.c
index 1f67c2d..81d5ee2 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -2296,6 +2296,7 @@ static int64_t xive_source_set_xive(struct irq_source *is, uint32_t isn,
uint16_t server, uint8_t prio)
{
struct xive_src *s = container_of(is, struct xive_src, is);
+ uint8_t old_prio;
int64_t rc;
/*
@@ -2316,18 +2317,24 @@ static int64_t xive_source_set_xive(struct irq_source *is, uint32_t isn,
/* Unmangle server */
server >>= 2;
+ /* Grab existing prio/mask */
+ if (!xive_get_irq_targetting(isn, NULL, &old_prio, NULL))
+ return OPAL_PARAMETER;
+
/* Let XIVE configure the EQ synchronously */
rc = xive_set_irq_targetting(isn, server, prio, isn, true);
if (rc)
return rc;
/* The source has special variants of masking/unmasking */
- if (s->orig_ops && s->orig_ops->set_xive)
- rc = s->orig_ops->set_xive(is, isn, server, prio);
- else
- /* Ensure it's enabled/disabled in the source controller */
- xive_update_irq_mask(s, isn - s->esb_base, prio == 0xff);
-
+ if (old_prio != prio && (old_prio == 0xff || prio == 0xff)) {
+ if (s->orig_ops && s->orig_ops->set_xive)
+ rc = s->orig_ops->set_xive(is, isn, server, prio);
+ else
+ /* Ensure it's enabled/disabled in the source controller */
+ xive_update_irq_mask(s, isn - s->esb_base,
+ prio == 0xff);
+ }
return OPAL_SUCCESS;
}
--
2.9.3
More information about the Skiboot
mailing list