[Skiboot] [PATCH 2/6] xive: When disabling an EQ, wipe all of its settings

Benjamin Herrenschmidt benh at kernel.crashing.org
Tue Nov 21 14:48:23 AEDT 2017


This avoids having configuration bits left over

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 doc/xive.rst |  10 ++++--
 hw/xive.c    | 101 ++++++++++++++++++++++++++++++-----------------------------
 2 files changed, 58 insertions(+), 53 deletions(-)

diff --git a/doc/xive.rst b/doc/xive.rst
index c4f49501..85fe1119 100644
--- a/doc/xive.rst
+++ b/doc/xive.rst
@@ -565,14 +565,18 @@ and priority and adjust the behaviour of the queue via flags.
   .. note:: This call will reset the generation bit to 1 and the queue
 	    production pointer to 0.
 
-  .. note:: The PQ bits of the escalation interrupts will be set to 00
-	    when OPAL_XIVE_EQ_ENABLED is set, and to 01 (masked) when
-	    disabling it.
+  .. note:: The PQ bits of the escalation interrupts and of the queue
+            notification will be set to 00 when OPAL_XIVE_EQ_ENABLED is
+	    set, and to 01 (masked) when disabling it.
 
   .. note:: This must be called at least once on a queue with the flag
 	    OPAL_XIVE_EQ_ENABLED in order to enable it after it has been
 	    allocated (along with its owner VP).
 
+  .. note:: When the queue is disabled (flag OPAL_XIVE_EQ_ENABLED cleared)
+	    all other flags and arguments are ignored and the queue
+	    configuration is wiped.
+
 OPAL_XIVE_DONATE_PAGE
 ^^^^^^^^^^^^^^^^^^^^^
 .. code-block:: c
diff --git a/hw/xive.c b/hw/xive.c
index df38074d..2f1ad578 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -3983,61 +3983,62 @@ static int64_t opal_xive_set_queue_info(uint64_t vp, uint32_t prio,
 	 */
 	eq = *old_eq;
 
-	switch(qsize) {
-		/* Supported sizes */
-	case 12:
-	case 16:
-	case 21:
-	case 24:
-		eq.w3 = ((uint64_t)qpage) & 0xffffffff;
-		eq.w2 = (((uint64_t)qpage)) >> 32 & 0x0fffffff;
-		eq.w0 |= EQ_W0_ENQUEUE;
-		eq.w0 = SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12);
-		break;
-	case 0:
-		eq.w2 = eq.w3 = 0;
-		eq.w0 &= ~EQ_W0_ENQUEUE;
-		break;
-	default:
-		return OPAL_PARAMETER;
-	}
-
-	/* Ensure the priority and target are correctly set (they will
-	 * not be right after allocation
-	 */
-	eq.w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, vp_blk) |
-		SETFIELD(EQ_W6_NVT_INDEX, 0ul, vp_idx);
-	eq.w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, prio);
-	/* XXX Handle group i bit when needed */
+	if (qflags & OPAL_XIVE_EQ_ENABLED) {
+		switch(qsize) {
+			/* Supported sizes */
+		case 12:
+		case 16:
+		case 21:
+		case 24:
+			eq.w3 = ((uint64_t)qpage) & 0xffffffff;
+			eq.w2 = (((uint64_t)qpage)) >> 32 & 0x0fffffff;
+			eq.w0 |= EQ_W0_ENQUEUE;
+			eq.w0 = SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12);
+			break;
+		case 0:
+			eq.w2 = eq.w3 = 0;
+			eq.w0 &= ~EQ_W0_ENQUEUE;
+			break;
+		default:
+			return OPAL_PARAMETER;
+		}
 
-	/* Always notify flag */
-	if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
-		eq.w0 |= EQ_W0_UCOND_NOTIFY;
-	else
-		eq.w0 &= ~EQ_W0_UCOND_NOTIFY;
+		/* Ensure the priority and target are correctly set (they will
+		 * not be right after allocation
+		 */
+		eq.w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, vp_blk) |
+			SETFIELD(EQ_W6_NVT_INDEX, 0ul, vp_idx);
+		eq.w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, prio);
+		/* XXX Handle group i bit when needed */
+
+		/* Always notify flag */
+		if (qflags & OPAL_XIVE_EQ_ALWAYS_NOTIFY)
+			eq.w0 |= EQ_W0_UCOND_NOTIFY;
+		else
+			eq.w0 &= ~EQ_W0_UCOND_NOTIFY;
 
-	/* Escalation flag */
-	if (qflags & OPAL_XIVE_EQ_ESCALATE)
-		eq.w0 |= EQ_W0_ESCALATE_CTL;
-	else
-		eq.w0 &= ~EQ_W0_ESCALATE_CTL;
+		/* Escalation flag */
+		if (qflags & OPAL_XIVE_EQ_ESCALATE)
+			eq.w0 |= EQ_W0_ESCALATE_CTL;
+		else
+			eq.w0 &= ~EQ_W0_ESCALATE_CTL;
 
-	/* Unconditionally clear the current queue pointer, set
-	 * generation to 1 and disable escalation interrupts.
-	 */
-	eq.w1 = EQ_W1_GENERATION |
-		(old_eq->w1 & (EQ_W1_ESe_P | EQ_W1_ESe_Q |
-			       EQ_W1_ESn_P | EQ_W1_ESn_Q));
+		/* Unconditionally clear the current queue pointer, set
+		 * generation to 1 and disable escalation interrupts.
+		 */
+		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
-	 * enabled queue otherwise escalations won't work.
-	 */
-	if (qflags & OPAL_XIVE_EQ_ENABLED)
+		/* Enable. We always enable backlog for an enabled queue
+		 * otherwise escalations won't work.
+		 */
 		eq.w0 |= EQ_W0_VALID | EQ_W0_BACKLOG;
-	else {
-		eq.w0 &= ~EQ_W0_VALID;
-		eq.w1 &= ~(EQ_W1_ESe_P | EQ_W1_ESn_P);
-		eq.w1 |= EQ_W1_ESe_Q | EQ_W1_ESn_Q;
+	} else {
+		/* Clear everything and set PQ bits to 01 */
+		eq.w0 = old_eq->w0 & EQ_W0_FIRMWARE;
+		eq.w1 = EQ_W1_ESe_Q | EQ_W1_ESn_Q;
+		eq.w2 = eq.w3 = eq.w4 = eq.w5 = eq.w6 = eq.w7 = 0;
 	}
 
 	/* Update EQ, non-synchronous */
-- 
2.14.3



More information about the Skiboot mailing list