[Skiboot] [PATCH 09/11] xive: Always reset queue state in opal_xive_set_queue_info()

Benjamin Herrenschmidt benh at kernel.crashing.org
Wed Mar 15 20:58:58 AEDT 2017


We used to require an enable/disable transition, however that doesn't
work well with how KVM does "upgrade" a queue so instead just always
reset the queue state (queue pointer and generation) whenever a queue
is reconfigured. Escalations are reset to "masked" when the queue
is disabled.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 hw/xive.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/hw/xive.c b/hw/xive.c
index dc5f279..67c0126 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -3599,16 +3599,22 @@ static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio,
 	if (qflags & OPAL_XIVE_EQ_ESCALATE)
 		eq.w0 |= EQ_W0_ESCALATE_CTL;
 
-	/* Check enable transition. On any transition we clear PQ,
-	 * set the generation bit, clear the offset and mask the
-	 * escalation interrupt
+	/* Unconditionally clear the current queue pointer, set
+	 * generation to 1 and disable escalation interrupts.
 	 */
-	if ((qflags & OPAL_XIVE_EQ_ENABLED) && !(eq.w0 & EQ_W0_VALID)) {
+	eq.w1 = EQ_W1_GENERATION |
+		(old_eq->w1 & (EQ_W1_ESe_P | EQ_W1_ESe_Q |
+			       EQ_W1_ESn_P | EQ_W1_ESn_Q));
+
+	/* Enable or disable. We always enable backlog for an
+	 * enable queue otherwise escalations won't work.
+	 */
+	if (qflags & OPAL_XIVE_EQ_ENABLED)
 		eq.w0 |= EQ_W0_VALID | EQ_W0_BACKLOG;
-		eq.w1 = EQ_W1_GENERATION | EQ_W1_ESe_Q;
-	} else if (!(qflags & OPAL_XIVE_EQ_ENABLED)) {
+	else {
 		eq.w0 &= ~EQ_W0_VALID;
-		eq.w1 = EQ_W1_GENERATION | EQ_W1_ESe_Q;
+		eq.w1 &= ~(EQ_W1_ESe_P | EQ_W1_ESn_P);
+		eq.w1 |= EQ_W1_ESe_Q | EQ_W1_ESn_Q;
 	}
 
 	/* Update EQ, non-synchronous */
-- 
2.9.3



More information about the Skiboot mailing list