Message ID | 20240909211038.27440-12-kowal@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | XIVE2 changes for TIMA operations | expand |
On 9/9/24 23:10, Michael Kowal wrote: > From: Glenn Miles <milesg@linux.vnet.ibm.com> > > Hypervisor "pool" targets do not get their own interrupt line and instead > must share an interrupt line with the hypervisor "physical" targets. > This also means that the pool ring must use some of the registers from the > physical ring in the TIMA. Specifically, the NSR, PIPR and CPPR registers: > > NSR = Notification Source Register > PIPR = Post Interrupt Priority Register > CPPR = Current Processor Priority Register > > The NSR specifies that there is an active interrupt. The CPPR > specifies the priority of the context and the PIPR specifies the > priority of the interrupt. For an interrupt to be presented to > a context, the priority of the interrupt must be higher than the > priority of the context it is interrupting (value must be lower). > > The existing code was not aware of the sharing of these registers. > This commit adds that support. > > Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com> > Signed-off-by: Michael Kowal <kowal@linux.ibm.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Thanks, C. > --- > hw/intc/xive.c | 36 ++++++++++++++++++++++++++---------- > 1 file changed, 26 insertions(+), 10 deletions(-) > > diff --git a/hw/intc/xive.c b/hw/intc/xive.c > index 9d85da0999..5c5c3a2dd6 100644 > --- a/hw/intc/xive.c > +++ b/hw/intc/xive.c > @@ -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 */ > }; >
diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 9d85da0999..5c5c3a2dd6 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -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 */ };