Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216884/?format=api
{ "id": 2216884, "url": "http://patchwork.ozlabs.org/api/patches/2216884/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260327111700.795099-19-peter.maydell@linaro.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": "<20260327111700.795099-19-peter.maydell@linaro.org>", "list_archive_url": null, "date": "2026-03-27T11:16:13", "name": "[v2,18/65] hw/intc/arm_gicv5: Implement gicv5_set_priority()", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "1b1e3b527cdb7ae687e8e314fb4b1fdfa8c7fe78", "submitter": { "id": 5111, "url": "http://patchwork.ozlabs.org/api/people/5111/?format=api", "name": "Peter Maydell", "email": "peter.maydell@linaro.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260327111700.795099-19-peter.maydell@linaro.org/mbox/", "series": [ { "id": 497750, "url": "http://patchwork.ozlabs.org/api/series/497750/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=497750", "date": "2026-03-27T11:16:25", "name": "arm: Implement an emulation of GICv5 interrupt controller", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/497750/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216884/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216884/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@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=fp0cSAXY;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhypz0Gv3z1y1x\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 22:19:55 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1w65C0-0006iP-4h; Fri, 27 Mar 2026 07:17:32 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1w65Br-0006Wq-PC\n for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:23 -0400", "from mail-wr1-x434.google.com ([2a00:1450:4864:20::434])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <peter.maydell@linaro.org>)\n id 1w65Bo-0007up-Mk\n for qemu-devel@nongnu.org; Fri, 27 Mar 2026 07:17:23 -0400", "by mail-wr1-x434.google.com with SMTP id\n ffacd0b85a97d-43b9f43a1feso353048f8f.1\n for <qemu-devel@nongnu.org>; Fri, 27 Mar 2026 04:17:20 -0700 (PDT)", "from lanath.. (wildly.archaic.org.uk. [81.2.115.145])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43b919cf2b2sm15484227f8f.18.2026.03.27.04.17.18\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Fri, 27 Mar 2026 04:17:18 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1774610239; x=1775215039; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=7oCFUH8gap/6SDnvGDvqqyJf9FNOwDhKGaU4TmrDjPQ=;\n b=fp0cSAXYnzJHQbk5SO1URItFA+ZFYM+1Fv4vITzXvXRR+F4ORpRgpJuA3gHtlK3Bk9\n 9eNeJexlWoNzLD2JXGJSF45BpvSq3rVy5WqBzEx5ounVICn61OoEGW7PwDDiWaB2WRmv\n pH04lGal4NZvI/Q4mOAeDj2yp9pS5Xuuk/SBvkpoLPX9nlOlba/zQDHYjCO36J8RbyAB\n 8mtkmVQwnOJQ5MIzjhMHuIOtlYO+64gemMJap0lkvynbWpb3Yhao6F8pM7KhesSJuYab\n S2Vb1nrpzEcJXZGcOsA+85XHFa7YrNijS+4fW4oVxFNV9WszOKY2CfqbqyLsRNGiiJPG\n isZg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774610239; x=1775215039;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=7oCFUH8gap/6SDnvGDvqqyJf9FNOwDhKGaU4TmrDjPQ=;\n b=SDxf208ATyqcBCK5Ylur+c26qa9aBNpTMPS6N77IsNk7TfJ3KxqOohslj7Hf0/yY4W\n pj8jfqr4vi7wIy0yvshfwTkoF3GYVzXe9yiL7VeoS06jwtuHdcc4Fy9vg5qjhLSfGeKy\n sOcW1FA8BqO2/lE6XhK+OXW7weCf+oxU8H8dLsLOCah1qYApXXDFgnVKGTdkuPiJ8Ts4\n g8xv5/SANu14sHo29YWkUye+qyo3rL4HtvlA9FrSa3CQTfC4MjA+bekS2+BghgTkFgKj\n 4ttvzYqlo5hex5j8oSU8UtQ1fd4hMbXj51ZB/0nlNjc3i5GlwDXvBRZbwBQQL7l+GnVE\n bphw==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCXvX8rxV08GmzE0emtEi0KJhzh1Z9IydJBQ1GsAp5uAKvtF5He7cm/Vy83MUgnPjreeaqeRAVXfq+Ol@nongnu.org", "X-Gm-Message-State": "AOJu0Yz0bk4zKD0JxLAFwn2WiQQYj7w1GJQeVdYInHH1YbfZF9yslig0\n n2D8Vq5Rfwl+TISS249FbbhuWoj/M09hX33/tb+7gnU9KyQdnQtKXGNSLXCqc6+Mwos=", "X-Gm-Gg": "ATEYQzwkf83E+2jxbVb1V3bOidWmVk55iBwT3wpNMGN2+plWyxNp80UEFNbAI5ipcqK\n hVv9IYGokUK9nb2Yzw5krF/6HLZN3ibxuZ/0O2747llQDPOwTm2eRHjtro2MaWeaTLxYGMEUP4z\n P05dmmy7b7qgaaUfo2y6hnyBoWZHerW3BR2NvcgsdgWoq5xzdW16no6IkPI1uPBn9yvi8rCmcG8\n 9A3O0/CIgnhiV6ctpDdsb9h6/sQdYFTwVs3jj8lvYytkf94ILX0s6TvraVHVcUolkj5VjJ+ih54\n obJ4lszaDMTHli079j/EOZKFMu1l4NmN6jkWoR/RRZlA3p/6eS9S5lOwzkGSg6Jp0gvzb+LYMyZ\n AIErO3zaJ5Sev1uN6Hv2wMUscDroRRqF0WYapMsVioLyra884FbTHXwUuZNvZAczyhphzPpcIfH\n wFapLfVbRMzG8CzPVQs4W31qyNm1ThQUKOxINapJF+AI45q8yOXiZcujWk8R4a8kwKTkcwMSSye\n 8zC4XfQMncPze2TUGCn6v5c4jlGToU=", "X-Received": "by 2002:a05:6000:400e:b0:439:b7a2:60ff with SMTP id\n ffacd0b85a97d-43b9ea4a495mr3120574f8f.32.1774610238909;\n Fri, 27 Mar 2026 04:17:18 -0700 (PDT)", "From": "Peter Maydell <peter.maydell@linaro.org>", "To": "qemu-arm@nongnu.org,\n\tqemu-devel@nongnu.org", "Cc": "Jonathan Cameron <jonathan.cameron@huawei.com>", "Subject": "[PATCH v2 18/65] hw/intc/arm_gicv5: Implement gicv5_set_priority()", "Date": "Fri, 27 Mar 2026 11:16:13 +0000", "Message-ID": "<20260327111700.795099-19-peter.maydell@linaro.org>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260327111700.795099-1-peter.maydell@linaro.org>", "References": "<20260327111700.795099-1-peter.maydell@linaro.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=2a00:1450:4864:20::434;\n envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x434.google.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://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 <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Implement the gicv5_set_priority() function, which is our equivalent\nof the Stream Protocol SetPriority command. This acts by looking the\ninterrupt ID up in the Interrupt State Table and storing the new\npriority value into the table entry.\n\nThe memory transaction has to have the right transaction attributes\nfor the domain it is for; we precalculate these and keep them in the\nGICv5ISTConfig.\n\nThe GIC has an optional software-error reporting mechanism via the\nIRS_SWERR_* registers; this does not report all failure cases, only\nthose that would be annoying to detect and debug in some other way.\nWe choose not to implement this, but include some comments for\nreportable error cases for future reference. Our LOG_GUEST_ERROR\nlogging is a superset of this.\n\nAt this point we implement only handling of SetPriority for LPIs; we\nwill add SPI handling in a later commit. Virtual interrupts aren't\nsupported by this initial EL1-only GICv5 implementation.\n\nSigned-off-by: Peter Maydell <peter.maydell@linaro.org>\nReviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>\n---\n hw/intc/arm_gicv5.c | 233 +++++++++++++++++++++++++++++\n hw/intc/trace-events | 1 +\n include/hw/intc/arm_gicv5.h | 1 +\n include/hw/intc/arm_gicv5_stream.h | 29 ++++\n include/hw/intc/arm_gicv5_types.h | 10 ++\n 5 files changed, 274 insertions(+)", "diff": "diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c\nindex 172c5be0d4..3588f3323f 100644\n--- a/hw/intc/arm_gicv5.c\n+++ b/hw/intc/arm_gicv5.c\n@@ -9,6 +9,7 @@\n #include \"qemu/osdep.h\"\n #include \"hw/core/registerfields.h\"\n #include \"hw/intc/arm_gicv5.h\"\n+#include \"hw/intc/arm_gicv5_stream.h\"\n #include \"qapi/error.h\"\n #include \"qemu/log.h\"\n #include \"trace.h\"\n@@ -23,6 +24,25 @@ static const char *domain_name[] = {\n [GICV5_ID_REALM] = \"Realm\",\n };\n \n+static const char *inttype_name(GICv5IntType t)\n+{\n+ /*\n+ * We have to be more cautious with getting human readable names\n+ * for a GICv5IntType for trace strings than we do with the domain\n+ * enum, because here the value can come from a guest register\n+ * field.\n+ */\n+ static const char *names[] = {\n+ [GICV5_PPI] = \"PPI\",\n+ [GICV5_LPI] = \"LPI\",\n+ [GICV5_SPI] = \"SPI\",\n+ };\n+ if (t >= ARRAY_SIZE(names) || !names[t]) {\n+ return \"RESERVED\";\n+ }\n+ return names[t];\n+}\n+\n REG32(IRS_IDR0, 0x0)\n FIELD(IRS_IDR0, INT_DOM, 0, 2)\n FIELD(IRS_IDR0, PA_RANGE, 2, 4)\n@@ -265,6 +285,218 @@ REG64(IRS_SWERR_SYNDROMER0, 0x3c8)\n REG64(IRS_SWERR_SYNDROMER1, 0x3d0)\n FIELD(IRS_SWERR_SYNDROMER2, ADDR, 3, 53)\n \n+FIELD(L1_ISTE, VALID, 0, 1)\n+FIELD(L1_ISTE, L2_ADDR, 12, 44)\n+\n+FIELD(L2_ISTE, PENDING, 0, 1)\n+FIELD(L2_ISTE, ACTIVE, 1, 1)\n+FIELD(L2_ISTE, HM, 2, 1)\n+FIELD(L2_ISTE, ENABLE, 3, 1)\n+FIELD(L2_ISTE, IRM, 4, 1)\n+FIELD(L2_ISTE, HWU, 9, 2)\n+FIELD(L2_ISTE, PRIORITY, 11, 5)\n+FIELD(L2_ISTE, IAFFID, 16, 16)\n+\n+static MemTxAttrs irs_txattrs(GICv5Common *cs, GICv5Domain domain)\n+{\n+ /*\n+ * Return a MemTxAttrs to use for IRS memory accesses. IRS_CR1\n+ * has the usual Arm cacheability/shareability attributes, but\n+ * QEMU doesn't care about those. All we need to specify here is\n+ * the correct security attributes, which depend on the interrupt\n+ * domain. Conveniently, our GICv5Domain encoding matches the\n+ * ARMSecuritySpace one (because both follow an architecturally\n+ * specified field). The exception is that the EL3 domain must be\n+ * Secure instead of Root if we don't implement Realm.\n+ */\n+ if (domain == GICV5_ID_EL3 &&\n+ !gicv5_domain_implemented(cs, GICV5_ID_REALM)) {\n+ domain = GICV5_ID_S;\n+ }\n+ return (MemTxAttrs) {\n+ .space = domain,\n+ .secure = domain == GICV5_ID_S || domain == GICV5_ID_EL3,\n+ };\n+}\n+\n+static hwaddr l1_iste_addr(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ uint32_t id)\n+{\n+ /*\n+ * In a 2-level IST configuration, return the address of the L1\n+ * IST entry for this interrupt ID. The bottom l2_idx_bits of the\n+ * ID value are the index into the L2 table, and the higher bits\n+ * of the ID index the L1 table.\n+ */\n+ uint32_t l1_index = id >> cfg->l2_idx_bits;\n+ return cfg->base + (l1_index * 8);\n+}\n+\n+static bool get_l2_iste_addr(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ uint32_t id, hwaddr *l2_iste_addr)\n+{\n+ /*\n+ * Get the address of the L2 interrupt state table entry for this\n+ * interrupt. On success, fill in l2_iste_addr and return true.\n+ * On failure, return false.\n+ */\n+ hwaddr l2_base;\n+\n+ if (!cfg->valid) {\n+ return false;\n+ }\n+\n+ if (id >= (1 << cfg->id_bits)) {\n+ return false;\n+ }\n+\n+ if (cfg->structure) {\n+ /*\n+ * 2-level table: read the L1 IST. The bottom l2_idx_bits of\n+ * the ID value are the index into the L2 table, and the\n+ * higher bits of the ID index the L1 table. There is always\n+ * at least one L1 table entry.\n+ */\n+ hwaddr l1_addr = l1_iste_addr(cs, cfg, id);\n+ uint64_t l1_iste;\n+ MemTxResult res;\n+\n+ l1_iste = address_space_ldq_le(&cs->dma_as, l1_addr,\n+ cfg->txattrs, &res);\n+ if (res != MEMTX_OK) {\n+ /* Reportable with EC=0x01 if sw error reporting implemented */\n+ qemu_log_mask(LOG_GUEST_ERROR, \"L1 ISTE lookup failed for ID 0x%x\"\n+ \" at physical address 0x\" HWADDR_FMT_plx \"\\n\",\n+ id, l1_addr);\n+ return false;\n+ }\n+ if (!FIELD_EX64(l1_iste, L1_ISTE, VALID)) {\n+ return false;\n+ }\n+ l2_base = l1_iste & R_L1_ISTE_L2_ADDR_MASK;\n+ id = extract32(id, 0, cfg->l2_idx_bits);\n+ } else {\n+ /* 1-level table */\n+ l2_base = cfg->base;\n+ }\n+\n+ *l2_iste_addr = l2_base + (id * cfg->istsz);\n+ return true;\n+}\n+\n+static bool read_l2_iste_mem(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ hwaddr addr, uint32_t *l2_iste)\n+{\n+ MemTxResult res;\n+\n+ *l2_iste = address_space_ldl_le(&cs->dma_as, addr, cfg->txattrs, &res);\n+ if (res != MEMTX_OK) {\n+ /* Reportable with EC=0x02 if sw error reporting implemented */\n+ qemu_log_mask(LOG_GUEST_ERROR, \"L2 ISTE read failed at physical \"\n+ \"address 0x\" HWADDR_FMT_plx \"\\n\", addr);\n+ }\n+ return res == MEMTX_OK;\n+}\n+\n+static bool write_l2_iste_mem(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ hwaddr addr, uint32_t l2_iste)\n+{\n+ MemTxResult res;\n+\n+ address_space_stl_le(&cs->dma_as, addr, l2_iste, cfg->txattrs, &res);\n+ if (res != MEMTX_OK) {\n+ /* Reportable with EC=0x02 if sw error reporting implemented */\n+ qemu_log_mask(LOG_GUEST_ERROR, \"L2 ISTE write failed at physical \"\n+ \"address 0x\" HWADDR_FMT_plx \"\\n\", addr);\n+ }\n+ return res == MEMTX_OK;\n+}\n+\n+/*\n+ * This is returned by get_l2_iste() and has everything we need to do\n+ * the writeback of the L2 ISTE word in put_l2_iste(). Currently the\n+ * get/put functions always directly do guest memory reads and writes\n+ * to update the L2 ISTE. In a future commit we will add support for a\n+ * cache of some of the ISTE data in a local hashtable; the APIs are\n+ * designed with that in mind.\n+ */\n+typedef struct L2_ISTE_Handle {\n+ hwaddr l2_iste_addr;\n+ uint32_t l2_iste;\n+} L2_ISTE_Handle;\n+\n+static uint32_t *get_l2_iste(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ uint32_t id, L2_ISTE_Handle *h)\n+{\n+ /*\n+ * Find the L2 ISTE for the interrupt @id.\n+ *\n+ * We return a pointer to the ISTE: the caller can freely read and\n+ * modify the uint64_t pointed to to update the ISTE. If the\n+ * caller modifies the L2 ISTE word, it must call put_l2_iste(),\n+ * passing it @h, to write back the ISTE. If the caller is only\n+ * reading the L2 ISTE, it does not need to call put_l2_iste().\n+ *\n+ * We fill in @h with information needed for put_l2_iste().\n+ *\n+ * If the ISTE could not be read (typically because of a memory\n+ * error), return NULL.\n+ */\n+ if (!get_l2_iste_addr(cs, cfg, id, &h->l2_iste_addr) ||\n+ !read_l2_iste_mem(cs, cfg, h->l2_iste_addr, &h->l2_iste)) {\n+ return NULL;\n+ }\n+ return &h->l2_iste;\n+}\n+\n+static void put_l2_iste(GICv5Common *cs, const GICv5ISTConfig *cfg,\n+ L2_ISTE_Handle *h)\n+{\n+ /*\n+ * Write back the modified L2_ISTE word found with get_l2_iste().\n+ * Once this has been called the L2_ISTE_Handle @h and the pointer\n+ * to the L2 ISTE word are no longer valid.\n+ */\n+ write_l2_iste_mem(cs, cfg, h->l2_iste_addr, h->l2_iste);\n+}\n+\n+void gicv5_set_priority(GICv5Common *cs, uint32_t id, uint8_t priority,\n+ GICv5Domain domain, GICv5IntType type, bool virtual)\n+{\n+ GICv5 *s = ARM_GICV5(cs);\n+\n+ trace_gicv5_set_priority(domain_name[domain], inttype_name(type), virtual,\n+ id, priority);\n+ /* We must ignore unimplemented low-order priority bits */\n+ priority &= MAKE_64BIT_MASK(5 - QEMU_GICV5_PRI_BITS, QEMU_GICV5_PRI_BITS);\n+\n+ if (virtual) {\n+ qemu_log_mask(LOG_GUEST_ERROR, \"gicv5_set_priority: tried to set \"\n+ \"priority of a virtual interrupt\\n\");\n+ return;\n+ }\n+\n+ switch (type) {\n+ case GICV5_LPI:\n+ {\n+ const GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];\n+ L2_ISTE_Handle h;\n+ uint32_t *l2_iste_p = get_l2_iste(cs, cfg, id, &h);\n+\n+ if (!l2_iste_p) {\n+ return;\n+ }\n+ *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, PRIORITY, priority);\n+ put_l2_iste(cs, cfg, &h);\n+ break;\n+ }\n+ default:\n+ qemu_log_mask(LOG_GUEST_ERROR, \"gicv5_set_priority: tried to set \"\n+ \"priority of bad interrupt type %d\\n\", type);\n+ return;\n+ }\n+}\n+\n static void irs_ist_baser_write(GICv5 *s, GICv5Domain domain, uint64_t value)\n {\n GICv5Common *cs = ARM_GICV5_COMMON(s);\n@@ -331,6 +563,7 @@ static void irs_ist_baser_write(GICv5 *s, GICv5Domain domain, uint64_t value)\n */\n l2_idx_bits = l2bits - istbits;\n cfg->base = cs->irs_ist_baser[domain] & R_IRS_IST_BASER_ADDR_MASK;\n+ cfg->txattrs = irs_txattrs(cs, domain),\n cfg->id_bits = id_bits;\n cfg->istsz = 1 << istbits;\n cfg->l2_idx_bits = l2_idx_bits;\ndiff --git a/hw/intc/trace-events b/hw/intc/trace-events\nindex 80fc47794b..42f5e73d54 100644\n--- a/hw/intc/trace-events\n+++ b/hw/intc/trace-events\n@@ -235,6 +235,7 @@ gicv5_badwrite(const char *domain, uint64_t offset, uint64_t data, unsigned size\n gicv5_spi(uint32_t id, int level) \"GICv5 SPI ID %u asserted at level %d\"\n gicv5_ist_valid(const char *domain, uint64_t base, uint8_t id_bits, uint8_t l2_idx_bits, uint8_t istsz, bool structure) \"GICv5 IRS %s IST now valid: base 0x%\" PRIx64 \" id_bits %u l2_idx_bits %u IST entry size %u 2-level %d\"\n gicv5_ist_invalid(const char *domain) \"GICv5 IRS %s IST no longer valid\"\n+gicv5_set_priority(const char *domain, const char *type, bool virtual, uint32_t id, uint8_t priority) \"GICv5 IRS SetPriority %s %s virtual:%d ID %u prio %u\"\n \n # arm_gicv5_common.c\n gicv5_common_realize(uint32_t irsid, uint32_t num_cpus, uint32_t spi_base, uint32_t spi_irs_range, uint32_t spi_range) \"GICv5 IRS realized: IRS ID %u, %u CPUs, SPI base %u, SPI IRS range %u, SPI range %u\"\ndiff --git a/include/hw/intc/arm_gicv5.h b/include/hw/intc/arm_gicv5.h\nindex f6ecd9c323..c631ecc3e8 100644\n--- a/include/hw/intc/arm_gicv5.h\n+++ b/include/hw/intc/arm_gicv5.h\n@@ -19,6 +19,7 @@ OBJECT_DECLARE_TYPE(GICv5, GICv5Class, ARM_GICV5)\n \n typedef struct GICv5ISTConfig {\n hwaddr base; /* Base address */\n+ MemTxAttrs txattrs; /* TX attrs to use for this table */\n uint8_t id_bits; /* number of bits in an ID for this table */\n uint8_t l2_idx_bits; /* number of ID bits that index into L2 table */\n uint8_t istsz; /* L2 ISTE size in bytes */\ndiff --git a/include/hw/intc/arm_gicv5_stream.h b/include/hw/intc/arm_gicv5_stream.h\nindex 7257ddde90..e1649cbb40 100644\n--- a/include/hw/intc/arm_gicv5_stream.h\n+++ b/include/hw/intc/arm_gicv5_stream.h\n@@ -12,6 +12,7 @@\n #define HW_INTC_ARM_GICV5_STREAM_H\n \n #include \"target/arm/cpu-qom.h\"\n+#include \"hw/intc/arm_gicv5_types.h\"\n \n typedef struct GICv5Common GICv5Common;\n \n@@ -29,4 +30,32 @@ typedef struct GICv5Common GICv5Common;\n */\n bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs);\n \n+/*\n+ * The architected Stream Protocol is asynchronous; commands can be\n+ * initiated both from the IRS and from the CPU interface, and some\n+ * require acknowledgement. For QEMU, we simplify this because we know\n+ * that in the CPU interface code we hold the BQL and so our IRS model\n+ * is not going to be busy; when we send commands from the CPUIF\n+ * (\"upstream commands\") we can model this as a synchronous function\n+ * call whose return corresponds to the acknowledgement of a completed\n+ * command.\n+ */\n+\n+/**\n+ * gicv5_set_priority\n+ * @cs: GIC IRS to send command to\n+ * @id: interrupt ID\n+ * @priority: priority to set\n+ * @domain: interrupt Domain to act on\n+ * @type: interrupt type (LPI or SPI)\n+ * @virtual: true if this is a virtual interrupt\n+ *\n+ * Set priority of an interrupt; matches stream interface SetPriority\n+ * command from CPUIF to IRS. There is no report back of\n+ * success/failure to the CPUIF in the protocol.\n+ */\n+void gicv5_set_priority(GICv5Common *cs, uint32_t id,\n+ uint8_t priority, GICv5Domain domain,\n+ GICv5IntType type, bool virtual);\n+\n #endif\ndiff --git a/include/hw/intc/arm_gicv5_types.h b/include/hw/intc/arm_gicv5_types.h\nindex 7d23752ece..e2b937fe62 100644\n--- a/include/hw/intc/arm_gicv5_types.h\n+++ b/include/hw/intc/arm_gicv5_types.h\n@@ -45,4 +45,14 @@ typedef enum GICv5Domain {\n #define GICV5_PPI_CNTP 30\n #define GICV5_PPI_TRBIRQ 31\n \n+/*\n+ * Type of the interrupt; these values match the 3-bit format\n+ * specified in the GICv5 spec R_GYVWB.\n+ */\n+typedef enum GICv5IntType {\n+ GICV5_PPI = 1,\n+ GICV5_LPI = 2,\n+ GICV5_SPI = 3,\n+} GICv5IntType;\n+\n #endif\n", "prefixes": [ "v2", "18/65" ] }