[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