All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: "Cédric Le Goater" <clg@kaod.org>,
	qemu-ppc@nongnu.org, "Greg Kurz" <groug@kaod.org>,
	"Suraj Jitindar Singh" <sjitindarsingh@gmail.com>,
	qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 09/10] ppc/xive: Synthesize interrupt from the saved IPB in the NVT
Date: Sun, 30 Jun 2019 22:46:00 +0200	[thread overview]
Message-ID: <20190630204601.30574-10-clg@kaod.org> (raw)
In-Reply-To: <20190630204601.30574-1-clg@kaod.org>

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. The HW grabs the associated NVT to pull the pending bits, and
merge 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 <clg@kaod.org>
---
 include/hw/ppc/xive.h      | 14 ++++++++
 include/hw/ppc/xive_regs.h |  1 +
 hw/intc/xive.c             | 67 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index b764e1e4e6d4..e4dcaa7a10e9 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -420,11 +420,25 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
 void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
 Object *xive_tctx_create(Object *cpu, Object *xrtr, Error **errp);
 
+/*
+ * The VP number space in a block is defined by the END_W6_NVT_INDEX
+ * field of the XIVE END
+ */
 static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
 {
     return (nvt_blk << 19) | nvt_idx;
 }
 
+static inline uint32_t xive_nvt_idx(uint32_t cam_line)
+{
+    return cam_line & 0x7ffff;
+}
+
+static inline uint32_t xive_nvt_blk(uint32_t cam_line)
+{
+    return (cam_line >> 19) & 0xf;
+}
+
 /*
  * KVM XIVE device helpers
  */
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index 3fdf1a83b9b6..7ba0fb055174 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;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 56700681884f..2225183e0e16 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -345,6 +345,62 @@ 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) {
+        uint8_t *regs = &tctx->regs[TM_QW1_OS];
+
+        /* 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 */
+        regs[TM_IPB] |= ipb;
+        regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]);
+
+        /* Possibly resend */
+        xive_tctx_notify(tctx, TM_QW1_OS);
+    }
+}
+
+/*
+ * Updating the OS CAM line can trigger a resend of interrupt
+ */
+static void xive_tm_push_os_cam(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.
@@ -364,6 +420,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_cam, 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 },
@@ -1471,6 +1528,7 @@ static void xive_router_end_backlog(XiveRouter *xrtr,
                                     uint8_t priority)
 {
     XiveNVT nvt;
+    uint8_t ipb;
 
     /* NVT cache lookup */
     if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) {
@@ -1485,8 +1543,13 @@ static void xive_router_end_backlog(XiveRouter *xrtr,
         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



  parent reply	other threads:[~2019-06-30 20:50 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-30 20:45 [Qemu-devel] [PATCH 00/10] ppc/pnv: add XIVE support for KVM guests Cédric Le Goater
2019-06-30 20:45 ` [Qemu-devel] [PATCH 01/10] ppc/xive: Force the Physical CAM line value to group mode Cédric Le Goater
2019-07-01  5:26   ` David Gibson
2019-06-30 20:45 ` [Qemu-devel] [PATCH 02/10] ppc/xive: Make the PIPR register readonly Cédric Le Goater
2019-07-01  5:27   ` David Gibson
2019-06-30 20:45 ` [Qemu-devel] [PATCH 03/10] ppc/pnv: Rework cache watch model of PnvXIVE Cédric Le Goater
2019-07-01  5:32   ` David Gibson
2019-06-30 20:45 ` [Qemu-devel] [PATCH 04/10] ppc/xive: Fix TM_PULL_POOL_CTX special operation Cédric Le Goater
2019-07-01  5:32   ` David Gibson
2019-06-30 20:45 ` [Qemu-devel] [PATCH 05/10] ppc/xive: Implement TM_PULL_OS_CTX special command Cédric Le Goater
2019-06-30 20:45 ` [Qemu-devel] [PATCH 06/10] ppc/xive: Provide escalation support Cédric Le Goater
2019-06-30 20:45 ` [Qemu-devel] [PATCH 07/10] ppc/xive: Improve 'info pic' support Cédric Le Goater
2019-06-30 20:45 ` [Qemu-devel] [PATCH 08/10] ppc/xive: Extend XiveTCTX with an router object pointer Cédric Le Goater
2019-07-03  2:07   ` David Gibson
2019-07-03  5:54     ` Cédric Le Goater
2019-07-12  1:15       ` David Gibson
2019-07-15 15:45         ` Cédric Le Goater
2019-07-17  2:08           ` David Gibson
2019-07-17  8:35             ` Cédric Le Goater
2019-06-30 20:46 ` Cédric Le Goater [this message]
2019-06-30 20:46 ` [Qemu-devel] [PATCH 10/10] ppc/pnv: Dump the XIVE NVT table Cédric Le Goater
2019-07-03  2:10 ` [Qemu-devel] [PATCH 00/10] ppc/pnv: add XIVE support for KVM guests David Gibson
2019-07-03  5:56   ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190630204601.30574-10-clg@kaod.org \
    --to=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=sjitindarsingh@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.