Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2229569/?format=api
{ "id": 2229569, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229569/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260428083119.1400110-1-gs_liugan@163.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/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": "" }, "msgid": "<20260428083119.1400110-1-gs_liugan@163.com>", "date": "2026-04-28T08:31:18", "name": "hw/intc/arm_gicv3: Fix NS write to ICC_AP1Rn_EL1 when prebits < 7", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "08b95020fe31850d8bd2270d2cd657a067c53bec", "submitter": { "id": 93270, "url": "http://patchwork.ozlabs.org/api/1.1/people/93270/?format=api", "name": "liugan1", "email": "gs_liugan@163.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260428083119.1400110-1-gs_liugan@163.com/mbox/", "series": [ { "id": 501855, "url": "http://patchwork.ozlabs.org/api/1.1/series/501855/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501855", "date": "2026-04-28T08:31:18", "name": "hw/intc/arm_gicv3: Fix NS write to ICC_AP1Rn_EL1 when prebits < 7", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/501855/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2229569/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2229569/checks/", "tags": {}, "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 (1024-bit key;\n unprotected) header.d=163.com header.i=@163.com header.a=rsa-sha256\n header.s=s110527 header.b=eOi4rsRL;\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=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.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 4g4hL12LhZz1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 23:36:41 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHibT-0005Wm-Uj; Tue, 28 Apr 2026 09:35:55 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <gs_liugan@163.com>)\n id 1wHdrg-00088S-46; Tue, 28 Apr 2026 04:32:20 -0400", "from m16.mail.163.com ([117.135.210.3])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <gs_liugan@163.com>)\n id 1wHdrZ-0004Ay-9Z; Tue, 28 Apr 2026 04:32:19 -0400", "from PC-YLX4Y6J2.company.local (unknown [])\n by gzga-smtp-mtada-g1-1 (Coremail) with SMTP id\n _____wCHeop0cPBplDlxCA--.30779S2;\n Tue, 28 Apr 2026 16:31:49 +0800 (CST)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;\n s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=nd\n INuL6QIvXx9NNGe9DLNHQgIRcEsSwATo/VEV4bvgc=; b=eOi4rsRL7Tddem8R/u\n pAx64XiyAalnpSC/G07nFxBA+l4WOS16/fS6BZK7oz78iMK7rP/GNJgIWKjVzGmt\n 6NKJ22IcHR8OAcSKeT0vCQCvvUdz9jeNAb+i11Am9Su0LwbHAYjoZBa7fLETuhh1\n g8Vh7Sa9y3z82E28Xh2iNMZ1U=", "From": "liugan1 <gs_liugan@163.com>", "To": "qemu-devel@nongnu.org", "Cc": "qemu-arm@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,\n liugan1 <liugan1@lixiang.com>", "Subject": "[PATCH] hw/intc/arm_gicv3: Fix NS write to ICC_AP1Rn_EL1 when prebits\n < 7", "Date": "Tue, 28 Apr 2026 16:31:18 +0800", "Message-ID": "<20260428083119.1400110-1-gs_liugan@163.com>", "X-Mailer": "git-send-email 2.50.1", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-CM-TRANSID": "_____wCHeop0cPBplDlxCA--.30779S2", "X-Coremail-Antispam": "1Uf129KBjvJXoWxJF1fGw1DWry7tw1ftFW5Jrb_yoWrAFykpF\n s3G34fur4kt3WSvwsxtF4UZFyF9FZ5XF45CrsrK34UCrn8AF18Xw4akFyYk34jkr4DJF1a\n qrn0vrWkuFZ8XFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2\n 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jCQ6LUUUUU=", "X-Originating-IP": "[220.248.55.69]", "X-CM-SenderInfo": "xjvbzxhxjd0qqrwthudrp/xtbC5BbP-WnwcHZjxQAA35", "Received-SPF": "pass client-ip=117.135.210.3; envelope-from=gs_liugan@163.com;\n helo=m16.mail.163.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, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001,\n UNPARSEABLE_RELAY=0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-Mailman-Approved-At": "Tue, 28 Apr 2026 09:35:54 -0400", "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": "From: liugan1 <liugan1@lixiang.com>\n\nThe existing code uses a blanket `regno < 2` check to make\nICC_AP1R0_EL1 and ICC_AP1R1_EL1 writes from Non-secure code WI\n(Write Ignore) when EL3 is present. This is intended to prevent\nNS code from claiming active interrupts in the Secure priority\nrange, which could block Secure interrupt delivery.\n\nHowever, that check assumes prebits=7 (4 APR registers), where the\nNS priority range (128..255) maps entirely to AP1R2/AP1R3. Since\ncommit 39f29e599355 (\"hw/intc/arm_gicv3: Use correct number of\npriority bits for the CPU\", first in 7.1), all QEMU AArch64 CPUs\nare initialised with gic_pribits=5 (one APR register), so NS\npriorities map to AP1R0 bits [16:31]. Blanket WI of the entire\nAP1R0 register prevents NS code from clearing its own NS active\npriority bits. Machines using hw_compat_7_0 (e.g. virt-7.0) still\nforce pribits=8 via force-8-bit-prio and are therefore unaffected.\n\nA concrete consequence observed in virtualisation scenarios: when\na guest VM acknowledges an SPI interrupt but does not perform EOI,\nis force-killed and restarted, the new guest's attempt to clear\nthe residual active state by writing ICC_AP1R0_EL1=0 is silently\nignored. The running priority (RPR) remains stuck at the old\ninterrupt's priority, preventing all equal-or-lower priority\ninterrupts (including timer interrupts) from being delivered, and\nhanging the guest.\n\nFix this by computing the exact Secure/NS boundary within the APR\nbank based on prebits. For registers entirely in the Secure range,\nkeep the WI behaviour. For the register that straddles the\nboundary, preserve only the Secure bits while allowing NS bits to\nbe modified. For registers entirely in the NS range, allow full\nwrite access.\n\nThe new logic produces identical behaviour to the old code when\nprebits=7, preserving existing behaviour for machines that use\nforce-8-bit-prio.\n\nFixes: 39f29e599355 (\"hw/intc/arm_gicv3: Use correct number of priority bits for the CPU\")\nSigned-off-by: liugan1 <liugan1@lixiang.com>\n---\n hw/intc/arm_gicv3_cpuif.c | 35 +++++++++++++++++++++++++++++++++--\n 1 file changed, 33 insertions(+), 2 deletions(-)", "diff": "diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c\nindex fcb3922fa0..921d1fdfde 100644\n--- a/hw/intc/arm_gicv3_cpuif.c\n+++ b/hw/intc/arm_gicv3_cpuif.c\n@@ -1869,9 +1869,40 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,\n * at a priority outside the Non-secure range (128..255), since this\n * would otherwise allow malicious NS code to block delivery of S interrupts\n * by writing a bad value to these registers.\n+ *\n+ * The NS priority range (128..255) maps to APR bits starting at\n+ * aprbit = 0x80 >> (8 - prebits). Depending on prebits, this boundary\n+ * may fall within AP1R0 or AP1R1, so we cannot simply WI the entire\n+ * register. Instead we calculate which bits within each register\n+ * correspond to the Secure range and preserve those, while allowing\n+ * NS code to modify only the NS range bits.\n+ *\n+ * prebits=4: num_aprs=1, NS starts at AP1R0[8]\n+ * prebits=5: num_aprs=1, NS starts at AP1R0[16]\n+ * prebits=6: num_aprs=2, NS starts at AP1R1[0]\n+ * prebits=7: num_aprs=4, NS starts at AP1R2[0]\n */\n- if (grp == GICV3_G1NS && regno < 2 && arm_feature(env, ARM_FEATURE_EL3)) {\n- return;\n+ if (grp == GICV3_G1NS && arm_feature(env, ARM_FEATURE_EL3)) {\n+ int ns_start_bit = 0x80 >> (8 - cs->prebits);\n+ int ns_start_regno = ns_start_bit / 32;\n+ int ns_start_regbit = ns_start_bit % 32;\n+\n+ if (regno < ns_start_regno) {\n+ /* This entire register is in the Secure range: WI */\n+ return;\n+ } else if (regno == ns_start_regno && ns_start_regbit > 0) {\n+ /*\n+ * This register is split: low bits are Secure, high bits are NS.\n+ * Preserve the Secure bits (below ns_start_regbit) from the\n+ * current value, and take the NS bits (at and above\n+ * ns_start_regbit) from the written value.\n+ */\n+ uint32_t secure_mask = MAKE_64BIT_MASK(0, ns_start_regbit);\n+\n+ value = (cs->icc_apr[grp][regno] & secure_mask) |\n+ (value & ~secure_mask);\n+ }\n+ /* else: regno > ns_start_regno, entire register is NS: allow write */\n }\n \n if (cs->nmi_support) {\n", "prefixes": [] }