aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2016-11-14 13:06:11 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-11-15 15:06:02 +1100
commita2474ecbdea969569a069ec95918626cfdaf3fcc (patch)
tree628fe6dd174a882e155ee074edfc8b18b688d317 /hw
parent6873a5c71b00b0ed3d358b92ed5c235fcf592cac (diff)
downloadskiboot-a2474ecbdea969569a069ec95918626cfdaf3fcc.zip
skiboot-a2474ecbdea969569a069ec95918626cfdaf3fcc.tar.gz
skiboot-a2474ecbdea969569a069ec95918626cfdaf3fcc.tar.bz2
xive: Fix comments in xive_source_set_xive()
Properly documenting assumptions and behaviour related to interrupts occurring while masked. This reflects the documentation update. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xive.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/hw/xive.c b/hw/xive.c
index 3759049..33c8fe2 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -1525,6 +1525,21 @@ static int64_t xive_source_set_xive(struct irq_source *is, uint32_t isn,
uint32_t idx = isn - s->esb_base;
void *mmio_base;
+ /*
+ * WARNING: There is an inherent race with the use of the
+ * mask bit in the EAS/IVT. When masked, interrupts are "lost"
+ * but their P/Q bits are still set. So when unmasking, one has
+ * to check the P bit and possibly trigger a resend.
+ *
+ * We "deal" with it by relying on the fact that the OS will
+ * lazy disable MSIs. Thus mask will only be called if the
+ * interrupt occurred while already logically masked. Thus
+ * losing subsequent occurrences is of no consequences, we just
+ * need to "cleanup" P and Q when unmasking.
+ *
+ * This needs to be documented in the OPAL APIs
+ */
+
/* Unmangle server */
server >>= 2;
@@ -1532,12 +1547,7 @@ static int64_t xive_source_set_xive(struct irq_source *is, uint32_t isn,
if (!xive_set_eq_info(isn, server, prio))
return OPAL_PARAMETER;
- /* Ensure it's enabled/disabled in the source controller.
- *
- * This won't do much for LSIs but will work for MSIs and will
- * ensure that a stray P bit left over won't block further
- * interrupts when enabling
- */
+ /* Ensure it's enabled/disabled in the source controller */
mmio_base = s->esb_mmio + (1ul << s->esb_shift) * idx;
if (s->flags & XIVE_SRC_EOI_PAGE1)
mmio_base += 1ull << (s->esb_shift - 1);