@@ -74,33 +74,49 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
if (regs[TM_NSR] & mask) {
uint8_t cppr = regs[TM_PIPR];
+ uint8_t alt_ring;
+ uint8_t *alt_regs;
+
+ /* POOL interrupt uses IPB in QW2, POOL ring */
+ if ((ring == TM_QW3_HV_PHYS) && (nsr & (TM_QW3_NSR_HE_POOL << 6))) {
+ alt_ring = TM_QW2_HV_POOL;
+ } else {
+ alt_ring = ring;
+ }
+ alt_regs = &tctx->regs[alt_ring];
regs[TM_CPPR] = cppr;
/* Reset the pending buffer bit */
- regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
- regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+ alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
+ regs[TM_PIPR] = ipb_to_pipr(alt_regs[TM_IPB]);
/* Drop Exception bit */
regs[TM_NSR] &= ~mask;
- trace_xive_tctx_accept(tctx->cs->cpu_index, ring,
- regs[TM_IPB], regs[TM_PIPR],
+ trace_xive_tctx_accept(tctx->cs->cpu_index, alt_ring,
+ alt_regs[TM_IPB], regs[TM_PIPR],
regs[TM_CPPR], regs[TM_NSR]);
}
- return (nsr << 8) | regs[TM_CPPR];
+ return ((uint64_t)nsr << 8) | regs[TM_CPPR];
}
static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
{
+ /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */
+ uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring;
+ uint8_t *alt_regs = &tctx->regs[alt_ring];
uint8_t *regs = &tctx->regs[ring];
- if (regs[TM_PIPR] < regs[TM_CPPR]) {
+ if (alt_regs[TM_PIPR] < alt_regs[TM_CPPR]) {
switch (ring) {
case TM_QW1_OS:
regs[TM_NSR] |= TM_QW1_NSR_EO;
break;
+ case TM_QW2_HV_POOL:
+ alt_regs[TM_NSR] = (TM_QW3_NSR_HE_POOL << 6);
+ break;
case TM_QW3_HV_PHYS:
regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6);
break;
@@ -108,8 +124,8 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
g_assert_not_reached();
}
trace_xive_tctx_notify(tctx->cs->cpu_index, ring,
- regs[TM_IPB], regs[TM_PIPR],
- regs[TM_CPPR], regs[TM_NSR]);
+ regs[TM_IPB], alt_regs[TM_PIPR],
+ alt_regs[TM_CPPR], alt_regs[TM_NSR]);
qemu_irq_raise(xive_tctx_output(tctx, ring));
}
}
@@ -217,14 +233,14 @@ static uint64_t xive_tm_vt_poll(XivePresenter *xptr, XiveTCTX *tctx,
static const uint8_t xive_tm_hw_view[] = {
3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-0 User */
3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-1 OS */
- 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
+ 0, 0, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
3, 3, 3, 3, 0, 3, 0, 2, 3, 0, 0, 3, 3, 3, 3, 0, /* QW-3 PHYS */
};
static const uint8_t xive_tm_hv_view[] = {
3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-0 User */
3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-1 OS */
- 0, 0, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
+ 0, 0, 3, 3, 0, 3, 3, 0, 0, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
3, 3, 3, 3, 0, 3, 0, 2, 3, 0, 0, 3, 0, 0, 0, 0, /* QW-3 PHYS */
};