diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2017-03-15 20:58:58 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-03-16 17:18:01 +1100 |
commit | d801ff7ff17faa94cb02b10d532130c57db8f70c (patch) | |
tree | 15a1f1f28a6c00186dd8fe27bd1e23390543caad /hw | |
parent | 4010f5eb8cf02e78376f5cc91a13b24f0874c7df (diff) | |
download | skiboot-d801ff7ff17faa94cb02b10d532130c57db8f70c.zip skiboot-d801ff7ff17faa94cb02b10d532130c57db8f70c.tar.gz skiboot-d801ff7ff17faa94cb02b10d532130c57db8f70c.tar.bz2 |
xive: Always reset queue state in opal_xive_set_queue_info()
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@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xive.c | 20 |
1 files changed, 13 insertions, 7 deletions
@@ -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 */ |