get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/812466/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 812466,
    "url": "http://patchwork.ozlabs.org/api/patches/812466/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170911171235.29331-8-clg@kaod.org/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170911171235.29331-8-clg@kaod.org>",
    "list_archive_url": null,
    "date": "2017-09-11T17:12:21",
    "name": "[RFC,v2,07/21] ppc/xive: add MMIO handlers for the XIVE interrupt sources",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "1680edfbd412557915c713f67eada39150a3124d",
    "submitter": {
        "id": 68548,
        "url": "http://patchwork.ozlabs.org/api/people/68548/?format=api",
        "name": "Cédric Le Goater",
        "email": "clg@kaod.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170911171235.29331-8-clg@kaod.org/mbox/",
    "series": [
        {
            "id": 2526,
            "url": "http://patchwork.ozlabs.org/api/series/2526/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=2526",
            "date": "2017-09-11T17:12:14",
            "name": "Guest exploitation of the XIVE interrupt controller (POWER9)",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/2526/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/812466/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/812466/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xrZSM5fldz9s81\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 12 Sep 2017 03:20:19 +1000 (AEST)",
            "from localhost ([::1]:59297 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1drSNd-0005wo-Nb\n\tfor incoming@patchwork.ozlabs.org; Mon, 11 Sep 2017 13:20:17 -0400",
            "from eggs.gnu.org ([2001:4830:134:3::10]:35016)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <clg@kaod.org>) id 1drSHJ-0000sW-7U\n\tfor qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:46 -0400",
            "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <clg@kaod.org>) id 1drSHE-00042k-IC\n\tfor qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:45 -0400",
            "from 7.mo2.mail-out.ovh.net ([188.165.48.182]:49537)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <clg@kaod.org>) id 1drSHE-00041p-9D\n\tfor qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:13:40 -0400",
            "from player770.ha.ovh.net (b6.ovh.net [213.186.33.56])\n\tby mo2.mail-out.ovh.net (Postfix) with ESMTP id 54295AB0A1\n\tfor <qemu-devel@nongnu.org>; Mon, 11 Sep 2017 19:13:39 +0200 (CEST)",
            "from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr\n\t[90.76.52.173]) (Authenticated sender: clg@kaod.org)\n\tby player770.ha.ovh.net (Postfix) with ESMTPSA id 240B93C006C;\n\tMon, 11 Sep 2017 19:13:32 +0200 (CEST)"
        ],
        "From": "=?utf-8?q?C=C3=A9dric_Le_Goater?= <clg@kaod.org>",
        "To": "qemu-ppc@nongnu.org, qemu-devel@nongnu.org,\n\tDavid Gibson <david@gibson.dropbear.id.au>,\n\tBenjamin Herrenschmidt <benh@kernel.crashing.org>,\n\tAlexey Kardashevskiy <aik@ozlabs.ru>, Alexander Graf <agraf@suse.de>",
        "Date": "Mon, 11 Sep 2017 19:12:21 +0200",
        "Message-Id": "<20170911171235.29331-8-clg@kaod.org>",
        "X-Mailer": "git-send-email 2.13.5",
        "In-Reply-To": "<20170911171235.29331-1-clg@kaod.org>",
        "References": "<20170911171235.29331-1-clg@kaod.org>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "X-Ovh-Tracer-Id": "14142147256532831059",
        "X-VR-SPAMSTATE": "OK",
        "X-VR-SPAMSCORE": "-100",
        "X-VR-SPAMCAUSE": "gggruggvucftvghtrhhoucdtuddrfeelledrgedtgdduudehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm",
        "Content-Transfer-Encoding": "quoted-printable",
        "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]",
        "X-Received-From": "188.165.48.182",
        "Subject": "[Qemu-devel] [RFC PATCH v2 07/21] ppc/xive: add MMIO handlers for\n\tthe XIVE interrupt sources",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Id": "<qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Cc": "=?utf-8?q?C=C3=A9dric_Le_Goater?= <clg@kaod.org>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"
    },
    "content": "Each interrupt source is associated with a two bit state machine\ncalled an Event State Buffer (ESB) which is controlled by MMIO to\ntrigger events. See code for more details on the states and\ntransitions.\n\nThe MMIO space for the ESB translation is 512GB large on baremetal\n(powernv) systems and the BAR depends on the chip id. In our model for\nthe sPAPR machine, we choose to only map a sub memory region for the\nprovisionned IRQ numbers and to use the mapping address of chip 0 on a\nreal system. The OS will get the address of the MMIO page of the ESB\nentry associated with an IRQ using the H_INT_GET_SOURCE_INFO hcall.\n\nFor KVM support, we should think of a way to map this QEMU memory\nregion in the host to trigger events directly.\n\nSigned-off-by: Cédric Le Goater <clg@kaod.org>\n---\n hw/intc/spapr_xive.c        | 255 ++++++++++++++++++++++++++++++++++++++++++++\n include/hw/ppc/spapr_xive.h |   6 ++\n 2 files changed, 261 insertions(+)",
    "diff": "diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c\nindex 1ed7b6a286e9..8a85d64efc4c 100644\n--- a/hw/intc/spapr_xive.c\n+++ b/hw/intc/spapr_xive.c\n@@ -33,6 +33,218 @@ static void spapr_xive_irq(sPAPRXive *xive, int srcno)\n }\n \n /*\n+ * \"magic\" Event State Buffer (ESB) MMIO offsets.\n+ *\n+ * Each interrupt source has a 2-bit state machine called ESB\n+ * which can be controlled by MMIO. It's made of 2 bits, P and\n+ * Q. P indicates that an interrupt is pending (has been sent\n+ * to a queue and is waiting for an EOI). Q indicates that the\n+ * interrupt has been triggered while pending.\n+ *\n+ * This acts as a coalescing mechanism in order to guarantee\n+ * that a given interrupt only occurs at most once in a queue.\n+ *\n+ * When doing an EOI, the Q bit will indicate if the interrupt\n+ * needs to be re-triggered.\n+ *\n+ * The following offsets into the ESB MMIO allow to read or\n+ * manipulate the PQ bits. They must be used with an 8-bytes\n+ * load instruction. They all return the previous state of the\n+ * interrupt (atomically).\n+ *\n+ * Additionally, some ESB pages support doing an EOI via a\n+ * store at 0 and some ESBs support doing a trigger via a\n+ * separate trigger page.\n+ */\n+#define XIVE_ESB_GET            0x800\n+#define XIVE_ESB_SET_PQ_00      0xc00\n+#define XIVE_ESB_SET_PQ_01      0xd00\n+#define XIVE_ESB_SET_PQ_10      0xe00\n+#define XIVE_ESB_SET_PQ_11      0xf00\n+\n+#define XIVE_ESB_VAL_P          0x2\n+#define XIVE_ESB_VAL_Q          0x1\n+\n+#define XIVE_ESB_RESET          0x0\n+#define XIVE_ESB_PENDING        XIVE_ESB_VAL_P\n+#define XIVE_ESB_QUEUED         (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q)\n+#define XIVE_ESB_OFF            XIVE_ESB_VAL_Q\n+\n+static uint8_t spapr_xive_pq_get(sPAPRXive *xive, uint32_t idx)\n+{\n+    uint32_t byte = idx / 4;\n+    uint32_t bit  = (idx % 4) * 2;\n+\n+    assert(byte < xive->sbe_size);\n+\n+    return (xive->sbe[byte] >> bit) & 0x3;\n+}\n+\n+static uint8_t spapr_xive_pq_set(sPAPRXive *xive, uint32_t idx, uint8_t pq)\n+{\n+    uint32_t byte = idx / 4;\n+    uint32_t bit  = (idx % 4) * 2;\n+    uint8_t old, new;\n+\n+    assert(byte < xive->sbe_size);\n+\n+    old = xive->sbe[byte];\n+\n+    new = xive->sbe[byte] & ~(0x3 << bit);\n+    new |= (pq & 0x3) << bit;\n+\n+    xive->sbe[byte] = new;\n+\n+    return (old >> bit) & 0x3;\n+}\n+\n+static bool spapr_xive_pq_eoi(sPAPRXive *xive, uint32_t srcno)\n+{\n+    uint8_t old_pq = spapr_xive_pq_get(xive, srcno);\n+\n+    switch (old_pq) {\n+    case XIVE_ESB_RESET:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_RESET);\n+        return false;\n+    case XIVE_ESB_PENDING:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_RESET);\n+        return false;\n+    case XIVE_ESB_QUEUED:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_PENDING);\n+        return true;\n+    case XIVE_ESB_OFF:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_OFF);\n+        return false;\n+    default:\n+         g_assert_not_reached();\n+    }\n+}\n+\n+static bool spapr_xive_pq_trigger(sPAPRXive *xive, uint32_t srcno)\n+{\n+    uint8_t old_pq = spapr_xive_pq_get(xive, srcno);\n+\n+    switch (old_pq) {\n+    case XIVE_ESB_RESET:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_PENDING);\n+        return true;\n+    case XIVE_ESB_PENDING:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_QUEUED);\n+        return true;\n+    case XIVE_ESB_QUEUED:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_QUEUED);\n+        return true;\n+    case XIVE_ESB_OFF:\n+        spapr_xive_pq_set(xive, srcno, XIVE_ESB_OFF);\n+        return false;\n+    default:\n+         g_assert_not_reached();\n+    }\n+}\n+\n+/*\n+ * XIVE Interrupt Source MMIOs\n+ */\n+static void spapr_xive_source_eoi(sPAPRXive *xive, uint32_t srcno)\n+{\n+    ICSIRQState *irq = &xive->ics->irqs[srcno];\n+\n+    if (irq->flags & XICS_FLAGS_IRQ_LSI) {\n+        irq->status &= ~XICS_STATUS_SENT;\n+    }\n+}\n+\n+/* TODO: handle second page\n+ *\n+ * Some HW use a separate page for trigger. We only support the case\n+ * in which the trigger can be done in the same page as the EOI.\n+ */\n+static uint64_t spapr_xive_esb_read(void *opaque, hwaddr addr, unsigned size)\n+{\n+    sPAPRXive *xive = SPAPR_XIVE(opaque);\n+    uint32_t offset = addr & 0xF00;\n+    uint32_t srcno = addr >> xive->esb_shift;\n+    XiveIVE *ive;\n+    uint64_t ret = -1;\n+\n+    ive = spapr_xive_get_ive(xive, srcno);\n+    if (!ive || !(ive->w & IVE_VALID))  {\n+        qemu_log_mask(LOG_GUEST_ERROR, \"XIVE: invalid LISN %d\\n\", srcno);\n+        goto out;\n+    }\n+\n+    switch (offset) {\n+    case 0:\n+        spapr_xive_source_eoi(xive, srcno);\n+\n+        /* return TRUE or FALSE depending on PQ value */\n+        ret = spapr_xive_pq_eoi(xive, srcno);\n+        break;\n+\n+    case XIVE_ESB_GET:\n+        ret = spapr_xive_pq_get(xive, srcno);\n+        break;\n+\n+    case XIVE_ESB_SET_PQ_00:\n+    case XIVE_ESB_SET_PQ_01:\n+    case XIVE_ESB_SET_PQ_10:\n+    case XIVE_ESB_SET_PQ_11:\n+        ret = spapr_xive_pq_set(xive, srcno, (offset >> 8) & 0x3);\n+        break;\n+    default:\n+        qemu_log_mask(LOG_GUEST_ERROR, \"XIVE: invalid ESB addr %d\\n\", offset);\n+    }\n+\n+out:\n+    return ret;\n+}\n+\n+static void spapr_xive_esb_write(void *opaque, hwaddr addr,\n+                           uint64_t value, unsigned size)\n+{\n+    sPAPRXive *xive = SPAPR_XIVE(opaque);\n+    uint32_t offset = addr & 0xF00;\n+    uint32_t srcno = addr >> xive->esb_shift;\n+    XiveIVE *ive;\n+    bool notify = false;\n+\n+    ive = spapr_xive_get_ive(xive, srcno);\n+    if (!ive || !(ive->w & IVE_VALID))  {\n+        qemu_log_mask(LOG_GUEST_ERROR, \"XIVE: invalid LISN %d\\n\", srcno);\n+        return;\n+    }\n+\n+    switch (offset) {\n+    case 0:\n+        /* TODO: should we trigger even if the IVE is masked ? */\n+        notify = spapr_xive_pq_trigger(xive, srcno);\n+        break;\n+    default:\n+        qemu_log_mask(LOG_GUEST_ERROR, \"XIVE: invalid ESB write addr %d\\n\",\n+                      offset);\n+        return;\n+    }\n+\n+    if (notify && !(ive->w & IVE_MASKED)) {\n+        qemu_irq_pulse(xive->qirqs[srcno]);\n+    }\n+}\n+\n+static const MemoryRegionOps spapr_xive_esb_ops = {\n+    .read = spapr_xive_esb_read,\n+    .write = spapr_xive_esb_write,\n+    .endianness = DEVICE_BIG_ENDIAN,\n+    .valid = {\n+        .min_access_size = 8,\n+        .max_access_size = 8,\n+    },\n+    .impl = {\n+        .min_access_size = 8,\n+        .max_access_size = 8,\n+    },\n+};\n+\n+/*\n  * XIVE Interrupt Source\n  */\n static void spapr_xive_source_set_irq_msi(sPAPRXive *xive, int srcno, int val)\n@@ -74,6 +286,33 @@ static void spapr_xive_source_set_irq(void *opaque, int srcno, int val)\n /*\n  * Main XIVE object\n  */\n+#define P9_MMIO_BASE     0x006000000000000ull\n+\n+/* VC BAR contains set translations for the ESBs and the EQs. */\n+#define VC_BAR_DEFAULT   0x10000000000ull\n+#define VC_BAR_SIZE      0x08000000000ull\n+#define ESB_SHIFT        16 /* One 64k page. OPAL has two */\n+\n+static uint64_t spapr_xive_esb_default_read(void *p, hwaddr offset,\n+                                            unsigned size)\n+{\n+    qemu_log_mask(LOG_UNIMP, \"%s: 0x%\" HWADDR_PRIx \" [%u]\\n\",\n+                  __func__, offset, size);\n+    return 0;\n+}\n+\n+static void spapr_xive_esb_default_write(void *opaque, hwaddr offset,\n+                                         uint64_t value, unsigned size)\n+{\n+    qemu_log_mask(LOG_UNIMP, \"%s: 0x%\" HWADDR_PRIx \" <- 0x%\" PRIx64 \" [%u]\\n\",\n+                  __func__, offset, value, size);\n+}\n+\n+static const MemoryRegionOps spapr_xive_esb_default_ops = {\n+    .read = spapr_xive_esb_default_read,\n+    .write = spapr_xive_esb_default_write,\n+    .endianness = DEVICE_BIG_ENDIAN,\n+};\n \n void spapr_xive_reset(void *dev)\n {\n@@ -144,6 +383,22 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)\n     xive->nr_eqs = xive->nr_targets * XIVE_EQ_PRIORITY_COUNT;\n     xive->eqt = g_malloc0(xive->nr_eqs * sizeof(XiveEQ));\n \n+    /* VC BAR. That's the full window but we will only map the\n+     * subregions in use. */\n+    xive->esb_base = (P9_MMIO_BASE | VC_BAR_DEFAULT);\n+    xive->esb_shift = ESB_SHIFT;\n+\n+    /* Install default memory region handlers to log bogus access */\n+    memory_region_init_io(&xive->esb_mr, NULL, &spapr_xive_esb_default_ops,\n+                          NULL, \"xive.esb.full\", VC_BAR_SIZE);\n+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->esb_mr);\n+\n+    /* Install the ESB memory region in the overall one */\n+    memory_region_init_io(&xive->esb_iomem, OBJECT(xive), &spapr_xive_esb_ops,\n+                          xive, \"xive.esb\",\n+                          (1ull << xive->esb_shift) * xive->nr_irqs);\n+    memory_region_add_subregion(&xive->esb_mr, 0, &xive->esb_iomem);\n+\n     qemu_register_reset(spapr_xive_reset, dev);\n }\n \ndiff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h\nindex eab92c4c1bb8..0f516534d76a 100644\n--- a/include/hw/ppc/spapr_xive.h\n+++ b/include/hw/ppc/spapr_xive.h\n@@ -46,6 +46,12 @@ struct sPAPRXive {\n     XiveIVE      *ivt;\n     XiveEQ       *eqt;\n     uint32_t     nr_eqs;\n+\n+    /* ESB memory region */\n+    uint32_t     esb_shift;\n+    hwaddr       esb_base;\n+    MemoryRegion esb_mr;\n+    MemoryRegion esb_iomem;\n };\n \n #endif /* PPC_SPAPR_XIVE_H */\n",
    "prefixes": [
        "RFC",
        "v2",
        "07/21"
    ]
}