aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCédric Le Goater <clg@kaod.org>2019-11-15 17:24:14 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-12-17 10:39:47 +1100
commit516883c2f15bdd844543be218155898d06953c90 (patch)
tree9d913306625dcdce1555674dd5d456ddd4f58b09
parent95bd61c4dfc4c08d4248071f2f70d9c2afacc0d1 (diff)
downloadqemu-516883c2f15bdd844543be218155898d06953c90.zip
qemu-516883c2f15bdd844543be218155898d06953c90.tar.gz
qemu-516883c2f15bdd844543be218155898d06953c90.tar.bz2
ppc/xive: Record the IPB in the associated NVT
When an interrupt can not be presented to a vCPU, because it is not running on any of the HW treads, the XIVE presenter updates the Interrupt Pending Buffer register of the associated XIVE NVT structure. This is only done if backlog is activated in the END but this is generally the case. The current code assumes that the fields of the NVT structure is architected with the same layout of the thread interrupt context registers. Fix this assumption and define an offset for the IPB register backup value in the NVT. Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191115162436.30548-2-clg@kaod.org> Reviewed-by: Greg Kurz <groug@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--hw/intc/xive.c11
-rw-r--r--include/hw/ppc/xive_regs.h1
2 files changed, 10 insertions, 2 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 3d472e2..177663d 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1607,14 +1607,21 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
* - logical server : forward request to IVPE (not supported)
*/
if (xive_end_is_backlog(&end)) {
+ uint8_t ipb;
+
if (format == 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"XIVE: END %x/%x invalid config: F1 & backlog\n",
end_blk, end_idx);
return;
}
- /* Record the IPB in the associated NVT structure */
- ipb_update((uint8_t *) &nvt.w4, priority);
+ /*
+ * Record the IPB in the associated NVT structure for later
+ * use. The presenter will resend the interrupt when the vCPU
+ * is dispatched again on a HW thread.
+ */
+ ipb = xive_get_field32(NVT_W4_IPB, nvt.w4) | priority_to_ipb(priority);
+ nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, ipb);
xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
/*
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 55307cd..530f232 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -255,6 +255,7 @@ typedef struct XiveNVT {
uint32_t w2;
uint32_t w3;
uint32_t w4;
+#define NVT_W4_IPB PPC_BITMASK32(16, 23)
uint32_t w5;
uint32_t w6;
uint32_t w7;