get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2196577,
    "url": "http://patchwork.ozlabs.org/api/patches/2196577/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260215084950.4657-4-ankita@nvidia.com/",
    "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": "<20260215084950.4657-4-ankita@nvidia.com>",
    "list_archive_url": null,
    "date": "2026-02-15T08:49:50",
    "name": "[v3,3/3] hw/vfio: align mmap to power-of-2 of region size for hugepfnmap",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "46a893c5a0880845818a1d2fafa1a06e144eb6ee",
    "submitter": {
        "id": 86155,
        "url": "http://patchwork.ozlabs.org/api/people/86155/?format=api",
        "name": "Ankit Agrawal",
        "email": "ankita@nvidia.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260215084950.4657-4-ankita@nvidia.com/mbox/",
    "series": [
        {
            "id": 492205,
            "url": "http://patchwork.ozlabs.org/api/series/492205/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=492205",
            "date": "2026-02-15T08:49:48",
            "name": "hw/vfio: Enable hugepfnmap for non-power-of-2 device memory regions",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/492205/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196577/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196577/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=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256\n header.s=selector2 header.b=ZVgF8iyg;\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 4fDKWf3LFsz1xpY\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 15 Feb 2026 19:56:12 +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 1vrXub-00024N-Am; Sun, 15 Feb 2026 03:55:29 -0500",
            "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 <ankita@nvidia.com>) id 1vrXuM-0001yO-D6\n for qemu-devel@nongnu.org; Sun, 15 Feb 2026 03:55:17 -0500",
            "from mail-westcentralusazon11013057.outbound.protection.outlook.com\n ([40.93.201.57] helo=CY3PR05CU001.outbound.protection.outlook.com)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <ankita@nvidia.com>) id 1vrXuI-0003L4-W0\n for qemu-devel@nongnu.org; Sun, 15 Feb 2026 03:55:13 -0500",
            "from BYAPR21CA0026.namprd21.prod.outlook.com (2603:10b6:a03:114::36)\n by SJ0PR12MB6943.namprd12.prod.outlook.com (2603:10b6:a03:44b::11)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9611.15; Sun, 15 Feb\n 2026 08:50:04 +0000",
            "from MWH0EPF000C6185.namprd02.prod.outlook.com\n (2603:10b6:a03:114:cafe::5) by BYAPR21CA0026.outlook.office365.com\n (2603:10b6:a03:114::36) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9632.10 via Frontend Transport; Sun,\n 15 Feb 2026 08:50:04 +0000",
            "from mail.nvidia.com (216.228.117.160) by\n MWH0EPF000C6185.mail.protection.outlook.com (10.167.249.117) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.9632.12 via Frontend Transport; Sun, 15 Feb 2026 08:50:04 +0000",
            "from rnnvmail203.nvidia.com (10.129.68.9) by mail.nvidia.com\n (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Sun, 15 Feb\n 2026 00:49:52 -0800",
            "from rnnvmail204.nvidia.com (10.129.68.6) by rnnvmail203.nvidia.com\n (10.129.68.9) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Sun, 15 Feb\n 2026 00:49:52 -0800",
            "from localhost.nvidia.com (10.127.8.12) by mail.nvidia.com\n (10.129.68.6) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20 via Frontend\n Transport; Sun, 15 Feb 2026 00:49:51 -0800"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=MDZ2N9HVJ/i3Na0VquYoF+NQkGF1h17xi4igk27+Cdmslh4sgoOccNiRlgjYibxQqy+7tX2m1qRxsP7+MB8rIy6Rct/ZhnYu6qsM5n3oVSU334SBfNj9MGS6MFGLA0+0TCwALpyYnnE1WHBIH76rhRj8D/uzMYtbc+vmDSE/Yx18thkovIXrPXHu8ONM871/51QP2/7OFoxYtw4Jl3J4ZEq8rFrETP2VFgJ6O0y3FEglLpBibKIg/yJ1v2NZcdAuL7YM3cDVILFlzNm7n/wNzJGOdgv/o/7Q4YTaDcEp7Q665vKysO1bNHZ/2B2qoX9of6idlZpNfGKrYp4O9+Ulxg==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=CCtaeA+J9txp0JDlPfz3mNWLzYpinIGsU51LoSBjUhs=;\n b=k6uGc8uxhQsN9GrLBVFeIKVKr1Gv86Zs3ncbMPaPeYACW26qph1SL0rel/WHvJlgOre6S1VzME4SWYOZKEdqjVk/zxij2J4R769w90YiDBZJijvwRVnaA0k8tKWigCAu6aqY7nukuPiaKiUUy62RLACFlUGA+3TdKC32dLFGdK1Z7F7nSlKLe54hCNCyBMWLqz2qqBwPA4XFkARhIj+aU0NtYmL4Z8p4HKp95nQT/1L8/Re446IZL9l+t88i4mUhGbLEwDZ53IfaudieKuKLE1oHFpOq4/h08N7MpTE3XyBC8v7uorOnYULhfUo4nMiF550Nr/TDT0N2d6dDNUsbPA==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 216.228.117.160) smtp.rcpttodomain=shazbot.org smtp.mailfrom=nvidia.com;\n dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com;\n dkim=none (message not signed); arc=none (0)",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=CCtaeA+J9txp0JDlPfz3mNWLzYpinIGsU51LoSBjUhs=;\n b=ZVgF8iyg0g4QpsOHzcGjembhdiYdnzjrbUpevrpEbh8lIrGCF6TCgj5bM5IzxmSwRLocglHs0iXDcrUlLKjAfG3osqd0gON6rAkaT7UiXZbS2Zu1RakMEwUO/byuqA8pvEa4cpm/mYhoQoS0xIKdWlQz1FVonrjB1D8FO1UkyvJb5+I5v0n40Nt/aBR4ken6PC6xbWtaz5OX7T5qN9xjc0qZ8BEM59CLiK/UrqhyCBAZAwE9oaTJqMtWQqlfXfcMBv1FPu4oS/il7A1ZcgHgCTW5YIB+0mLOypsn9+2uLJM8hQMDEBlCEGb1bGmXUVRrjdcWNkrMJZFErUlMK/LA0A==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 216.228.117.160)\n smtp.mailfrom=nvidia.com;\n dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": [
            "Pass (protection.outlook.com: domain of nvidia.com designates\n 216.228.117.160 as permitted sender) receiver=protection.outlook.com;\n client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C",
            "permerror client-ip=40.93.201.57;\n envelope-from=ankita@nvidia.com;\n helo=CY3PR05CU001.outbound.protection.outlook.com"
        ],
        "From": "<ankita@nvidia.com>",
        "To": "<ankita@nvidia.com>, <vsethi@nvidia.com>, <jgg@nvidia.com>,\n <skolothumtho@nvidia.com>, <alex@shazbot.org>, <clg@redhat.com>",
        "CC": "<aniketa@nvidia.com>, <cjia@nvidia.com>, <kwankhede@nvidia.com>,\n <targupta@nvidia.com>, <zhiw@nvidia.com>, <mochs@nvidia.com>,\n <kjaju@nvidia.com>, <qemu-devel@nongnu.org>",
        "Subject": "[PATCH v3 3/3] hw/vfio: align mmap to power-of-2 of region size for\n hugepfnmap",
        "Date": "Sun, 15 Feb 2026 08:49:50 +0000",
        "Message-ID": "<20260215084950.4657-4-ankita@nvidia.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20260215084950.4657-1-ankita@nvidia.com>",
        "References": "<20260215084950.4657-1-ankita@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-NV-OnPremToCloud": "ExternallySecured",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "MWH0EPF000C6185:EE_|SJ0PR12MB6943:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "1dc42f12-4d49-40f9-d133-08de6c6f36a6",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;\n ARA:13230040|82310400026|36860700013|1800799024|376014|7053199007;",
        "X-Microsoft-Antispam-Message-Info": "\n NlE2RKnzOdX5P3jTLtDyVrJFw1EZwpCw65dxzOB0E5ihQgHNro89PQuAfnpJJ9J8OqCIgNy2K696h+HpGxjiiA/6Si+s9R6QZjsPrvtLpN4ySJHW9ByfD51jek/YlJVHVOGMfEaZexWIGX4dIQIy0p+eiM09Zd+Hl+QEHw5/o7hDHaIzRXdryoyONH4jMzeDG+camzLQ3P+H91NOqeC5DLzDJAJwCtVQtY8FgGvcmP4VlTbEFXCe6dxlPrumRhame2GXbbB0l+LUH3gdZxE9C1U1chrtbF2QIb1Ub4/BoCXTf2kIr8LYX1gs8PNdkjj/QZh6J9SMIe0r+fWRpWyaefNk0WSKBcyUjVyRtDL3sJPjE/9c2K+l5yYdjY+gNOGtb9zNsXhyyXP+Qs3TpSHZhoQwmCDei6uSpbEpFHRDUsV3oPthAy+v6MwJH6YJ0PmnKMtDwQ2c+d4nHEUP6K7FC8cdX9i+ZV04JuIEPZiCBIB2aI9ea8UpuN1AKXDi0O6w9KhF7zLNKGxatWUtalQ6kzfIRVScOUfnSPfXQWg+EsqxzLi9y/byXQbvdalxYA9OcmoYZdHM9gnqe/nHLHsyKOQsTNDR6aFgJBrgKIBN6gP4FAcDkaF/w4eoMY0EnH75MSHAbKfRL+iTUD+3SvSktNA1HVQAQHJ4CtpGvOlstoX491pDdNwnk28m4DeWtFv7AjcBJJ4DW6hQ8a+THo+94F5/4v6+IFf65gu21pdgm9OEVZgGUxUgENRvN1DvRcMgXH5eTls66DTdetrQRcluL0AgMI+okGcRb6TRC2VGHfnOOjJJrZvfH7Ww9RMM2dexlBfHj7c89+7R51g8C8BOrNzV+F5bf2V9Iw9lcso3pRjwBQLgTmFPCPCFl49cIogDNJVKPXt1Svy7PFKQ2g/TyuEBDK+Ptag4+PT5uxfkmg+7puFuqCZaxWSANtrFYvqCR6OK34llohwDD1FsDbg7p4GPA6W+0fGAKFIIfogRqPZoayMMZSARR9CZFIsPXy+59IADd17dXNy1THO/bI1mSv/nm+NFio7jvlpLje6r7Cst4hkpHim3QzkGuuLlufzuu+k0a6vwjvTAIKekFDDiuLBTw1KdhmzyMOCTOP0QTLYWwxwNbCIikArWBRS77HhTuXwd6vcnEG3MYrsh1gEo4qym0eqtoniFpTmPL23H+Y7yGqdBHTbdXLxRdKGa2yFei4A83U+CUnFXSTK1hcWYycFyIj/Od4YA+g0UOSDL8RKriCae53/4Wc98QdaAXu3WKbdnqZmIe0v0b9dqJayB7F+8iBck0WqMWHw4mQCnmXadicZmfmHnXc/zr5n/YI1kYsToBiD2l5YzQB3gj7nywjDuGth3tPwmEa3xbMZhA5mOCGZzUJK8u7SdgeiDr6GfTFj2TDQAEYeywi+x7PH8dhLVX67/bx7qXIWab3x70nPTb0hF8qxPz9SoDRBwGMYH2UuW4Q1pUJ9yIq29JacE1JYI/HfW+xQURp09zmVoQjtF/6LHPD4G4n04nNH699K8tBJFirxMsfH6sdMGA+8XJZ7X9+45tGglJmFCBeeJZpXSiKnihH6Vs2FbDgwIQGptN7kSYRkMTLIeenJczHq/yuSuZGXvmu9xwmJj4o8ib+vMU0Hrutkss3EHrWeikButmuLfoDbe16CczrqHVSTy+g==",
        "X-Forefront-Antispam-Report": "CIP:216.228.117.160; CTRY:US; LANG:en; SCL:1;\n SRV:;\n IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:dc6edge1.nvidia.com; CAT:NONE;\n SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014)(7053199007);\n DIR:OUT; SFP:1101;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "\n TFYXJKJWkmnZW2IYd60BrGuBdyXw4iCeLRvmw9MwGDtyZQpEvY7gA+hNmXHhXSnOR5Ftvtoe8RKDGTb4dBJnvOTJAe4GI/sBe1cdqf/5FTNDtcOk21VDGsTEdox970oHxifggx6J7AEBDe1a9IdHnxiz9TbBnpIf4l0Sipw+/AWDroGNd28C/418F7/clcF1wWaZWHhYexXd5iBo70P/3u81fDYbOflt/Vgy0EgZT2zr1TTo9a77zYDXGZ3oPzShREihq74kSpAf+RfKliYVm1gII7lPQ0L2NgeFqgfUJPHoNYzt26ZK9YENbLvnWuKPqyO97y38J9jaolhHrIRdCkUXEVLq9nsr7TS699RpugAugfC/KNc+YIwSG9V+PEKJ/sn0qArMWmTGu7k365w1ZekaL6QFHk19q0+2D2nKZ6RReqlObIaRn57+TCrj2TCT",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "15 Feb 2026 08:50:04.5845 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 1dc42f12-4d49-40f9-d133-08de6c6f36a6",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.117.160];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n MWH0EPF000C6185.namprd02.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "SJ0PR12MB6943",
        "X-Spam_score_int": "-10",
        "X-Spam_score": "-1.1",
        "X-Spam_bar": "-",
        "X-Spam_report": "(-1.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=no 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": "From: Ankit Agrawal <ankita@nvidia.com>\n\nOn Grace-based systems such as GB200, device memory is exposed as a\nBAR but the actual mappable size is not power-of-2 aligned. The\nprevious algorithm aligned each sparse mmap area based on its\nindividual size using ctz64() which prevented efficient huge page\nusage by the kernel.\n\nAdjust VFIO region mapping alignment to use the next power-of-2 of\nthe total region size and place the sparse subregions at their\nappropriate offset. This provides better opportunities to get huge\nalignment allowing the kernel to use larger page sizes for the VMA.\n\nThis enables the use of PMD-level huge pages which can significantly\nimprove memory access performance and reduce TLB pressure for large\ndevice memory regions.\n\nWith this change:\n- Create a single aligned base mapping for the entire region\n- Change Alignment to be based on pow2ceil(region->size), capped at 1GiB\n- Unmap gaps between sparse regions\n- Use MAP_FIXED to overlay sparse mmap areas at their offsets\n\nExample VMA for device memory of size 0x2F00F00000 on GB200:\n\nBefore (misaligned, no hugepfnmap):\nff88ff000000-ffb7fff00000 rw-s 400000000000 00:06 727                    /dev/vfio/devices/vfio1\n\nAfter (aligned to 1GiB boundary, hugepfnmap enabled):\nff8ac0000000-ffb9c0f00000 rw-s 400000000000 00:06 727                    /dev/vfio/devices/vfio1\n\nRequires sparse regions to be sorted by offset (done in previous\npatch) to correctly identify and handle gaps.\n\ncc: Alex Williamson <alex@shazbot.org>\nReviewed-by: Alex Williamson <alex@shazbot.org>\nReviewed-by: Shameer Kolothum <skolothumtho@nvidia.com>\nSuggested-by: Jason Gunthorpe <jgg@nvidia.com>\nSigned-off-by: Ankit Agrawal <ankita@nvidia.com>\n---\n hw/vfio/region.c | 81 ++++++++++++++++++++++++++++++++----------------\n 1 file changed, 54 insertions(+), 27 deletions(-)",
    "diff": "diff --git a/hw/vfio/region.c b/hw/vfio/region.c\nindex b83b09fa2f..51523a33b1 100644\n--- a/hw/vfio/region.c\n+++ b/hw/vfio/region.c\n@@ -344,8 +344,11 @@ static bool vfio_region_create_dma_buf(VFIORegion *region, Error **errp)\n \n int vfio_region_mmap(VFIORegion *region)\n {\n-    int i, ret, prot = 0;\n+    void *map_base, *map_align;\n     Error *local_err = NULL;\n+    int i, ret, prot = 0;\n+    off_t map_offset = 0;\n+    size_t align;\n     char *name;\n     int fd;\n \n@@ -356,41 +359,56 @@ int vfio_region_mmap(VFIORegion *region)\n     prot |= region->flags & VFIO_REGION_INFO_FLAG_READ ? PROT_READ : 0;\n     prot |= region->flags & VFIO_REGION_INFO_FLAG_WRITE ? PROT_WRITE : 0;\n \n-    for (i = 0; i < region->nr_mmaps; i++) {\n-        size_t align = MIN(1ULL << ctz64(region->mmaps[i].size), 1 * GiB);\n-        void *map_base, *map_align;\n+    /*\n+     * Align the mmap for more efficient mapping in the kernel. Ideally\n+     * we'd know the PMD and PUD mapping sizes to use as discrete alignment\n+     * intervals, but we don't. As of Linux v6.19, the largest PUD size\n+     * supporting huge pfnmap is 1GiB (ARCH_SUPPORTS_PUD_PFNMAP is only set\n+     * on x86_64).\n+     *\n+     * Align by power-of-two of the size of the entire region - capped\n+     * by 1G - and place the sparse subregions at their appropriate offset.\n+     * This will get maximum alignment.\n+     *\n+     * NB. qemu_memalign() and friends actually allocate memory, whereas\n+     * the region size here can exceed host memory, therefore we manually\n+     * create an oversized anonymous mapping and clean it up for alignment.\n+     */\n \n-        /*\n-         * Align the mmap for more efficient mapping in the kernel.  Ideally\n-         * we'd know the PMD and PUD mapping sizes to use as discrete alignment\n-         * intervals, but we don't.  As of Linux v6.12, the largest PUD size\n-         * supporting huge pfnmap is 1GiB (ARCH_SUPPORTS_PUD_PFNMAP is only set\n-         * on x86_64).  Align by power-of-two size, capped at 1GiB.\n-         *\n-         * NB. qemu_memalign() and friends actually allocate memory, whereas\n-         * the region size here can exceed host memory, therefore we manually\n-         * create an oversized anonymous mapping and clean it up for alignment.\n-         */\n-        map_base = mmap(0, region->mmaps[i].size + align, PROT_NONE,\n-                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n-        if (map_base == MAP_FAILED) {\n-            ret = -errno;\n-            goto no_mmap;\n-        }\n+    align = MIN(pow2ceil(region->size), 1 * GiB);\n \n-        fd = vfio_device_get_region_fd(region->vbasedev, region->nr);\n+    map_base = mmap(0, region->size + align, PROT_NONE,\n+                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n+    if (map_base == MAP_FAILED) {\n+        ret = -errno;\n+        trace_vfio_region_mmap_fault(memory_region_name(region->mem), -1,\n+                                     region->fd_offset,\n+                                     region->fd_offset + region->size - 1, ret);\n+        return ret;\n+    }\n+\n+    fd = vfio_device_get_region_fd(region->vbasedev, region->nr);\n \n-        map_align = (void *)ROUND_UP((uintptr_t)map_base, (uintptr_t)align);\n-        munmap(map_base, map_align - map_base);\n-        munmap(map_align + region->mmaps[i].size,\n-               align - (map_align - map_base));\n+    map_align = (void *)ROUND_UP((uintptr_t)map_base, (uintptr_t)align);\n+    munmap(map_base, map_align - map_base);\n+    munmap(map_align + region->size,\n+           align - (map_align - map_base));\n \n-        region->mmaps[i].mmap = mmap(map_align, region->mmaps[i].size, prot,\n+    for (i = 0; i < region->nr_mmaps; i++) {\n+        munmap(map_align + map_offset, region->mmaps[i].offset - map_offset);\n+        region->mmaps[i].mmap = mmap(map_align + region->mmaps[i].offset,\n+                                     region->mmaps[i].size, prot,\n                                      MAP_SHARED | MAP_FIXED, fd,\n                                      region->fd_offset +\n                                      region->mmaps[i].offset);\n         if (region->mmaps[i].mmap == MAP_FAILED) {\n             ret = -errno;\n+            /*\n+             * Only unmap the rest of the region. Any mmaps that were successful\n+             * will be unmapped in no_mmap.\n+             */\n+            munmap(map_align + region->mmaps[i].offset,\n+                   region->size - region->mmaps[i].offset);\n             goto no_mmap;\n         }\n \n@@ -408,6 +426,15 @@ int vfio_region_mmap(VFIORegion *region)\n                                region->mmaps[i].offset,\n                                region->mmaps[i].offset +\n                                region->mmaps[i].size - 1);\n+\n+        map_offset = region->mmaps[i].offset + region->mmaps[i].size;\n+    }\n+\n+    /*\n+     * Unmap the rest of the region not covered by sparse mmap.\n+     */\n+    if (map_offset < region->size) {\n+        munmap(map_align + map_offset, region->size - map_offset);\n     }\n \n     if (!vfio_region_create_dma_buf(region, &local_err)) {\n",
    "prefixes": [
        "v3",
        "3/3"
    ]
}