[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 11/17] ppc/xive: Synthesize interrupt from the sa
From: |
Cédric Le Goater |
Subject: |
[Qemu-devel] [PATCH v2 11/17] ppc/xive: Synthesize interrupt from the saved IPB in the NVT |
Date: |
Thu, 18 Jul 2019 13:54:14 +0200 |
When an interrupt can not be presented to a vCPU, the XIVE presenter
updates the Interrupt Pending Buffer of the XIVE NVT if backlog is
activated in the END.
Later, when the same vCPU is dispatched, its context is pushed in the
thread context registers and the VO bit is set in the CAM line word to
activate the context. The HW grabs the associated NVT to pull the
pending bits, and merges them with the IPB of the TIMA. If interrupts
were missed while the vCPU was not dispatched, these are synthesized
in this sequence.
Signed-off-by: Cédric Le Goater <address@hidden>
---
include/hw/ppc/xive.h | 5 ---
include/hw/ppc/xive_regs.h | 22 ++++++++++++
hw/intc/xive.c | 68 +++++++++++++++++++++++++++++++++-----
3 files changed, 82 insertions(+), 13 deletions(-)
diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index 51e3c37b7483..251a8f2de10e 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -420,11 +420,6 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor
*mon);
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb);
-static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
-{
- return (nvt_blk << 19) | nvt_idx;
-}
-
/*
* KVM XIVE device helpers
*/
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 3fdf1a83b9b6..92ff80d25456 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -232,6 +232,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;
@@ -248,4 +249,25 @@ typedef struct XiveNVT {
#define xive_nvt_is_valid(nvt) (be32_to_cpu((nvt)->w0) & NVT_W0_VALID)
+/*
+ * The VP number space in a block is defined by the END_W6_NVT_INDEX
+ * field of the XIVE END
+ */
+#define XIVE_NVT_SHIFT 19
+
+static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
+{
+ return (nvt_blk << XIVE_NVT_SHIFT) | nvt_idx;
+}
+
+static inline uint32_t xive_nvt_idx(uint32_t cam_line)
+{
+ return cam_line & ((1 << XIVE_NVT_SHIFT) - 1);
+}
+
+static inline uint32_t xive_nvt_blk(uint32_t cam_line)
+{
+ return (cam_line >> XIVE_NVT_SHIFT) & 0xf;
+}
+
#endif /* PPC_XIVE_REGS_H */
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index be66b1fb3261..bcb22ad7e69a 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -44,12 +44,6 @@ static uint8_t ipb_to_pipr(uint8_t ibp)
return ibp ? clz32((uint32_t)ibp << 24) : 0xff;
}
-static void ipb_update(uint8_t *regs, uint8_t priority)
-{
- regs[TM_IPB] |= priority_to_ipb(priority);
- regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
-}
-
static uint8_t exception_mask(uint8_t ring)
{
switch (ring) {
@@ -353,6 +347,56 @@ static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr
offset,
return qw1w2;
}
+static void xive_tctx_need_resend(XiveTCTX *tctx, uint8_t nvt_blk,
+ uint32_t nvt_idx)
+{
+ XiveNVT nvt;
+ uint8_t ipb;
+ XiveRouter *xrtr = XIVE_ROUTER(tctx->xrtr);
+
+ /*
+ * Grab the associated NVT to pull the pending bits, and merge
+ * them with the IPB of the thread interrupt context registers
+ */
+ if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVT %x/%x\n",
+ nvt_blk, nvt_idx);
+ return;
+ }
+
+ ipb = xive_get_field32(NVT_W4_IPB, nvt.w4);
+
+ if (ipb) {
+ /* Reset the NVT value */
+ nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, 0);
+ xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4);
+
+ /* Merge in current context */
+ xive_tctx_ipb_update(tctx, TM_QW1_OS, ipb);
+ }
+}
+
+/*
+ * Updating the OS CAM line can trigger a resend of interrupt
+ */
+static void xive_tm_push_os_ctx(XiveTCTX *tctx, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ uint32_t qw1w2 = value;
+ uint8_t nvt_blk = xive_nvt_blk(qw1w2);
+ uint32_t nvt_idx = xive_nvt_idx(qw1w2);
+ bool vo = !!(qw1w2 & TM_QW1W2_VO);
+
+ /* First update the registers */
+ qw1w2 = cpu_to_be32(qw1w2);
+ memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
+
+ /* Check the interrupt pending bits */
+ if (vo) {
+ xive_tctx_need_resend(tctx, nvt_blk, nvt_idx);
+ }
+}
+
/*
* Define a mapping of "special" operations depending on the TIMA page
* offset and the size of the operation.
@@ -372,6 +416,7 @@ static const XiveTmOp xive_tm_operations[] = {
* effects
*/
{ XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, NULL },
+ { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2, 4, xive_tm_push_os_ctx, NULL
},
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL
},
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
@@ -1586,14 +1631,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);
/*
--
2.21.0
- [Qemu-devel] [PATCH v2 01/17] ppc/xive: use an abstract type for XiveNotifier, (continued)
- [Qemu-devel] [PATCH v2 01/17] ppc/xive: use an abstract type for XiveNotifier, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 03/17] ppc/xive: Implement TM_PULL_OS_CTX special command, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 04/17] ppc/xive: Provide backlog support, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 05/17] ppc/xive: Provide escalation support, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 06/17] ppc/xive: Provide unconditional escalation support, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 07/17] ppc/xive: Provide silent escalation support, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 08/17] ppc/xive: Improve 'info pic' support, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 09/17] ppc/xive: Extend XiveTCTX with a XiveRouter pointer, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 10/17] ppc/xive: Introduce xive_tctx_ipb_update(), Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 11/17] ppc/xive: Synthesize interrupt from the saved IPB in the NVT,
Cédric Le Goater <=
- [Qemu-devel] [PATCH v2 12/17] ppc/pnv: Remove pnv_xive_vst_size() routine, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 13/17] ppc/pnv: Dump the XIVE NVT table, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 15/17] ppc/pnv: Grab the XiveRouter object from XiveTCTX in pnv_xive_get_tctx(), Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 14/17] ppc/pnv: Skip empty slots of the XIVE NVT table, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 16/17] ppc/pnv: Introduce a pnv_xive_get_block_id() interface to XiveRouter, Cédric Le Goater, 2019/07/18
- [Qemu-devel] [PATCH v2 17/17] ppc/pnv: quiesce some XIVE errors, Cédric Le Goater, 2019/07/18
- Re: [Qemu-devel] [PATCH v2 00/17] ppc/pnv: add XIVE support for KVM guests, no-reply, 2019/07/18
- Re: [Qemu-devel] [PATCH v2 00/17] ppc/pnv: add XIVE support for KVM guests, David Gibson, 2019/07/22