{"id":2220036,"url":"http://patchwork.ozlabs.org/api/patches/2220036/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260406025828.22909-1-huzy4@chinatelecom.cn/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/projects/14/?format=json","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":"<20260406025828.22909-1-huzy4@chinatelecom.cn>","list_archive_url":null,"date":"2026-04-06T02:58:28","name":"[RFC] hw/i386/pc: split ram-below-4g at 1MB and prevent cross-boundary merging","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"599af3c78a454bcc8f5087484e69886e3138ddcd","submitter":{"id":93066,"url":"http://patchwork.ozlabs.org/api/people/93066/?format=json","name":"Zhiyu Hu","email":"huzy4@chinatelecom.cn"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260406025828.22909-1-huzy4@chinatelecom.cn/mbox/","series":[{"id":498817,"url":"http://patchwork.ozlabs.org/api/series/498817/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=498817","date":"2026-04-06T02:58:28","name":"[RFC] hw/i386/pc: split ram-below-4g at 1MB and prevent cross-boundary merging","version":1,"mbox":"http://patchwork.ozlabs.org/series/498817/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2220036/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2220036/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 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 4fpvss0btNz1yFt\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 06 Apr 2026 13:28:01 +1000 (AEST)","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 1w9acm-000245-Uv; Sun, 05 Apr 2026 23:27:40 -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 <huzy4@chinatelecom.cn>)\n id 1w9aKA-0003H2-Ud\n for qemu-devel@nongnu.org; Sun, 05 Apr 2026 23:08:26 -0400","from smtph3-04.21cn.com ([150.223.194.106])\n by eggs.gnu.org with esmtp (Exim 4.90_1)\n (envelope-from <huzy4@chinatelecom.cn>) id 1w9aK7-00063R-4N\n for qemu-devel@nongnu.org; Sun, 05 Apr 2026 23:08:26 -0400","from clientip-58.37.193.6 (unknown [172.27.0.101])\n by smtph3-04.21cn.com (HERMES) with SMTP id 08853C00D314;\n Mon,  6 Apr 2026 10:59:11 +0800 (CST)","from  ([58.37.193.6])\n by gateway-ssl-dep-548b9f977f-v2mf7 with ESMTP id\n e731eab87c1e44fc871898a7b02ae7df for qemu-devel@nongnu.org;\n Mon, 06 Apr 2026 10:59:22 CST"],"HMM_SOURCE_IP":"172.27.0.101:0.1262061526","HMM_ATTACHE_NUM":"0000","HMM_SOURCE_TYPE":"SMTP","X-189-SAVE-TO-SEND":"+huzy4@chinatelecom.cn","X-Transaction-ID":"e731eab87c1e44fc871898a7b02ae7df","X-Real-From":"huzy4@chinatelecom.cn","X-Receive-IP":"58.37.193.6","X-MEDUSA-Status":"0","From":"Zhiyu Hu <huzy4@chinatelecom.cn>","To":"qemu-devel@nongnu.org","Cc":"pbonzini@redhat.com, richard.henderson@linaro.org, mst@redhat.com,\n marcel.apfelbaum@gmail.com, peterx@redhat.com, philmd@linaro.org,\n Zhiyu Hu <huzy4@chinatelecom.cn>","Subject":"[RFC PATCH] hw/i386/pc: split ram-below-4g at 1MB and prevent\n cross-boundary merging","Date":"Mon,  6 Apr 2026 02:58:28 +0000","Message-ID":"<20260406025828.22909-1-huzy4@chinatelecom.cn>","X-Mailer":"git-send-email 2.43.0","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Received-SPF":"pass client-ip=150.223.194.106;\n envelope-from=huzy4@chinatelecom.cn; helo=smtph3-04.21cn.com","X-Spam_score_int":"-18","X-Spam_score":"-1.9","X-Spam_bar":"-","X-Spam_report":"(-1.9 / 5.0 requ) BAYES_00=-1.9,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-Mailman-Approved-At":"Sun, 05 Apr 2026 23:27:38 -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":"Split ram-below-4g into ram-below-1m and ram-1m-to-below-4g at the\n1MB boundary in pc_memory_init().\n\nAlso prevent flatview_simplify() from merging FlatRanges across the\n1MB boundary by adding a boundary check in can_merge(). Without this,\nPAM attribute changes below 1MB cause the below-1MB range to re-merge\nwith the above-1MB range, triggering VFIO to unmap/remap the entire\nmerged region and creating a transient IOMMU mapping hole for active\ndevice DMA (e.g. virtio-blk virtqueues) above 1MB.\n\nSigned-off-by: Zhiyu Hu <huzy4@chinatelecom.cn>\n---\n hw/i386/pc.c    | 30 +++++++++++++++++++++++++++---\n system/memory.c | 13 +++++++++++++\n 2 files changed, 40 insertions(+), 3 deletions(-)","diff":"diff --git a/hw/i386/pc.c b/hw/i386/pc.c\nindex 4b53b5be4a..4e9823e46f 100644\n--- a/hw/i386/pc.c\n+++ b/hw/i386/pc.c\n@@ -790,11 +790,35 @@ void pc_memory_init(PCMachineState *pcms,\n     /*\n      * Split single memory region and use aliases to address portions of it,\n      * done for backwards compatibility with older qemus.\n+     *\n+     * Further split the below-4g region at the 1MB boundary so that PAM\n+     * register updates (which only affect 0xC0000-0xFFFFF) do not cause\n+     * the VFIO DMA listener to unmap/remap the entire below-4g range.\n+     * This avoids a transient IOMMU mapping hole for virtqueue memory\n+     * (above 1MB) when the BIOS reconfigures PAM during early boot.\n      */\n     ram_below_4g = g_malloc(sizeof(*ram_below_4g));\n-    memory_region_init_alias(ram_below_4g, NULL, \"ram-below-4g\", machine->ram,\n-                             0, x86ms->below_4g_mem_size);\n-    memory_region_add_subregion(system_memory, 0, ram_below_4g);\n+    if (x86ms->below_4g_mem_size <= 0x100000) {\n+        memory_region_init_alias(ram_below_4g, NULL, \"ram-below-4g\",\n+                                 machine->ram,\n+                                 0, x86ms->below_4g_mem_size);\n+        memory_region_add_subregion(system_memory, 0, ram_below_4g);\n+    } else {\n+        MemoryRegion *ram_above_1m = g_malloc(sizeof(*ram_above_1m));\n+\n+        /* 0 ~ 1MB: affected by PAM/SMRAM overlays */\n+        memory_region_init_alias(ram_below_4g, NULL, \"ram-below-1m\",\n+                                 machine->ram,\n+                                 0, 0x100000);\n+        memory_region_add_subregion(system_memory, 0, ram_below_4g);\n+\n+        /* 1MB ~ below_4g_mem_size: not affected by PAM updates */\n+        memory_region_init_alias(ram_above_1m, NULL, \"ram-1m-to-below-4g\",\n+                                 machine->ram,\n+                                 0x100000,\n+                                 x86ms->below_4g_mem_size - 0x100000);\n+        memory_region_add_subregion(system_memory, 0x100000, ram_above_1m);\n+    }\n     e820_add_entry(0, x86ms->below_4g_mem_size, E820_RAM);\n     if (x86ms->above_4g_mem_size > 0) {\n         ram_above_4g = g_malloc(sizeof(*ram_above_4g));\ndiff --git a/system/memory.c b/system/memory.c\nindex 56f3225b21..28fc12e992 100644\n--- a/system/memory.c\n+++ b/system/memory.c\n@@ -321,6 +321,19 @@ void flatview_unref(FlatView *view)\n \n static bool can_merge(FlatRange *r1, FlatRange *r2)\n {\n+    /*\n+     * Do not merge ranges across the 1MB (0x100000) boundary.\n+     * PAM/SMRAM overlays frequently change attributes below 1MB,\n+     * and merging with the large RAM region above 1MB would cause\n+     * VFIO to unmap/remap the entire merged range on every PAM\n+     * update, creating a transient IOMMU mapping hole for device\n+     * DMA (e.g. virtio-blk virtqueues) in the above-1MB region.\n+     */\n+    if (int128_lt(r1->addr.start, int128_make64(0x100000))\n+        && int128_ge(r2->addr.start, int128_make64(0x100000))) {\n+        return false;\n+    }\n+\n     return int128_eq(addrrange_end(r1->addr), r2->addr.start)\n         && r1->mr == r2->mr\n         && int128_eq(int128_add(int128_make64(r1->offset_in_region),\n","prefixes":["RFC"]}