From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265536; cv=pass; d=zohomail.com; s=zohoarc; b=XsW7C9B+NiA0JNpQ6WeBuG693rEHPgzLSlSNm/p8wKgEq0jH6ZD272ql2JcdyPE36liOroHXdr5bs6vz1Oi83sSFeK10eqqW1T5Mi3JsilXHHHIM5MOo4hyS5wv1sB7fozgGP40UHrYNEIlAVLArG4PQNjk4VTpGufsLRcdUfak= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265536; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wzeKAO+rXcuLDHgcb16pHML/zJ2nWk54OrooHG4hgVA=; b=BXQdd9/9PQIpbXX8rcu/9TqvBuI2STtZMAZkrWiS+YTZQOPJxVO/F3APDAX9rNovdB3a4mKJEY++6sWyTjRNsG18Z7swJ4I4W75KuU4JtSnMVOjz67jVrQEPt+Kr4+qNORCQuCENBflpn4m8c/UVNEkHilaYIK0NHb3zGSquSQo= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265536612839.5551865343352; Fri, 8 May 2026 11:38:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5K-0006fF-Gb; Fri, 08 May 2026 14:38:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5E-0006eZ-AE; Fri, 08 May 2026 14:37:56 -0400 Received: from mail-centralusazlp170100005.outbound.protection.outlook.com ([2a01:111:f403:c111::5] helo=DM1PR04CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5C-0002Yg-KO; Fri, 08 May 2026 14:37:56 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by CH3PR12MB8482.namprd12.prod.outlook.com (2603:10b6:610:15b::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.20; Fri, 8 May 2026 18:37:44 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:44 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xxKkGqmuuIs63zltx+H8jpj467ES8n7KOtXzXPIwM02/dd1mEI1MBXBT8s+WezDQnHMMyNuqu562eBqBXVqNOMW5jJhhPB7rn4QS6pQU4bMuW0kRp674LkGgD0YQxjj1gSGThHorCXr3pSoZo5oyUoBf7NTSm8CgYuxUcEt/qINEivYsL2ZEXgXD9lHmhwEfczFn560/O8hKlN89SFhwDuJdKET/fS+Kyp7djfYOLyaD5jnW2+C77P9qCmEXz3VCSzUFNARwDXurCrJn8gQowPUJfqWeXppPWD/J/rdMStrwRjOT/Lay+WYC1H7lDfKB+UnUON9VOGe/v6QlXvo5mw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=wzeKAO+rXcuLDHgcb16pHML/zJ2nWk54OrooHG4hgVA=; b=Or9KA3WQ6FMsrXolc7Pj/AxJkQMbBeUESYatqwg4KYveKDz66cuLOTWgo9+YBFa47KRPW9vhOR2nH9tGiONCk46zfCBNijXG3qpU8gqJpX04hJzF5bDDWBncAXmC9iat4uQGtWV/Cb17f8tX+4ZT7CFiVu9cvyAmQXe58WJRvL9CHvywXwMvhFCUJredf9sDJf4lFXwkctI6+Th1C2MNITOKMVCKChsfyRC7cF6WOszt8Kf9N4Hjhc5RS7gaKLWV8bPDhrI0GKztaOTwRJHz7TlugQDiId/B5yy1hCWY4InbdIIUsfBDeUcDlFqHMsydsZrOLoZfQ/+O4w/itPaIRg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=wzeKAO+rXcuLDHgcb16pHML/zJ2nWk54OrooHG4hgVA=; b=gszBdSVTpMaxoxdwTiSq6obN3yvUfnJgL0y5yfBQa2TLLjxpGyFZjnOzStycrK6u1WQY33atEqA1WCtGJKA19PJDXWRuZmfokJh+wMZq/KgDPMUGUNH8SJlgMoh5aXKNfEGzEwvtehNyuZHx88ohFHdAvscnL6MPYiSr2ijYanykyOuL4bk6gFoPj8f5kSePtKDeq12PayE64jmd6B7k37DxwOt3erxq/y2JUAWCIdRvgvQpa7892e/Z65F1A4KTD3w4eTjaVAV4jRy6WjtBXA+6MHDdm7uFFrjhD3JMOUZ6eCfE1WUlV46CayNd65gA/K0u2TDqIdUNZW1rn/zMsA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 1/8] hw/pci: add fixed-bars property to allow fixed BAR addresses Date: Fri, 8 May 2026 13:37:10 -0500 Message-Id: <20260508183717.193630-2-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0PR04CA0029.namprd04.prod.outlook.com (2603:10b6:208:52d::34) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|CH3PR12MB8482:EE_ X-MS-Office365-Filtering-Correlation-Id: 367e1f7f-9c98-4194-e3b4-08dead30e349 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|376014|1800799024|18002099003|56012099003|22082099003; X-Microsoft-Antispam-Message-Info: 0pb1G/CMYMLLce3OgjPr7PH4yHgqHV2y3ELixEVaSgl1O22hP0GXcz/ESaWd8bEMxRg5P2vjABtOKcMYabBgatwmiUij+IRPLB8G/8/L578h/S5CcNdXjCPFug1NlF1OuE3DKp6n3m0Rm3X5ijiX/CDxaUsDhUyv01ek7YoDzJjdOoeOmGdW8lZItkucuiIUdikGnBoqad5qDQs5m8UwJ/+BckEGviJ0IDZSl0PAfgHw+8YY+iSAqn6pT3iV6tLjGHOjg4w/JwTKxOSLDYXN1NxVZTe76WX3VWgOfXA1NNgTtpFZxqolrdZqFQDaiK4yQhK/KdT1f2mrn0qFShG3gZ4MsQ3Xfvzo/RcRpj4Jy3vCSZRpsd4qvp23GZZSTg9VCetjC6upCvpsROq6VJ1sPOR6yfJJ4hgIdS/sEnX69kSeeITU0eVh04HxSsWuRz8gLIG+bF1vOKTgP8cy0HFMtP8dK3ptezFpklw3R69X8khdPKuQR3ybmrSxjSOJ/Y66+qB8VW4g1FHz3eJJ31tlt5zTHJdH5j1np0vSFQKS607p76RH2ZmsWk6W4YQXUVVOAB9vNyqTmgUjufUxNkhn8XyGHnXGtLlvnCrgAJe6mmP/tIbPSMaj97w1FqLhTInMckyCypmdNtce30fYTFP2C4U6SI9H6+q8JuWFzSTLgo2dTK3xMYx/rBkjwbL6vzg9 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(376014)(1800799024)(18002099003)(56012099003)(22082099003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Ry/S1oklQYrbDDv5qYtbAmtRiRwsF6EF+zzV4UVIr9/+N56+bWSM9hphlYp0?= =?us-ascii?Q?bHj8MkEEdXbQG117itWj42LRxBBA9k0zzL95ZmfeIaL/8Y33qbK3tcHieCBM?= =?us-ascii?Q?1ja4H74ftJBp52QETZ18RafcS2NzcB+EslQvOAv62Xxlt+DsmTlfNBsw0HVj?= =?us-ascii?Q?Sn4jhEsfdODQ0IcQvd/Or6CtkSmk5+if7g8kE+a3lt6vRnGjCHEiq/MeKTWj?= =?us-ascii?Q?HfkfSgy349HwqQmyRn+ST8WSKpey/3GXD5c38kOiOmmQ/Pahze/gEqJGbEHB?= =?us-ascii?Q?NmIC22M4NgZmRaUwj5fS+ahHtDst9TJqzPdBUVakAsmwYh1FaZWZUS9eEpBx?= =?us-ascii?Q?s+4egGspg0BsO7a7ykp47wV03O9lDsRtYr40+wqV0rAsNuEYPMFA10L+IOpj?= =?us-ascii?Q?h662b/OC/ipXYEj0DEuIydHd9JbFVrckDYOnT1C842vioXcx0PVcBgECvvG1?= =?us-ascii?Q?F+Q0Z7bJQ19Q5bPHdNOQKiyTGh2ixaa16WjYcsuZ4FGznRgxQZkn3AGNTVrV?= =?us-ascii?Q?4nHVO02/q0M10+VYaaoj8chjhkOQLjqsCqjESrpeic0TG7UA8pGr5nJYRkHh?= =?us-ascii?Q?O38vb9hVv7scmWM7RgSIir26ReQhNOyDElu0IlZI7m8kNDsI25E2lAYqaeL7?= =?us-ascii?Q?bWIjjiLj1bJeptZBwH8c6guzXrKYyh2WR7LeSJuGODwGyFr0KQmFdoP4yAl9?= =?us-ascii?Q?pM28ifTnKVeA5zmuAvrx2X6hkJnD93t7YNhjOO3gVDoEI1wpuAx6l7n7G0fg?= =?us-ascii?Q?U3Am8cOcWj3eJIG0Ro3X0bk68E0YQiTsjzQKpVINO7ES92ADueo9KTQjDeuq?= =?us-ascii?Q?YRNLxBMNxcXckGbqllObz4U8dcDCXuUFpbQOFnEyc4jjwG80GleVykHDqMjC?= =?us-ascii?Q?eRGqSpE0PWWh/QDzbsfBupp1tLC50JXLxGHoGqn6LehXixwuoNnpIMM10x6j?= =?us-ascii?Q?QmogR2UUkzHmGvx7PJa82i114AYz0vy6XqNmLOox9tdyvaIRQRbEXX/4BesK?= =?us-ascii?Q?DOQqeyeHkWW7Bu1UckjHwPR1FMxBrF8F3iiNrr5NUTUepuCoS+O/2yHy2rEN?= =?us-ascii?Q?Cs64MvxiGjOS0JWP/OkAyx8kATRi2wQnt5E1s7jPgeW4V6twgvXkylWO45et?= =?us-ascii?Q?jfiSspINMvyxMgCw/OyRzGaWLrEe9kunFvpXdhjIJlNTLeYCS6iM1PIpMygh?= =?us-ascii?Q?F4OkUvlg3K8e7Pp8nZHExnz3b8aEZFaa2xS7ifzaDfo9jvhAMNFznpDW5O8K?= =?us-ascii?Q?bvP/wzbJNXYds92pyOpMgvhu6bTsScYpq4dPNRPs1BJ2aVrfQWeksGxS7e6q?= =?us-ascii?Q?OJPoxNtuezXV/l8qcOM4Q402MxsIy64rtMm3QNO/qyglfV8s5ZCvNqgEszts?= =?us-ascii?Q?Xig+u2+9PXZ90mnPBVBUuYwKEnJxB8Vwj9drX7QPKVNOsrnJjCbgYY9nbnox?= =?us-ascii?Q?2u3JnkJzAFLGq6ZcJBFwA0nxXtkWTMpL2XtJCNkviYpDw5ScU79BCEc5oXjv?= =?us-ascii?Q?UU4bWEbDJXLr6ZAqFmk7jqgffbOrKk/jEHn962hc/Hxhqm/Dpqs6EpAar/l5?= =?us-ascii?Q?C23Sj8rLCF7DuBMYFmBSOpIekohNIrKUf8VnBQa9ZYySoQ7m40f0MMWAuN6r?= =?us-ascii?Q?+T4ka7WnTKocueIhlgX+PnRJXFhu6tw9C4KOhl9atkobJ/nxzBv1A+0iybcQ?= =?us-ascii?Q?nwj6/G5KwNozGm1aUFn/2B+r0ld3C2qT7Jcg7hF1sZiwrfm7iJIDeB1gE3MM?= =?us-ascii?Q?byNhFppPQQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 367e1f7f-9c98-4194-e3b4-08dead30e349 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:41.7928 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: mdjBOkoyMNRU2udJg+30J4MYTBrDMQ+ORe98hlReOP7hXjEt4lJRB58m0U3kyfHGzxGxy9qeMzI3oNsDjwVbgw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8482 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c111::5; envelope-from=tdave@nvidia.com; helo=DM1PR04CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265539252154100 Content-Type: text/plain; charset="utf-8" Introduce a per-device fixed-bars property that allows users to provide fixed PCI BAR addresses for PCI endpoint devices. The fixed-bars property cannot be supported on hot-plugged PCI devices. PCI BARs for the hot-plugged device are programmed by the guest at the time the device appears. Property format: - Comma-separated list of BAR entries, each as: barN@[,barM@]* - Example: -device vfio-pci,...,fixed-bars=3Dbar2@0x6b8000000000 - Multiple BARs: -device vfio-pci,host=3D...,id=3Ddev0 -set dev0.fixed-bars=3Dbar0@0x400000000000,bar4@0x410000000000 Signed-off-by: Tushar Dave --- hw/pci/pci.c | 108 ++++++++++++++++++++++++++++++++++++ include/hw/pci/pci_device.h | 10 ++++ 2 files changed, 118 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2c3657d00d..054fc2c0fa 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -50,6 +50,7 @@ #include "hw/core/boards.h" #include "hw/nvram/fw_cfg.h" #include "qapi/error.h" +#include "qapi/util.h" #include "qemu/cutils.h" #include "pci-internal.h" =20 @@ -81,6 +82,7 @@ static const Property pci_props[] =3D { DEFINE_PROP_STRING("romfile", PCIDevice, romfile), DEFINE_PROP_UINT32("romsize", PCIDevice, romsize, UINT32_MAX), DEFINE_PROP_INT32("rombar", PCIDevice, rom_bar, -1), + DEFINE_PROP_STRING("fixed-bars", PCIDevice, fixed_bars), DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present, QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), DEFINE_PROP_BIT("x-pcie-lnksta-dllla", PCIDevice, cap_present, @@ -218,6 +220,103 @@ static void pci_bus_unrealize(BusState *qbus) vmstate_unregister(NULL, &vmstate_pcibus, bus); } =20 +#define FIXED_BARS_ERR "fixed-bars: expected barN@[,barM@]*; " + +static int pci_parse_bar_token(const char *tok, Error **errp) +{ + int v =3D qapi_enum_parse(&OffAutoPCIBAR_lookup, tok, -1, errp); + + if (v < 0) { + return -1; + } + if (v < OFF_AUTO_PCIBAR_BAR0) { + error_setg(errp, FIXED_BARS_ERR "invalid BAR '%s', expected bar0..= bar5", tok); + return -1; + } + return v - OFF_AUTO_PCIBAR_BAR0; +} + +/* + * Parse fixed-bars=3DbarN@[,barM@]* + * BAR type, size, and alignment validation is deferred to the allocator, + * which has the full device context needed to perform those checks. + * On error, sets *@errp. + */ +static void pci_parse_fixed_bars(PCIDevice *pci_dev, Error **errp) +{ + Error *local_err =3D NULL; + char **entries =3D NULL; + char **parts =3D NULL; + const char *endp; + char **e; + uint64_t bar_addr; + int index; + int i, ret; + + if (!pci_dev->fixed_bars || !*pci_dev->fixed_bars) { + return; + } + if (DEVICE(pci_dev)->hotplugged) { + error_setg(&local_err, + "fixed-bars is not supported on hot-plugged PCI devices= "); + goto out; + } + + entries =3D g_strsplit(pci_dev->fixed_bars, ",", -1); + for (e =3D entries; e && *e; e++) { + const char *entry =3D g_strstrip(*e); + if (*entry =3D=3D '\0') { + error_setg(&local_err, FIXED_BARS_ERR "empty field in list"); + goto out; + } + + parts =3D g_strsplit(entry, "@", 2); + if (!parts[0] || !parts[1]) { + error_setg(&local_err, FIXED_BARS_ERR "not '%s'", entry); + goto out; + } + + index =3D pci_parse_bar_token(parts[0], &local_err); + if (index < 0) { + goto out; + } + + ret =3D qemu_strtou64(parts[1], &endp, 0, &bar_addr); + if (ret) { + error_setg(&local_err, FIXED_BARS_ERR "unparseable address in = '%s'", + entry); + goto out; + } + if (*endp !=3D '\0') { + error_setg(&local_err, FIXED_BARS_ERR "trailing data after add= ress in '%s'", + entry); + goto out; + } + g_clear_pointer(&parts, g_strfreev); + + if (!pci_dev->fixed_bar_addrs) { + pci_dev->fixed_bar_addrs =3D g_new(pcibus_t, PCI_NUM_REGIONS -= 1); + for (i =3D 0; i < PCI_NUM_REGIONS - 1; i++) { + pci_dev->fixed_bar_addrs[i] =3D PCI_BAR_UNMAPPED; + } + } + if (pci_dev->fixed_bar_addrs[index] !=3D PCI_BAR_UNMAPPED) { + error_setg(&local_err, FIXED_BARS_ERR "bar%d specified more th= an once", + index); + goto out; + } + pci_dev->fixed_bar_addrs[index] =3D (pcibus_t)bar_addr; + } + +out: + g_clear_pointer(&parts, g_strfreev); + g_strfreev(entries); + if (local_err) { + g_clear_pointer(&pci_dev->fixed_bar_addrs, g_free); + error_propagate(errp, local_err); + } +} + static int pcibus_num(PCIBus *bus) { if (pci_bus_is_root(bus)) { @@ -1473,6 +1572,8 @@ static void pci_qdev_unrealize(DeviceState *dev) pci_del_option_rom(pci_dev); pcie_sriov_unregister_device(pci_dev); =20 + g_clear_pointer(&pci_dev->fixed_bar_addrs, g_free); + if (pc->exit) { pc->exit(pci_dev); } @@ -2369,6 +2470,13 @@ static void pci_qdev_realize(DeviceState *qdev, Erro= r **errp) is_default_rom =3D true; } =20 + pci_parse_fixed_bars(pci_dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + pci_qdev_unrealize(DEVICE(pci_dev)); + return; + } + pci_add_option_rom(pci_dev, is_default_rom, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h index 5cac6e1688..3e46876985 100644 --- a/include/hw/pci/pci_device.h +++ b/include/hw/pci/pci_device.h @@ -179,6 +179,16 @@ struct PCIDevice { char *failover_pair_id; uint32_t acpi_index; =20 + /* + * When fixed-bars property is in use, fixed_bar_addrs is non-NULL + * and has PCI_NUM_REGIONS - 1 elements (bar0..bar5); each slot is + * either PCI_BAR_UNMAPPED (no fixed address for that BAR) or the + * fixed address for that BAR. NULL if the property is unused/empty + * or the map is not yet allocated. + */ + char *fixed_bars; + pcibus_t *fixed_bar_addrs; + /* * Indirect DMA region bounce buffer size as configured for the device= . This * is a configuration parameter that is reflected into bus_master_as w= hen --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265512; cv=pass; d=zohomail.com; s=zohoarc; b=Fzq6t90SsOEBx/OmDFDzM9z0W4ywqricBLZ5UdQjPIXIv/hllIlKZR/eEELZCMX/HKhkQ4wGGXkqkZeytJw8OqEwpXjRy5MhsklqTpOAOeH6FwxJPIp6znZxrtTqYOUmUA3yOKi0pPvosIzq9xXuAqD/TOTzFCyVFhgkXqpKYes= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265512; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Vjsk54Bj0Tn0vx32otBq+7newk94c9VNDoiW2FCunpU=; b=kSl5KjZpInHPQYfxagiBcdyf6mvvo34i6E4wfhqenIRug9orTynkaXacpLs8xrwUiaxbAYilKUGJ9G+u4vlnr6EFybr6Z4A6qdrzk9bQKpLIY7tDIfRVyXRLY1u0xwzIM0mu4Ss9p9s6dOlk9rgbhNmEuZ1VDfiYvNAHwCmEGi0= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265512266306.1077121750203; Fri, 8 May 2026 11:38:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5O-0006fy-Kx; Fri, 08 May 2026 14:38:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5G-0006er-GH; Fri, 08 May 2026 14:37:58 -0400 Received: from mail-centralusazlp170100005.outbound.protection.outlook.com ([2a01:111:f403:c111::5] helo=DM1PR04CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5E-0002Yg-Qd; Fri, 08 May 2026 14:37:58 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by CH3PR12MB8482.namprd12.prod.outlook.com (2603:10b6:610:15b::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.20; Fri, 8 May 2026 18:37:44 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:44 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=J/FiBKmMAjIn5yztW+zyDoF93kKLjiP6DAzoZFUtbz2f3Uy5L0SHtwId4ACWHfQeD9WGj4efIFRFCwQMiQw48DYdBiuWCrF5KX6RyrkIrSquX5LiyGHfuJbo6lPZDR9Xygm9rhGXOhRi7y77yIw6UkXsMuQ+lG1hfMKb+SaZOdWxlVmbJf8c/haapWf58S2o8oivgFhztjucWqGpOFsgz1FBtcjZOFrHQmGYJjxzP/ZEA66nFtpvV0Gnad8Vk98hjGmuEsXvo5pIZnJQVegtnhj5CMEDEyBtQRoi8hjXCT6rvA5m0MS5Fly+6Dni3Gf11Csu2ko27/56vtvOxuN4Dg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=Vjsk54Bj0Tn0vx32otBq+7newk94c9VNDoiW2FCunpU=; b=Vxz3iYhQ7yAdiwT/UTk0rrc9LwhDjrtJpnVLQFi4R/mjsKshvr0S7/tNDuNj9njfjcgAeoXIlyJywf1Ktnd1XN2AjTtaCnB2v4/MybKbGRfDkSbc9oyW8VKPxg0vISPFGnyaYpKep6AVgTKxMG65dpnYMgcXWuE4/0tVi4QlgXliIn7CAgdQxfx1NX7PZVHTFhQCuTmShNi55DKbNw2sQakzOs1JmCRKYwiP3c2QrrNFuqUrUwn41eMBbQE18wmUjEgQNZ7p8KHOxTkfsmETIri8kDt7UVxoGlxG5pGt7V4TS10pTyM5QFWueoh5TxloY1vm29AvR4+9/VHoBCz9Fw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Vjsk54Bj0Tn0vx32otBq+7newk94c9VNDoiW2FCunpU=; b=CDlF19tL1Zn8alZT2tRQj8dqw33oCFNieJ/IGws1NrjTvET+hZxBkpjqzRGcucaqelUx7gpOVhIo2alwCuiKdtZi/F4QeKpNAuHGBLCrdWXjZie8AoAc8FVv8xKQ4g2y57WW7jRS+/95QZmYzEvQn8GM2zVMmQA2fIubz328xlGPhCQw/LEZSYiRl48gGTEDRSaG6KPACFIea1VkU4y2dqHGg4bGlAHsFpyvakdR8cERV4anSVZ672NiZXqeP6YAEYdI6CAqXil4mR2mBnWdba9lhwTFFyTP9uUsPYuv9C2TvTQn8oP/EkdwGUeKTVEwc12Ccil6uLYdsTtk7bnaCQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 2/8] hw/pci: enumerate PCI bus and program bridge bus numbers Date: Fri, 8 May 2026 13:37:11 -0500 Message-Id: <20260508183717.193630-3-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BN9PR03CA0948.namprd03.prod.outlook.com (2603:10b6:408:108::23) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|CH3PR12MB8482:EE_ X-MS-Office365-Filtering-Correlation-Id: 1efcef15-8cf5-437e-a4c2-08dead30e4ce X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|376014|1800799024|18002099003|56012099003|22082099003|3023799003; X-Microsoft-Antispam-Message-Info: +0Siqv6Q70OETSdoUC0w0Qme3tzBt5d7G/0vTEvfIarNsheGLO4Z2rUTnwL069RE/zOUjz3gT/yIBiOEZsp+BNz9Kx2c22VXc8YLc2C/BMxVQc8wmHR9iEAupvuucl1tNEnsXo7mXwBiflaFCchHsSMTwG1MVPv876rMgqJWsrU1nheeheNdZ0pnmh00dKEU6FEWf3X7zmlpM1i3lhRhZDoxPQYR76ObirafHDaGTs71o1PhDv3Zu9D5RfbRgxcMHPerJSY7wPOL5MxtUYyimmu3DIaBPCmDFZVKcce3FiiLEraJwTkqxcyZKqTf50qjG07zOKhlt7wIq50BDXag6f5GMzRFtr3h0PeNj5BVnhDTcOnpAnb6L8S9qKWPP7aIEp7ZjKw+G9vNXbMzxxpcjQS8WuYEwJ6czRerAimWAiiiq1BhSYXixNiIZeXnDofWvlNrZmYtb4eZAu7pxukNsDyUgL+Yr3jxcJ9gqy1mI6e7FtmCPk5IDXQf0fPiX38+v6RIWfDjOMiXvScHemFSlXIeZvaq+og5xKSc6RKYWAWmx+fCYEh3MQrmFtmjGsqv/yJPxfUKKiAODxIM9mgVSTpVu9FhJ2ocSpNbuAW19HQbF6yx4BE6NqT+Vm80w8UMw7BWdFKNcyWqGRCb78Kx/gECYzRwUAN2JF8Mw+1PSj5Yz7rlEEOYU6687BZDhbIv X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(376014)(1800799024)(18002099003)(56012099003)(22082099003)(3023799003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?6SU17shNrWdGVFL/Mvc3KsvkDgvFkM8lEyfkaYpUltbgTiQhFfC4K3nVO4Sq?= =?us-ascii?Q?hXy4m5CG44niWE8oXJeRkB0V4Q8bUHpx2oE3wthl72JzRPKW6ZQW284qd29e?= =?us-ascii?Q?AfoJwOqmTf2siNPt2uzs0jDZhjYHCb+ogYti2x3wCBQXqqnTLn7vm8fpzPnA?= =?us-ascii?Q?3wGi5WVXa9Q7eFNvH0GuY15YTCB4ZMERZzuDGmlrGTZpx7Jsy4/oU2VNUQnX?= =?us-ascii?Q?govjnPyPCmoU+wlCif8wSQ7QBUWlVgAoyLjU35dsnwekRSPhIV/4P608CSfz?= =?us-ascii?Q?DDyuEdNF7Hpw98FC2wgjvs5QnANetJqoUmno39E1lBTsVFmkj5HMrLFywAPj?= =?us-ascii?Q?oo8tbfAeyDgz9lwrcFluXMWOgM6qMkMIWfs6VLlhgQxmsNEoRj733Hw6uFa6?= =?us-ascii?Q?Ecle+lppWG83x7hpyh2af1TNdz4ARxlFVWbBxsg6j4AemTBlg+8dPXi8AgRY?= =?us-ascii?Q?g3D/W4Ge1EQXmExM3pIE0LcwHRgCQ5QQugZhnQJnYtFd3FkvXXtKBOMmb1LK?= =?us-ascii?Q?iW+eLZnBAXWS4HcyR72xhKMEUkg6e9QEOhmc2RzkI5AlIbLY1ZMp5ob1wntu?= =?us-ascii?Q?eA5J53oDG3WwrESjbm7s2Kw2ifBUVcZRY3Vtq7vhN1Ef2Ro6edsq7otiWp6y?= =?us-ascii?Q?b+U/k1aJVCmbvZZ8rAazqpT+kdVtxJ+BfIvLAdEFJnQ7d2aE69o0DTsOzqSY?= =?us-ascii?Q?AALHhH2xVZHlAomx0oxuLLlzMF2C/Hab+tt956Lylae+CgY5bU4N8tyL+gYP?= =?us-ascii?Q?Lk+Kvw1ZoQU1PF2qNyROYPgttwqxtmVJN/+bNhSta+m5VO3Ryi64IMmJMiZr?= =?us-ascii?Q?VeoFCqeceWnxUVUNYOkb0HFF4lYxv+5O4cLFTxO65IhKwLfqNbPrpIuiz4o4?= =?us-ascii?Q?NSp+cnOPpfbT0QHnzd4bFq/mm1ekHMCGtyxhIFH1eP16OUfp3pn3PUUK/jtG?= =?us-ascii?Q?cpmq0CBCKbg/C4TuJJ6hvSKi227oIyRpkmWwEMpn/qEhxvgPCoP7V9Mp9AfZ?= =?us-ascii?Q?VVV4mvL77Z+C5A665CuAKGSKJBN66vx7XiKkvwh4J8RJN4gyzxDdH7Bd8JK+?= =?us-ascii?Q?vXtvlT9eNaGKS7aoJdyRSjU5+LPDtvRQ6bNyBSdnWpFz4rboIjP7UOPC/snU?= =?us-ascii?Q?qPNXcPUe30VHl/8A7Fc/qsVmzgpbKZjU4gfUitsbODoOZPKbHZMTzMWjDuAW?= =?us-ascii?Q?Y0DOK2v9nlEz2rl8G5wn4zHCYBnmpLQo9pPldxqIuXwARvpagVw723okiyVX?= =?us-ascii?Q?tpeVe7nk0e1U8+ReQjmNm/RWFBOU5bufS2oWXGOS1T57ER3EOnTzWgcbxN+N?= =?us-ascii?Q?VqCdXpFqTDgtYbsJbNNRpxEtpv3sgCC79LJMsz2oF1LMnKB/GHGyYg8hdbhE?= =?us-ascii?Q?529dUSyki8h5DVErmHHbpYoCr+K7DaElzFMfpAP4biZC0WLdmJrtGFXkv9sV?= =?us-ascii?Q?IBwI/W0wEx90ieDdXDCNLW4e0ACiwdEigUoPQ/s9QrxkdhHh91ex2YRd43OJ?= =?us-ascii?Q?fonsFjlSCw95mNJX2qaQawBy4gmT6wovD0aDT4iaD3BOB56/gDTTH0FNByCl?= =?us-ascii?Q?mKbUrXBO4b6A1hQ0MCkdZWT8c/seWpx9oE1CzQP/M3Bc8z9Hp5/cET6O7ZEx?= =?us-ascii?Q?Ak1eklPGirOx4LwMGcpowVkS88ARdHGFBoyWpxW2n8CuhzKFPuASaSqFIW4P?= =?us-ascii?Q?p9J1bHKCSRfWKVhwAkrl10IAp5BXRIpT1DRPROGg79Iaxs2jjUQRB0ZMTWCx?= =?us-ascii?Q?x/sz0S2iEQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1efcef15-8cf5-437e-a4c2-08dead30e4ce X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:44.3208 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: d8Pcfdavw3TYi6JEUpVHmzJUUGglXVzk3NRQX6IoyynMd1OXSfUwUJLvVYQ3y0zfzaqsTexHtG+zFiTRhINbEw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8482 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c111::5; envelope-from=tdave@nvidia.com; helo=DM1PR04CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265514548158500 Content-Type: text/plain; charset="utf-8" When guest firmware is told not to perform bus enumeration, QEMU must program bridge primary, secondary, and subordinate bus number registers before handing control to firmware. Walk the hierarchy under the root bus, assign secondary bus numbers in firmware-like order (PXB roots first by bus number, then PCI bridges by devfn), and program those bridge registers. Note that SR-IOV bus number allocation (VF offset/stride/NumVFs) is not handled in this commit and requires additional work. Signed-off-by: Tushar Dave --- hw/pci/meson.build | 1 + hw/pci/pci-enumerate.c | 144 +++++++++++++++++++++++++++++++++++++++++ hw/pci/pci-enumerate.h | 15 +++++ 3 files changed, 160 insertions(+) create mode 100644 hw/pci/pci-enumerate.c create mode 100644 hw/pci/pci-enumerate.h diff --git a/hw/pci/meson.build b/hw/pci/meson.build index a6cbd89c0a..7e8f5bb87d 100644 --- a/hw/pci/meson.build +++ b/hw/pci/meson.build @@ -5,6 +5,7 @@ pci_ss.add(files( 'pci.c', 'pci_bridge.c', 'pci_host.c', + 'pci-enumerate.c', 'pci-hmp-cmds.c', 'pci-qmp-cmds.c', 'pcie_sriov.c', diff --git a/hw/pci/pci-enumerate.c b/hw/pci/pci-enumerate.c new file mode 100644 index 0000000000..2c6d25b25d --- /dev/null +++ b/hw/pci/pci-enumerate.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2026 NVIDIA + * Written by Tushar Dave + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci-enumerate.h" + +/* Forward declaration */ +static uint8_t pci_program_bus_numbers(PCIBus *bus, uint8_t current_bus_nu= m, + uint8_t *next_bus_num); + +static int cmp_bus_by_devfn(gconstpointer a, gconstpointer b) +{ + PCIBus *bus_a =3D *(PCIBus * const *)a; + PCIBus *bus_b =3D *(PCIBus * const *)b; + return (int)bus_a->parent_dev->devfn - (int)bus_b->parent_dev->devfn; +} + +static int cmp_bus_by_num(gconstpointer a, gconstpointer b) +{ + PCIBus *bus_a =3D *(PCIBus * const *)a; + PCIBus *bus_b =3D *(PCIBus * const *)b; + return pci_bus_num(bus_a) - pci_bus_num(bus_b); +} + +/* + * Program one bridge's primary, secondary and subordinate bus numbers + * and recurse. Return the max subordinate bus number. + */ +static uint8_t pci_program_bridge(PCIDevice *bridge, PCIBus *child_bus, + uint8_t current_bus_num, + uint8_t *next_bus_num) +{ + uint8_t secondary, max_child; + + /* Bus number space exhausted; no bus number to assign. */ + if (*next_bus_num =3D=3D 0) { + return current_bus_num; + } + secondary =3D *next_bus_num; + (*next_bus_num)++; + + pci_default_write_config(bridge, PCI_PRIMARY_BUS, current_bus_num, 1); + pci_default_write_config(bridge, PCI_SECONDARY_BUS, secondary, 1); + /* + * Unlike real hardware, QEMU does not require opening a subordinate + * aperture before scanning downstream devices. Write secondary as + * a placeholder; the final value is set after recursion below. + */ + pci_default_write_config(bridge, PCI_SUBORDINATE_BUS, secondary, 1); + + max_child =3D pci_program_bus_numbers(child_bus, secondary, next_bus_n= um); + pci_default_write_config(bridge, PCI_SUBORDINATE_BUS, max_child, 1); + return max_child; +} + +/* + * Program bus numbers for this bus and all subordinates. + * - current_bus_num: this bus' number (0 for root, or already set for PXB= ). + * - next_bus_num: next free bus number to assign to a bridge. + * + * Children come from bus->child only. Two kinds: + * 1) PXB (extra root): child has PCI_BUS_IS_ROOT. Has bus number + * already set, recurse only. + * 2) Normal bridge: parent is IS_PCI_BRIDGE. Assign secondary =3D *next_b= us_num, + * program primary, secondary and subordinate bus numbers, and recurse. + * + * Order matches EDK2 PciBusDxe enumeration: process PXB children first + * (sorted by bus number), then bridges (sorted by devfn). + */ +static uint8_t pci_program_bus_numbers(PCIBus *bus, uint8_t current_bus_nu= m, + uint8_t *next_bus_num) +{ + PCIBus *child_bus; + GArray *pxb_buses =3D g_array_new(false, false, sizeof(PCIBus *)); + GArray *bridges =3D g_array_new(false, false, sizeof(PCIBus *)); + uint8_t max_subordinate =3D current_bus_num; + uint8_t child_num; + uint8_t one_max; + guint i; + + /* Single pass over bus->child: split into PXB vs bridge */ + QLIST_FOREACH(child_bus, &bus->child, sibling) { + if (!child_bus->parent_dev) { + continue; + } + if (pci_bus_is_root(child_bus)) { + /* PXB or similar: bus number already set (e.g. bus_nr=3D1, 9)= */ + g_array_append_val(pxb_buses, child_bus); + } else if (IS_PCI_BRIDGE(child_bus->parent_dev)) { + g_array_append_val(bridges, child_bus); + } + } + + /* PXB first, sorted by bus number (e.g. 1 before 9) */ + if (pxb_buses->len > 1) { + g_array_sort(pxb_buses, cmp_bus_by_num); + } + for (i =3D 0; i < pxb_buses->len; i++) { + child_bus =3D g_array_index(pxb_buses, PCIBus *, i); + child_num =3D (uint8_t)pci_bus_num(child_bus); + if (child_num + 1 > *next_bus_num) { + *next_bus_num =3D child_num + 1; + } + one_max =3D pci_program_bus_numbers(child_bus, child_num, next_bus= _num); + if (one_max > max_subordinate) { + max_subordinate =3D one_max; + } + } + g_array_free(pxb_buses, true); + + /* Bridges second, sorted by devfn */ + if (bridges->len > 1) { + g_array_sort(bridges, cmp_bus_by_devfn); + } + for (i =3D 0; i < bridges->len; i++) { + child_bus =3D g_array_index(bridges, PCIBus *, i); + one_max =3D pci_program_bridge(child_bus->parent_dev, child_bus, + current_bus_num, next_bus_num); + if (one_max > max_subordinate) { + max_subordinate =3D one_max; + } + } + g_array_free(bridges, true); + + return max_subordinate; +} + +void pci_enumerate_bus(PCIBus *root_bus) +{ + uint8_t next_bus_num; + + if (!root_bus) { + return; + } + next_bus_num =3D 1; + pci_program_bus_numbers(root_bus, 0, &next_bus_num); +} diff --git a/hw/pci/pci-enumerate.h b/hw/pci/pci-enumerate.h new file mode 100644 index 0000000000..b1e4b989f1 --- /dev/null +++ b/hw/pci/pci-enumerate.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2026 NVIDIA + * Written by Tushar Dave + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_PCI_PCI_ENUMERATE_H +#define HW_PCI_PCI_ENUMERATE_H + +#include "hw/pci/pci_bus.h" + +void pci_enumerate_bus(PCIBus *root_bus); + +#endif --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265519; cv=pass; d=zohomail.com; s=zohoarc; b=Af0KEF7mD720tWGvhN8qfV2BtEY8+JhBWGjCWW7Y8Z8Y8zrbmNjILe1vv5GQXqITLZ29u7txJHbmhhvpxhT70Uo+/LU7p9oVCVY4BvD+nA8Yz/Nq03sX0T43aJ8KP1OfxxEYrz44jQcM2VOYBXuE4BJZh6OOEk1mmUrOzqPwXSY= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265519; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=XqE/IoyY03xAlx51xRPj7NQYnIAcmcFFJKBlXu8boSc=; b=QRMn9yoNPU0t2FGZ+HMABx3zMXpGYvXgEVJnKXHL1fdI7AhxJTl5JQ1V0pYd2AR7Cxjf4AVgi+PW60J1EQKRrwToYegbbhE0HImfq8uRNgDw3st2ND+a0h/4PIuMMYpIkp6s1OV2/5MC1SZuUSU2oYNq5Fdu+677fZ3b1n90TwU= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265519048491.58245442609007; Fri, 8 May 2026 11:38:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5Q-0006hT-QS; Fri, 08 May 2026 14:38:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5K-0006fz-WE; Fri, 08 May 2026 14:38:04 -0400 Received: from mail-centralusazlp170100005.outbound.protection.outlook.com ([2a01:111:f403:c111::5] helo=DM1PR04CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5I-0002Yg-Pp; Fri, 08 May 2026 14:38:02 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by CH3PR12MB8482.namprd12.prod.outlook.com (2603:10b6:610:15b::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.20; Fri, 8 May 2026 18:37:46 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:46 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=s6vU6OVid0/K/O7U0+6y/Jz67LTbJoC1Jwor5p2QXbWAcrZEgYIo+gV9BZigATZmqnU+NAsScNEwBko8LmynNl1QoqzyvDjte5o7khOI2/4izSMHJ9pDFtUii5phLaENEVIOhygmHZ1exbGzFGjjtvlvMlTcWn7NcYyy39nuFdWW96COZivix1fRMyqpjOeXsbRNcWoFNQpcmYoBL48/eqjjvnOdonKdYKK3C9jPm2hF9QDEsH2FzQZjDPJZkQhylw1Gck+216g5F4TMqqd/yvXCoIcNza+VD1K6+8bEpCwAc/wFlPsNCN/aOtjLLZKrPDrxwDveJyowRvVo7xGlkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=XqE/IoyY03xAlx51xRPj7NQYnIAcmcFFJKBlXu8boSc=; b=MVhntnwdiaAV8ZCA0S4FxH3zK11L9cdCUld/+QDBim2uab9ub86prTXw3Wb5FT5JIqA4VVsFiTnUEEr3UFkqmAgu5wbvMtjYive6oriXyV4L38H83LbGU8PiBivZkq5U8mfqIYd7+k7GVziAugPZSl3GOuWc58nSrguQPj0V/VAuIP1UOZAEFiVKIjGtKyv9j3cy13dOUqX40rAr/YXblLD72mipuh6XPDLXSYUyj0XBSw4qDSIJ/IaKtqvMQK4B7UF4GcPnPTaabc2BysrZmtIz1ES8hRPq6XxG9Rpysxah71/ubhZsgDCVeRWbJmfiwx9zGXgV3guNY0Nry39RDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XqE/IoyY03xAlx51xRPj7NQYnIAcmcFFJKBlXu8boSc=; b=uqoaK8TARKmErb2fLWt1zZkhm9NKtpAF+nuWMVdbJFySR1eRfEUnZGd3jZtcVvY3WmNANXAUJe63bl0rR1hSBBbMAtbN1ab7jJeJ1vHcjKASfJOX4CPrhul4q/8Ksiig/09xlxf/iK8X22fn9hWRHi0uXNwcgrNL0V3COt/UdF6NmWtLs8apSsUO0UZ5hgrzQaHiouwbLMInNhvdv3f6+oQs/6qpTkyaySpczS03HbVl+JPsGF6ggYhss3MSTjLrN2U2T+OEuugzaP+cjHycYuTldpaKe8Ix4wNi/ulmGM5g00hjOZ9f01rqQA959grg0p2tlxt24pcv7A8uUJ3Vww== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 3/8] hw/pci: introduce allocator for fixed BAR placement Date: Fri, 8 May 2026 13:37:12 -0500 Message-Id: <20260508183717.193630-4-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0P221CA0027.NAMP221.PROD.OUTLOOK.COM (2603:10b6:208:52a::21) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|CH3PR12MB8482:EE_ X-MS-Office365-Filtering-Correlation-Id: eacdf569-593e-4b94-d89b-08dead30e627 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|376014|1800799024|18002099003|56012099003|22082099003|3023799003; X-Microsoft-Antispam-Message-Info: dZ6h6c7jE+Qf1rebWfnieA+8iH2ASY5zo+ZkOVilQWoqaQbDkoY16ldhyuXAPHpvb+HfxWF3KDm3qq4f9mFuVG4zlHKBm7MV6yaYpLYAnJlOjaEKp9tdiE8jM78QDi6jIcZlFaDbeZUcERu4colPgm/th9zXfPRueW8JBRcJRxOY7KRtuh49T2WzVVVXNDB84/9MsF6c93pQx6MgoBbZGmeVRQoCuiwM3qDFe4AsHY0jPx1AE3rG4Oi063zDmlzj0tkwIqCokckeFl8fSkWiwh6fM4L8fB/uhbMAZ5i5jz3pQPWf0q7ansiRre0hfWerftG92leNLhSwzkp5GUDZmqDPUUXAVYHEIULpUYYzrGT+uDlk46QJkSmFDMTKkSC1hSV9mOfIYkqL9m00owruhg5+O58snNGBDzhun7OEuP65c9qmH9WGWOiAwzvDHaewfQawmyOZKpIqSvmncbbTaREx4Q9DSvNDmwmAz/o7XmRYvW0qU6JYma93ExMG3uYDH3AOUvwSHfEILu2N2/Ukz6sKxH3bKnho696qt/OHynrFRHVtWkqJgq79kRhDsSqFLhhafW376G/iiSjRlggS1cjDd7Kk2r3hVZWQlNiqvb2mhtUa8pB4bgGgVIlNqTilTgAl4BJiXUc5o+BrLe8OeZCfcbVKzoOx+6rlqv/ely61E2C4GsSjr2zuTbGCs8A5 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(376014)(1800799024)(18002099003)(56012099003)(22082099003)(3023799003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?ZTFIWHRkdTZ3TzRHWXRUV2ltM0hCQS9ENnZuMHQ1MVBqQ1JFSmthVldUdEJY?= =?utf-8?B?RC80SG5sMUhpVDZEM21oTVIwQ3lUTUhqWm5JMlZlQUU3b2JrVnJIaDBwYlZj?= =?utf-8?B?RXpleXNlSi9QWnpaenpnWjVsM1FkMUFoelp6ZXNudThqQVFDSmU1R1Roem5u?= =?utf-8?B?VnVaUTFtcHBTUFJLME9xbU9BYVpMZml2VTNjRk9XMjlDM3NoZllON2grZVhK?= =?utf-8?B?enJ1cFljV0hlbGhLUTlnb2lZTml5VmVySlh1M2dJOXRYOWY3RjVIcjNHVy9u?= =?utf-8?B?WHdSblNzZHlWSTJ2c2Q3OVR1NTk5YzVOa1R6L2NxQTlNQmZGL3V0a2YxSnVF?= =?utf-8?B?K3lFbUpLdFpCUFRzY0xuUDFMU21GZi93TW9Hc0M2cSswbFBjY01nQlQrR0x3?= =?utf-8?B?bjdocVNNdnRoSE9IZzJKaXFwdUJzSXl0REhiWmZmWUlBWDJNSVUvRHExYmFJ?= =?utf-8?B?UDdsYVIvWDdIanhMRXcxL3Vha05qbFJLVlFqSWlJZzBSLzMxVlhMZ2JoaFpY?= =?utf-8?B?L1p2U1VoT3d1eVRuUEtjRkpERENaV0V2OERRMVNpVlZpeGZueHI5Yjc4T2J1?= =?utf-8?B?dEROQlEyVStRYlRLa2Z4SGI3RXB4QnRvcGh4c1BQeWJ1NUZGUVJsVEYrRE5Z?= =?utf-8?B?Skx2NUptazk5Ym1UYjl3ZktXN2JoSFFoSk9wYTZTaENhczU4TG4xK0ZnaUs4?= =?utf-8?B?R2RDcDcvRTl2YTZieUVKNUdIQXplbUFDNzRFTzExYnZGcVZwNFFjZHJyR1Ra?= =?utf-8?B?S282TWVmWWMxbXJ2N2hTbFN1ZTBEWFFnT1pLMFhDV1ZNMGhza0NDVFI4L1Vy?= =?utf-8?B?UjE1T0dVRWRRaGVad0hjcDhnVTVxUE5rZ28wR0V0Z0h5SmkxWXBGbUVDV1ZZ?= =?utf-8?B?WHdhd3pPOVo2d3g2dXg3OHlBWmp5OWNpNnYrMGY3eTBxS2l1TlBMUHdJUzBw?= =?utf-8?B?ZkVGanlzY3lXOXk4SnhQNlV0bDVtaytUenBpVkpxZ3VmS1NDSGNzZmZQNWlx?= =?utf-8?B?cWU0bXI5dVBWZVNkNkdLWS85MlVzcjczNUdiQzhNd3dzTHdGMlBmOGZDTG5s?= =?utf-8?B?V0JudFBIZTN6Ymh3WVRZRFd2NnNOemtFbnBESU9BY0NHTUY3cnBheXdwRkdx?= =?utf-8?B?MXpmTEUwa2FBUTdsd0Yvb2JzMHZlK0hTeTdhcDltaUV6MGRSblNzK2dVcVVl?= =?utf-8?B?WDBjN2hUV0ltMGJOQmthL2tTdXlxQ1d5aXlMYVpTZSsvY0xlak42N200NjVy?= =?utf-8?B?VTByQTJJMEJNeUNhTm1KeVk0c1V3TWcxTmpZN2dWWTJSUlhkUlZZRXVmRWx2?= =?utf-8?B?TDMzZUxkY3FTdEJpY2hlUFhkVjg1Ump0U3VuRTlvWjlNYmFVM095czZUQ2Ur?= =?utf-8?B?Z2ZsTTc1ZHoreXJ2K256b1kwd21nS0ZSTHM4THR1WFdHUXlkcm8yN0l4dU4y?= =?utf-8?B?ekZydVplMlZ0TXFCME1jL3c5UFpLTlJzbkxtZGNLTDBiWXY0TXNLdkZUUXdx?= =?utf-8?B?U2M5aE05VG1mN1NxTG5KQ2w4TmJMVFVMWGhXSXI5ZmN4djVPSUZLbGtjc293?= =?utf-8?B?eitOdllNK1M5T1NsN0gzU2dnZFZwTU9nTmNnRi90RHJQN0Z0TjlFNFR5cGtO?= =?utf-8?B?ZStFNmdwL3FRZ3kwdlFpb0Yvc0JPdEVzSVlyd3JRMUNtS01pSlo2eE93eVYv?= =?utf-8?B?L2tvWWgzdjIzdHcrVkI3aE90K01rb2d2UTUwaEQycTFNSUJOT05BeGNnc200?= =?utf-8?B?SFVBejlaRHA2K2xlMkN3dzNWUWVjVHc1NnErM2dWL0FySDB4d3pUNHlmd1Nu?= =?utf-8?B?b0IyNnc3bFg1cjBsL2JMUENFTndQVllLR08wdTVJU3B5M2FNc093RVkvQ3JN?= =?utf-8?B?YlVCRUh1VjArZEcrMW1FZGFsbXEzVnNpNmJGZmZ6NExVUEpJWnFBMFZpN0pB?= =?utf-8?B?aVQvVHhBbno3R2FQa2lTUEVLNjBCb1hxdEc0aWg4R1RoTFRjMExVVjAvS1p6?= =?utf-8?B?bk9RR0lrZTFvazlFZE1pU0ZHWGtZdUVnRWRMdlFWUS81NFczdTZCbzRCQTkv?= =?utf-8?B?ZDRVNVhPZENydG03cDk5NEx2TmRWbzN6YW45NFFERmk0UTl5RGFZR3ZYcnVM?= =?utf-8?B?RnpTQ09uUHYxWFZ1SkJiYWhheW4wbWo5RHFjLzV6QjJlMmNGbEF6TkhaY2U2?= =?utf-8?B?Y0tnNVZaZjh4bXpYM1hWeUE1N203T2ZiMjY2WGJYVkpDNDlJMU91cm9GQ1cr?= =?utf-8?B?STEzTTMzS2FnVU9zbnF1VndQWk9oaFVpbTBPL2xJQnUwM2tnSFUxY0Z0WjY5?= =?utf-8?B?ZzY5NDIwOTlMS3hiWS9rMllUQ3IzdlZMUTdIOWRkaEZMQ0dBOFVJQT09?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: eacdf569-593e-4b94-d89b-08dead30e627 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:46.6434 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 5UaUvuHsktB3tELt2jpUicythJuZG0gonqpLi4XP7WTxkc2I5DmvSLzQgQvwpBLBwPSfBXbVjGQiTARhfdbHLQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR12MB8482 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c111::5; envelope-from=tdave@nvidia.com; helo=DM1PR04CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265520056158500 The allocator walks the PCI topology and, for each device with fixed BAR requests, validates the BAR (type, size, alignment, and that the resulting range fits within the machine-provided MMIO64 window), detects conflicts against already claimed ranges, and programs 64-bit prefetchable BARs. A global list of claimed ranges is maintained to detect overlapping allocations across devices. Overlapping fixed BARs within a device are also detected, and any conflict results in an error. This patch implements the initial phase of fixed BAR handling and reservation tracking. Allocation of remaining resources and bridge window setup will be added in follow-up patches. Limitations: Only 64-bit prefetchable MMIO BARs within the MMIO64 window are handled. This covers devices that use large prefetchable MMIO regions. 32-bit MMIO, PIO, and 64-bit non-prefetchable BARs are not supported and will be addressed in future work. Signed-off-by: Tushar Dave --- hw/pci/meson.build | 1 + hw/pci/pci-resource.c | 255 ++++++++++++++++++++++++++++++++++++++++++ hw/pci/pci-resource.h | 65 +++++++++++ 3 files changed, 321 insertions(+) create mode 100644 hw/pci/pci-resource.c create mode 100644 hw/pci/pci-resource.h diff --git a/hw/pci/meson.build b/hw/pci/meson.build index 7e8f5bb87d..d26695414f 100644 --- a/hw/pci/meson.build +++ b/hw/pci/meson.build @@ -6,6 +6,7 @@ pci_ss.add(files( 'pci_bridge.c', 'pci_host.c', 'pci-enumerate.c', + 'pci-resource.c', 'pci-hmp-cmds.c', 'pci-qmp-cmds.c', 'pcie_sriov.c', diff --git a/hw/pci/pci-resource.c b/hw/pci/pci-resource.c new file mode 100644 index 0000000000..5e9a78ec16 --- /dev/null +++ b/hw/pci/pci-resource.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2026 NVIDIA + * Written by Tushar Dave + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/range.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci_host.h" +#include "hw/pci/pci-resource.h" + +/* Global list of claimed fixed 64-bit prefetchable BAR ranges */ +static GArray *fixed_claim_regions; + +static void fixed_claim_regions_reset(void) +{ + if (fixed_claim_regions) { + g_array_free(fixed_claim_regions, true); + fixed_claim_regions =3D NULL; + } + fixed_claim_regions =3D g_array_new(false, true, sizeof(FixedClaim)); +} + +static bool fixed_claim_regions_conflicts(uint64_t start, uint64_t end, + uint64_t wbase64, uint64_t wlimi= t64, + uint64_t *conflict_end) +{ + /* Hard guard: out-of-window ranges are invalid input */ + if (start < wbase64 || end > wlimit64) { + error_report("placement [0x%"PRIx64"..0x%"PRIx64"] out of window " + "[0x%"PRIx64"..0x%"PRIx64"]", + start, end, wbase64, wlimit64); + exit(1); + } + if (!fixed_claim_regions) { + return false; + } + for (guint i =3D 0; i < fixed_claim_regions->len; i++) { + FixedClaim *c =3D &g_array_index(fixed_claim_regions, FixedClaim, = i); + if (ranges_overlap(start, end - start + 1, c->start, c->end - c->s= tart + 1)) { + if (conflict_end) { + *conflict_end =3D c->end; + } + return true; + } + } + return false; +} + +static void fixed_claim_regions_add(uint64_t start, uint64_t end, PCIDevic= e *dev, int bar) +{ + FixedClaim cl =3D { .start =3D start, .end =3D end, .owner =3D dev, .b= ar =3D bar }; + g_array_append_val(fixed_claim_regions, cl); +} + +static void pci_validate_fixed_bar(PCIDevice *dev, int bar_index, + uint64_t addr, uint64_t size, + uint64_t wbase64, uint64_t wlimit64) +{ + PCIIORegion *r =3D &dev->io_regions[bar_index]; + uint64_t end; + + if (!r->size || !(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) { + error_report("Invalid fixed-bars for %s [%02x:%02x.%x] BAR%d: " + "BAR not 64-bit or size=3D0 (type=3D0x%x size=3D0x%"P= RIx64")", + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + bar_index, r->type, (uint64_t)r->size); + exit(1); + } + /* This path only programs 64-bit prefetchable MMIO in the MMIO64 wind= ow. */ + if (!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH) && + !pci_bus_is_root(pci_get_bus(dev))) { + error_report("Invalid fixed-bars for %s [%02x:%02x.%x] BAR%d: " + "this allocator only supports 64-bit prefetchable MMI= O; " + "64-bit non-prefetchable is not supported", + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), bar_index= ); + exit(1); + } + end =3D addr + size - 1; + if (addr & (size - 1)) { + error_report("Invalid fixed-bars alignment for %s [%02x:%02x.%x] " + "BAR%d: addr=3D0x%"PRIx64" size=3D0x%"PRIx64, + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + bar_index, addr, size); + exit(1); + } + if (addr < wbase64 || end > wlimit64) { + error_report("fixed-bars out of window for %s [%02x:%02x.%x] BAR%d= " + "range=3D[0x%"PRIx64"..0x%"PRIx64"] window=3D[0x%"PRI= x64"..0x%"PRIx64"]", + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + bar_index, addr, end, wbase64, wlimit64); + exit(1); + } +} + +static void pci_check_fixed_bar_overlap(PCIDevice *dev, PhysBAR *pbars) +{ + for (int i =3D 0; i < PCI_ROM_SLOT; i++) { + if (!(pbars[i].flags & IORESOURCE_PREFETCH)) { + continue; + } + for (int j =3D i + 1; j < PCI_ROM_SLOT; j++) { + if (!(pbars[j].flags & IORESOURCE_PREFETCH)) { + continue; + } + if (ranges_overlap(pbars[i].addr, dev->io_regions[i].size, + pbars[j].addr, dev->io_regions[j].size)) { + error_report("Invalid fixed-bars =E2=80=94 fixed BAR overl= ap on %s [%02x:%02x.%x]: " + "BAR%d [0x%lx..0x%lx] vs BAR%d [0x%lx..0x%lx]= ", + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + i, pbars[i].addr, pbars[i].addr + dev->io_reg= ions[i].size - 1, + j, pbars[j].addr, pbars[j].addr + dev->io_reg= ions[j].size - 1); + exit(1); + } + } + } +} + +/* Program 64-bit prefetchable BARs */ +static void pci_program_prefetch_bars(PCIDevice *dev, PhysBAR *pbars) +{ + int idx; + uint32_t laddr; + + for (idx =3D 0; idx < PCI_ROM_SLOT; idx++) { + PhysBAR *pbar =3D &pbars[idx]; + + if (!(pbar->flags & IORESOURCE_PREFETCH)) { + continue; + } + laddr =3D pbar->addr & PCI_BASE_ADDRESS_MEM_MASK; + laddr |=3D PCI_BASE_ADDRESS_MEM_TYPE_64; + /* Set PREFETCH bit only if the BAR itself is prefetchable */ + if (dev->io_regions[idx].type & PCI_BASE_ADDRESS_MEM_PREFETCH) { + laddr |=3D PCI_BASE_ADDRESS_MEM_PREFETCH; + } + + pci_host_config_write_common(dev, + PCI_BASE_ADDRESS_0 + (idx * 4), + pci_config_size(dev), + laddr, + 4); + pci_host_config_write_common(dev, + PCI_BASE_ADDRESS_0 + (idx * 4) + 4, + pci_config_size(dev), + (uint32_t)(pbar->addr >> 32), + 4); + } +} + +/* Phase 1: claim and program fixed BARs for one device (per-device callba= ck) */ +static void pci_dev_claim_and_program_fixed_bars(PCIBus *bus, PCIDevice *d= ev, void *opaque) +{ + PciProgramCtx *pctx =3D (PciProgramCtx *)opaque; + PhysBAR *pbar, pbars[PCI_ROM_SLOT]; + bool had_any_fixed =3D false; + uint64_t start; + uint64_t end; + int idx; + + pbar =3D pbars; + memset(pbar, 0, sizeof(pbars)); + + if (!dev->fixed_bar_addrs) { + return; + } + for (idx =3D 0; idx < PCI_ROM_SLOT; idx++) { + PCIIORegion *r =3D &dev->io_regions[idx]; + if (dev->fixed_bar_addrs[idx] =3D=3D PCI_BAR_UNMAPPED) { + continue; + } + pci_validate_fixed_bar(dev, idx, + dev->fixed_bar_addrs[idx], + r->size, + pctx->mmio64_base, + pctx->mmio64_base + pctx->mmio64_size = - 1); + + start =3D dev->fixed_bar_addrs[idx]; + end =3D start + r->size - 1; + if (fixed_claim_regions_conflicts(start, end, + pctx->mmio64_base, + pctx->mmio64_base + pctx->mmio= 64_size - 1, + NULL)) { + error_report("Invalid fixed-bars =E2=80=94 fixed BAR for %s [%= 02x:%02x.%x] " + "BAR%d [0x%"PRIx64"..0x%"PRIx64"] overlaps an exi= sting fixed range", + dev->name, pci_dev_bus_num(dev), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + idx, start, end); + exit(1); + } + fixed_claim_regions_add(start, end, dev, idx); + pbars[idx].addr =3D dev->fixed_bar_addrs[idx]; + pbars[idx].end =3D pbars[idx].addr + r->size - 1; + pbars[idx].flags =3D IORESOURCE_PREFETCH; + had_any_fixed =3D true; + } + if (had_any_fixed) { + g_hash_table_insert(pctx->had_fixed, dev, dev); + } + /* Abort if intra-device fixed overlap */ + pci_check_fixed_bar_overlap(dev, pbars); + /* Program fixed BARs now */ + pci_program_prefetch_bars(dev, pbars); +} + +static void pci_bus_claim_and_program_fixed_bars(PCIBus *bus, void *opaque) +{ + pci_for_each_device_under_bus(bus, pci_dev_claim_and_program_fixed_bar= s, opaque); +} + +static void pci_resource_init_from_mmio(PciAllocCfg *pci_res, + const PciFixedBarMmioParams *mmio) +{ + pci_res->mmio32_base =3D mmio->mmio32_base; + pci_res->mmio32_size =3D mmio->mmio32_size; + pci_res->mmio64_base =3D mmio->mmio64_base; + pci_res->mmio64_size =3D mmio->mmio64_size; +} + +void pci_fixed_bar_allocator(PCIBus *root, const PciFixedBarMmioParams *mm= io) +{ + PciAllocCfg pci_res_buf, *pci_res =3D &pci_res_buf; + PCIBus *bus =3D root; + + /* Fill allocator MMIO window once from machine memmap */ + pci_resource_init_from_mmio(pci_res, mmio); + + /* Reset fixed-claims tracking */ + fixed_claim_regions_reset(); + + PciProgramCtx pctx =3D { + .mmio64_base =3D pci_res->mmio64_base, + .mmio64_size =3D pci_res->mmio64_size, + .had_fixed =3D g_hash_table_new(NULL, NULL), + }; + + /* Phase 1: program all fixed BARs and claim them */ + pci_for_each_bus(bus, pci_bus_claim_and_program_fixed_bars, &pctx); + + /* TODOs: Phases 2=E2=80=933, program remaining BARs, bridge window re= fresh etc,. */ + + /* Cleanup */ + g_hash_table_destroy(pctx.had_fixed); + fixed_claim_regions_reset(); +} diff --git a/hw/pci/pci-resource.h b/hw/pci/pci-resource.h new file mode 100644 index 0000000000..cc4d6f71cb --- /dev/null +++ b/hw/pci/pci-resource.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2026 NVIDIA + * Written by Tushar Dave + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_PCI_PCI_RESOURCE_H +#define HW_PCI_PCI_RESOURCE_H + +#include "exec/hwaddr.h" +#include "hw/pci/pci.h" +#include + +#define IORESOURCE_PREFETCH 0x00002000 + +typedef struct { + uint64_t addr; + uint64_t end; + uint64_t flags; +} PhysBAR; + +typedef struct { + uint64_t wbase; + uint64_t wlimit; + uint64_t wbase64; + uint64_t wlimit64; + uint64_t rbase; + uint64_t rlimit; + uint64_t rsize; + uint64_t piobase; + bool available; + bool search_mmio64; + PCIDevice *dev; + PCIBus *bus; + /* Allocator window (filled once from machine memmap) */ + hwaddr mmio32_base; + hwaddr mmio32_size; + hwaddr mmio64_base; + hwaddr mmio64_size; +} PciAllocCfg; + +typedef struct FixedClaim { + uint64_t start; + uint64_t end; + PCIDevice *owner; + int bar; +} FixedClaim; + +typedef struct { + hwaddr mmio64_base; + hwaddr mmio64_size; + GHashTable *had_fixed; /* set of PCIDevice* that had at least one fixe= d BAR */ +} PciProgramCtx; + +typedef struct PciFixedBarMmioParams { + hwaddr mmio32_base; + hwaddr mmio32_size; + hwaddr mmio64_base; + hwaddr mmio64_size; +} PciFixedBarMmioParams; + +void pci_fixed_bar_allocator(PCIBus *root, const PciFixedBarMmioParams *mm= io); + +#endif --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265524; cv=pass; d=zohomail.com; s=zohoarc; b=NKYI5b+u8HBKRQAOqA+aFrOkI148D0HD4qZuDO/CvzPGi4b0eGWUp6nbDKO8YZlf6RjqjzxHjsRFa3z3BjAfGO/UCg2ZQhyymAK6/xu80hzfT66FBv1Ji6ZTFO1aa+up3BJ4EzkuPemQHdQ+1hS9yZGygydGCaNaSFXMTt5jf5E= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265524; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=W726+PPqMc4z9M6h6iHFJtIw4+4PuxeojHkmcipqfoE=; b=NFfDO8JqP8EP2mCeb+t46v2TgCWqGxgnb7rmoLKCpV6nRdWfOa9ckG/K0EalaVRvcKBL7m0MwDe+eRlGhKSKRlYfNZRXExbDubmrxgcNE/az35xVWA8G1phTr5hIXSclxljrbFL+zPPYVMw+3KBGbN5FF23pmEnNVsNwC9c1mXI= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265524437955.0787362528364; Fri, 8 May 2026 11:38:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5O-0006gO-MA; Fri, 08 May 2026 14:38:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5I-0006fE-Pv; Fri, 08 May 2026 14:38:02 -0400 Received: from mail-northcentralusazlp170100001.outbound.protection.outlook.com ([2a01:111:f403:c105::1] helo=CH1PR05CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5G-0002b2-07; Fri, 08 May 2026 14:38:00 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by DM4PR12MB6205.namprd12.prod.outlook.com (2603:10b6:8:a8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.15; Fri, 8 May 2026 18:37:49 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:49 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=s5FkCqitWBKd/1Ke2DzePeqcZARTEnIySGXs71PB9gzHFxg/V3RrUan18F2WexLMoQgC8wo774ld+nvGbU56ctm8Fyt90/QAdTWdGhKa/i4mZ099ljhAkHYTfoTtTuzyqgA8VvxETO61Juf9qTsaMmOJVpOVOxjQ3G2+VnH4p+I9GG5f1t3VLf17OPNvwwz88JKAFN8gCtUBxO2v7AnStVZ5hgz55xtGAba117wK589oZj/bu9BiCfZUNLmEu4VE97Zqpo0NXRvHBED6R3aCM+zgYsjEQCEce/svRLsFhJN9xB1I9zPt44Ankmu3UV+tbJQSybnB0EgamFAqB/AP4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=W726+PPqMc4z9M6h6iHFJtIw4+4PuxeojHkmcipqfoE=; b=v5KD10mqLEQjqVdCK/JteGUxH81WbIZtAHVmCGQTQc7Bg2OdaL5LhHdpYXCCb5cTKuOYwUz4+E3Fj6IXHYcxFsFXsArP7c2Z06H268FiDrW8UpWmpQLh8L6x3mkfT98PCtPYdnxZidEkcxWQ3pItwgMht5CFTBGdv1NYCuKGgJznrMst/6V0myCVHFPhgEZUQvLcN1ejZh14PHhdK2dTLf1b9HcSe70NZUqdp73e7WC8SaNrs28fjLrJhe3xbVNWcdYF8wNHdbRqDEvRpsdRPKrYahb5DhLusNFKap7tRYft+lS0onw1FbwRV5bFesaJ5zWiBZCDl44H08wj9yRc4Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=W726+PPqMc4z9M6h6iHFJtIw4+4PuxeojHkmcipqfoE=; b=L+PImY0FkjGdq4whRRmU4O1sAKcwJQjEd/sqSnFZHZnQkwEd7AmEog+Cjl0qjz3v/GcS/O19QE4gVik8kK4IEC3iy6A+8bbdRHW9Zj9RnT3hpKySVrv7CfLQ3v1x1Dou2hqOxH7Av/ztg0gYwyfVuIAxIk4TW6tFjuPDUz2kt0wr0S8UIn/1y5+NT/3VwtAWOAvWsgJ90G6OoedWz/BE96aXctxXFWT+xzFpj76f9KKEaqotTTErNS7TeIL/e4sP7ip1Cecz8W1yPpNmJtPcYGc+xVg2dwq3oT57FfAfX9+6a7aO++GkZxFJkOF6d81Iuzuss/3jSbXHU6m86+UVoA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 4/8] hw/pci: pack remaining BARs and update bridge windows Date: Fri, 8 May 2026 13:37:13 -0500 Message-Id: <20260508183717.193630-5-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0PR04CA0004.namprd04.prod.outlook.com (2603:10b6:208:52d::6) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|DM4PR12MB6205:EE_ X-MS-Office365-Filtering-Correlation-Id: 2aa4b1ef-7f63-4400-21c7-08dead30e795 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|1800799024|376014|22082099003|18002099003|56012099003|3023799003; X-Microsoft-Antispam-Message-Info: pQ9YfJNrlybMJeXQGudKZUk81yqN98JdRvwcj93VnAZlV7cVHKk3wFotgPcTcKIfjp1ONhRMlcogtR46dtZQXRlVzc4fOs8M+7wm9bTBUhhF4CtUDCO8dHvuqkBWg3nnWGCtsDABVZtXoanM4b/4hNoUnK1UTQFHwzSmE9VI/MJV2H1ZYlCQS1xFnH2nnPL1iZS5bWkCO1KIzoZxxLLtRFlNiq4xO5jRj3VyQg2AExOPnkcZv5dMArw/eUu9Aj+ibosh/rA31biqu2vAliU0DNLLAAfOf7yuRwbne4z7KTwR390F04EUy1uiJ6iBS4HZxzwskfYXaMgvQRxsA9XXGx976LjBnhjqa26JXuPPryZYqDtQWClDcShodq21YF4VWgsqcgK76t27qRw5k4KbVi3I3tuQsL+eC1kxpaRbP1gHSlFLwkTeMbroWQarBg2hX+RKwDDwVWh5DvraAEysis0CUvZD9RYFhKtsO5fYxaXXm0eZ88JcLucWRMZGsrC3zCCnqRQ0LodWRhb8Fq+tvrACsaMRByFJd1NK+pps9ouEY1Q+5Q/0CWUhh0D+1Fa3AMjvCPT99oc4Vl9kaE/3Gj42Yqr8ZOEfVxW33ePv0B8tJOmFUSg7BAdABiAXWCPLWQ+D78jRUHzAXS/3/54SZC+ah9nXTW+5ATlECcTdL5sBYa16Vh016JH7j4W6PyHT X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014)(22082099003)(18002099003)(56012099003)(3023799003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?bzhCS2JNUUhPVnljaVFNYjlEOE54RmlidHFVRVRhMnEzUCtuWHhpelFxSDND?= =?utf-8?B?a0V1YXo5a3J0aWZEbjFRYXUrT1UyNzVKQzFhZmhCT1RXU2tyODJ3ZUF6OVZT?= =?utf-8?B?UTRxY1FTbjduU1lDUnA1Tmhla291RUozcGFXRUk3NExZd2J2V0V5bStpSHlQ?= =?utf-8?B?SisxYlFCQkxQZXVWMTRtMFd5Ykh0OTNCbkxRdnlvNUx3cGNwNWQ0eE5WeFJq?= =?utf-8?B?djZ4aEV2bW9iN014MGhBR1JYMGkrTzdVNEZJUEMzRzF6UzBXYU10c2kvUVZ6?= =?utf-8?B?ZE5tS3BENk01cnFPS0dTWlo4UzFVK2FJTFEwc3ZkRXNUeFgyR0hiYldGUTBD?= =?utf-8?B?U0xENXNOVFhzU3N1YW1JK0xjYzcxSTdIREZMSXFtbEhNNlRySHk5NUova0tp?= =?utf-8?B?SmhLY2xBYWVYbCs3aGxkNkUxQUtmb2NkSVI2M0NRNEVwTnhQWSt0NGs1TXhT?= =?utf-8?B?eEtXaWsxWkpsK1N2ZkxoSlJPK0o1dldzTnBoT3BkMHlyYlh0Q3d5TkhOektn?= =?utf-8?B?bW1YNTVidXJNZXUyNkVSQXFwZ1Axa09aV2I1ejZzNDRoL21MeW5NejRjRmpq?= =?utf-8?B?UkRvWkxNUHl5cmg3V0F0T1NnUzZ1VWpGRXBQUGVlNklPYmxORFpucXVTbUh3?= =?utf-8?B?SFlQb21sTFZ5cTV6MXluSk1hNGJHMm1Gb1FlZW1tSXVEM2diN1EvMklVeXBk?= =?utf-8?B?a0d6d2Z6aDlvOERnb1ZhN2N0ZjgyQld2QTBRRXFTK1VwNHNWbWM3Y1cxNGIw?= =?utf-8?B?d2V5R25WdEtPWk51bFE4MlZ4V3FZczIyS1pQNkxkMWVDUUo3U1lNWE5yUFcy?= =?utf-8?B?MGRNQ1ZvcGQya3BGUVZNcElDR0xMcjZERjdsenFrSlhScDd2cC91WTFha1R4?= =?utf-8?B?Y1l2WGRKRHpBY0pRemwzMTBpZUVObHNmZUh0dUxCVGx1aUtLUE9QeDdYM3p6?= =?utf-8?B?RTRHeGRpOTRZRzF0bGxoSmgvN05pa2pwS2ZGekFVSGJHRnBpUjE3MzF5VjRa?= =?utf-8?B?S1pPV3pDWjZZTGo4bEFCZ1krR3hzQWl3aHF6NldKNlRYQVAvWjk1ZHRiZ3lQ?= =?utf-8?B?RXRPRGh0cllzYy9TOFlIMkd5Q28ycE52UEVpa3poVDh1eXQzbFgwQmJobWt1?= =?utf-8?B?OEplV1pFQmFoQ1hVdG9qY0g1dFpoL04xWmx5Z25ScEl4bDZjNjVqVXZ4SHBQ?= =?utf-8?B?SzNpYXZIWUdpZGxnV1ZJL3o4MHdMMFFPL01KMXQ5dG11OS90UU0vLzlNc05C?= =?utf-8?B?eEQ2YU0wb1NmWDJtaG5ESktKNm4xNTRsaFNtM1UwVzNseXZvczlOMXArVk1K?= =?utf-8?B?dnZWWitSSGI1bXljQjJQVTVhTDN1dTcyNW9WRzZDSGRRekVCbUcyUE9kdHhk?= =?utf-8?B?Q2R2S2xXaFJYaFd4Z2xkQnVSYU1uRCtJaUFsZFEwR3ZGbHdpc1gvUDZWalNE?= =?utf-8?B?dDJvVkZ4bGxReXF0b2dYeDJWYk8rUHc2SGkyYzA2RjlMNDJ2MDVqTWlvM3ow?= =?utf-8?B?MmZEMGZnd2xlL1RIdDNoY1hHNjB0NVBSZkxWdDEyQzFyeHp6aGQ1MFhyL01W?= =?utf-8?B?d3Q5UG9ZejJtT3hYcU5rWk1pRHlSZjJBV2VEUlAvM3FBbVJUS3l6VlR6Tnp5?= =?utf-8?B?Qy80aSttejQxb2FBb1BaNDc4REdCNysvN3BDYWhXRXhLY3Y4V1A0QjJEeVUz?= =?utf-8?B?UTJBZGFrQ09VN3JseGxMbWlFK0VlQTdueUIrT05kdTVWb04zejBqM3MvRUY4?= =?utf-8?B?aEhWcUxEQ24yL2R5am5LZ0ZLd3BSV2JTQ09wUjk1VFdRN2tQS2RhaXZ5NCtR?= =?utf-8?B?WWVZR1lsc2pmVVl3RGsyUzhkaUhDc3ZrT2NmM2xsWnBqaGVvQ0Rmc0ZKUnNy?= =?utf-8?B?YkpoZFFaejdySmQyMGd6USt5RXNnR0V6QmgxNDlESThVV2MyUzc3eVFQUXNo?= =?utf-8?B?c3BnZURTSkZvT1J5TVp6ajA1STBVR3Y0ODNPUG1IaDZGKzJJUEJ4clVISGNr?= =?utf-8?B?cHNjZjhEaUdpTWpTQ1Zwa1BuRlpaQWF2TkVTd1FvOXFHVmttQXdnRTdjRm1x?= =?utf-8?B?Um1jdWFWWnVBV0VyYmVPRUJubHdvT21IWUR6MGkva005dEVmUVdzYnVzWVJ3?= =?utf-8?B?dUhZaU04SHZxWThteG9wcmhUMjI2RmNkRHlRdmM4VGFpb3VtcVp3ekxxWm9s?= =?utf-8?B?ZE1zRkhJeERjcHlwY2YwTmxkbTROc2dzcFRleUdqOGZ6Q201MThUU3VhdWRU?= =?utf-8?B?OHl1eFAwS0ZPcVNUOHFUUmYzT1NpNmI2ZGdtY3A3dTBGcjdkZ3pQeExKMTQ1?= =?utf-8?B?M1QwNHBaVUJuYmwybkZNdVEvcnNNRGJqM1J5S3pxbjJnZmRRSlRCZz09?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2aa4b1ef-7f63-4400-21c7-08dead30e795 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:49.0225 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: aRq117yklppaJ2/YbGLr5/4ZWZZ6gP4S71mjOkZobwHo90r678lwEhKZ5DWFS2iT9h/rvqUmgsuyYys6ktqhJA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6205 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c105::1; envelope-from=tdave@nvidia.com; helo=CH1PR05CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265527019154100 Extend the fixed BAR allocator to handle remaining 64-bit prefetchable BARs after fixed BAR placement. For each bus with fixed BAR devices, collect fixed and unassigned BARs, compute available MMIO64 holes considering both local fixed BAR anchors and globally claimed regions, and select an appropriate region to pack remaining BARs. Remaining BARs are sorted by size and packed into the selected hole using a greedy placement strategy. Fixed BAR placement is preserved, and all allocations are tracked via the global claim list. After BAR placement, update the PCI bridge prefetchable window to cover both fixed and dynamically assigned BAR ranges, ensuring firmware sees a consistent MMIO layout. This implements the second phase of the allocator that does dynamic BAR placement and bridge window sizing for buses with fixed BAR constraints. Signed-off-by: Tushar Dave --- hw/pci/pci-resource.c | 404 +++++++++++++++++++++++++++++++++++++++++- hw/pci/pci-resource.h | 17 ++ 2 files changed, 420 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci-resource.c b/hw/pci/pci-resource.c index 5e9a78ec16..de98924aa6 100644 --- a/hw/pci/pci-resource.c +++ b/hw/pci/pci-resource.c @@ -7,6 +7,7 @@ =20 #include "qemu/osdep.h" #include "qemu/error-report.h" +#include "qemu/bitops.h" #include "qemu/range.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bridge.h" @@ -158,6 +159,404 @@ static void pci_program_prefetch_bars(PCIDevice *dev,= PhysBAR *pbars) } } =20 +static void pci_update_prefetch_window(PCIBus *bus, uint64_t base, uint64_= t limit) +{ + PCIDevice *bridge =3D pci_bridge_get_device(bus); + uint32_t reg_base, reg_limit; + + assert(bridge); + + reg_base =3D (uint32_t)(extract64(base, 20, 12) << 4); + reg_limit =3D (uint32_t)(extract64(limit, 20, 12) << 4); + pci_host_config_write_common(bridge, + PCI_PREF_MEMORY_BASE, + pci_config_size(bridge), + reg_base | PCI_PREF_RANGE_TYPE_64, + 2); + pci_host_config_write_common(bridge, + PCI_PREF_BASE_UPPER32, + pci_config_size(bridge), + (uint32_t)(base >> 32), + 4); + pci_host_config_write_common(bridge, + PCI_PREF_MEMORY_LIMIT, + pci_config_size(bridge), + reg_limit | PCI_PREF_RANGE_TYPE_64, + 2); + pci_host_config_write_common(bridge, + PCI_PREF_LIMIT_UPPER32, + pci_config_size(bridge), + (uint32_t)(limit >> 32), + 4); +} + +static inline bool is_64bit_pref_bar(PCIIORegion *r) +{ + if (!r->size) { + return false; + } + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { + return false; + } + if (!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) { + return false; + } + if (!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH)) { + return false; + } + return true; +} + +/* Comparison function for sorting intervals by start address */ +static int compare_intervals(gconstpointer a, gconstpointer b) +{ + const AddressInterval *ia =3D (const AddressInterval *)a; + const AddressInterval *ib =3D (const AddressInterval *)b; + if (ia->start < ib->start) return -1; + if (ia->start > ib->start) return 1; + return 0; +} + +/* Comparison function for sorting BARs by descending size */ +static int compare_bar_size_desc(gconstpointer a, gconstpointer b) +{ + const BarEntry *ea =3D (const BarEntry *)a; + const BarEntry *eb =3D (const BarEntry *)b; + if (ea->size > eb->size) return -1; + if (ea->size < eb->size) return 1; + return 0; +} + +/* Categorize holes relative to anchors */ +static CategorizedHoles categorize_holes(GArray *holes, GArray *fixed_bars) +{ + CategorizedHoles result =3D { + .leftmost_hole =3D -1, + .middle_holes =3D g_array_new(false, false, sizeof(int)), + .rightmost_hole =3D -1 + }; + + /* Get anchor boundaries */ + uint64_t first_anchor_start =3D g_array_index(fixed_bars, AddressInter= val, 0).start; + uint64_t last_anchor_end =3D g_array_index(fixed_bars, AddressInterval, + fixed_bars->len - 1).end; + /* Categorize each hole */ + for (guint h =3D 0; h < holes->len; h++) { + AddressInterval *hole =3D &g_array_index(holes, AddressInterval, h= ); + + if (hole->end < first_anchor_start) { + result.leftmost_hole =3D h; /* Before all anchors */ + } else if (hole->start > last_anchor_end) { + result.rightmost_hole =3D h; /* After all anchors */ + } else { + g_array_append_val(result.middle_holes, h); /* Between anchor= s */ + } + } + return result; +} + +/* + * Compute REAL holes considering both local anchors and global claims. + * This returns actual free space that can be used for packing. + * Strategy: Collect all obstacles (local fixed BARs + global claims from + * other buses), then compute gaps between them. + */ +static GArray* compute_real_holes(GArray *fixed_bars, uint64_t mmio_start,= uint64_t mmio_end) +{ + GArray *holes =3D g_array_new(false, false, sizeof(AddressInterval)); + GArray *claimed_regions =3D g_array_new(false, false, sizeof(AddressIn= terval)); + uint64_t scan; + + /* Add local fixed BARs (anchors) as claimed regions */ + for (guint i =3D 0; i < fixed_bars->len; i++) { + AddressInterval *anchor =3D &g_array_index(fixed_bars, AddressInte= rval, i); + g_array_append_val(claimed_regions, *anchor); + } + + /* Add global claims from ALL buses (including other buses) */ + if (fixed_claim_regions) { + for (guint i =3D 0; i < fixed_claim_regions->len; i++) { + FixedClaim *claim =3D &g_array_index(fixed_claim_regions, Fixe= dClaim, i); + /* Only consider claims within our MMIO window */ + if (claim->start <=3D mmio_end && claim->end >=3D mmio_start) { + AddressInterval region =3D { + .start =3D claim->start, + .end =3D claim->end + }; + g_array_append_val(claimed_regions, region); + } + } + } + + /* Handle case with no claimed regions */ + if (claimed_regions->len =3D=3D 0) { + AddressInterval hole =3D { .start =3D mmio_start, .end =3D mmio_en= d }; + g_array_append_val(holes, hole); + g_array_free(claimed_regions, true); + return holes; + } + + /* Sort claimed regions by start address */ + g_array_sort(claimed_regions, compare_intervals); + + /* Compute holes between all claimed regions */ + scan =3D mmio_start; + for (guint i =3D 0; i < claimed_regions->len; i++) { + AddressInterval *claimed =3D &g_array_index(claimed_regions, Addre= ssInterval, i); + + /* Free space before this claimed region */ + if (scan < claimed->start) { + AddressInterval hole =3D { .start =3D scan, .end =3D claimed->= start - 1 }; + g_array_append_val(holes, hole); + } + + /* Move scan cursor past this claimed region */ + scan =3D MAX(scan, claimed->end + 1); + } + + /* Free space after last claimed region */ + if (scan <=3D mmio_end) { + AddressInterval hole =3D { .start =3D scan, .end =3D mmio_end }; + g_array_append_val(holes, hole); + } + + g_array_free(claimed_regions, true); + return holes; +} + +static bool pack_bars_into_region(GArray *bars, uint64_t pack_start, uint6= 4_t pack_end, + uint64_t *out_min_addr, uint64_t *out_m= ax_addr) +{ + uint64_t pack_cursor =3D pack_start; + uint64_t min_addr =3D UINT64_MAX; + uint64_t max_addr =3D 0; + + for (guint i =3D 0; i < bars->len; i++) { + BarEntry *e =3D &g_array_index(bars, BarEntry, i); + PCIIORegion *r =3D &e->dev->io_regions[e->bar_idx]; + + uint64_t aligned_addr =3D ROUND_UP(pack_cursor, r->size); + uint64_t bar_start =3D aligned_addr; + uint64_t bar_end =3D bar_start + r->size - 1; + + if (bar_end > pack_end) { + return false; /* Doesn't fit */ + } + + PhysBAR pbars_array[PCI_ROM_SLOT]; + memset(pbars_array, 0, sizeof(pbars_array)); + pbars_array[e->bar_idx].addr =3D bar_start; + pbars_array[e->bar_idx].end =3D bar_end; + pbars_array[e->bar_idx].flags =3D IORESOURCE_PREFETCH; + + pci_program_prefetch_bars(e->dev, pbars_array); + + min_addr =3D MIN(min_addr, bar_start); + max_addr =3D MAX(max_addr, bar_end); + pack_cursor =3D bar_end + 1; + } + + *out_min_addr =3D min_addr; + *out_max_addr =3D max_addr; + return true; +} + +static void finalize_bridge_window(PCIBus *bus, uint64_t min_addr, uint64_= t max_addr) +{ + PCIDevice *bridge_dev =3D pci_bridge_get_device(bus); + + if (bridge_dev) { + fixed_claim_regions_add(min_addr, max_addr, bridge_dev, -1); + pci_update_prefetch_window(bus, min_addr, max_addr); + } +} + +static bool pci_bus_phase2_fill_bar_lists(PCIBus *bus, PciProgramCtx *pctx, + GArray *fixed_bars, GArray *rema= ining_bars) +{ + AddressInterval interval; + BarEntry bentry; + PCIDevice *d; + PCIIORegion *r; + bool bus_has_fixed =3D false; + bool device_has_fixed; + int devfn, i; + + for (devfn =3D 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + d =3D bus->devices[devfn]; + if (!d) { + continue; + } + device_has_fixed =3D g_hash_table_contains(pctx->had_fixed, d); + if (device_has_fixed) { + bus_has_fixed =3D true; + } + for (i =3D 0; i < PCI_ROM_SLOT; i++) { + r =3D &d->io_regions[i]; + if (!is_64bit_pref_bar(r)) { + continue; + } + if (device_has_fixed && d->fixed_bar_addrs && + d->fixed_bar_addrs[i] !=3D PCI_BAR_UNMAPPED) { + interval.start =3D d->fixed_bar_addrs[i]; + interval.end =3D d->fixed_bar_addrs[i] + r->size - 1; + g_array_append_val(fixed_bars, interval); + } else { + bentry.dev =3D d; + bentry.bar_idx =3D i; + bentry.size =3D r->size; + g_array_append_val(remaining_bars, bentry); + } + } + } + return bus_has_fixed; +} + +/* Find a mmio64 hole, pack unassigned BARs and program the bridge */ +static void +pci_bus_phase2_hole_pack_and_update_bridge(PCIBus *bus, GArray *fixed_bars, + GArray *remaining_bars, + uint64_t mmio_start, + uint64_t mmio_end) +{ + GArray *holes; + FixedClaim *claim; + CategorizedHoles cat; + AddressInterval *holep, *selected; + int selected_hole, largest_middle, h_idx; + guint c, mid_i, f; + uint64_t bus_min_addr, bus_max_addr, remaining_demand; + uint64_t leftmost_anchor, rightmost_anchor_end, valid_start, valid_end; + uint64_t largest_size, hole_size, pack_start, pack_end; + + g_array_sort(fixed_bars, compare_intervals); + g_array_sort(remaining_bars, compare_bar_size_desc); + + remaining_demand =3D 0; + for (c =3D 0; c < remaining_bars->len; c++) { + remaining_demand +=3D g_array_index(remaining_bars, BarEntry, c).s= ize; + } + + leftmost_anchor =3D g_array_index(fixed_bars, AddressInterval, 0).star= t; + rightmost_anchor_end =3D g_array_index(fixed_bars, AddressInterval, + fixed_bars->len - 1).end; + + valid_start =3D mmio_start; + valid_end =3D mmio_end; + + if (fixed_claim_regions) { + for (c =3D 0; c < fixed_claim_regions->len; c++) { + claim =3D &g_array_index(fixed_claim_regions, FixedClaim, c); + if (claim->end < leftmost_anchor && claim->end >=3D valid_star= t) { + valid_start =3D claim->end + 1; + } + if (claim->start > rightmost_anchor_end && claim->start <=3D v= alid_end) { + valid_end =3D claim->start - 1; + } + } + } + + holes =3D compute_real_holes(fixed_bars, valid_start, valid_end); + cat =3D categorize_holes(holes, fixed_bars); + + selected_hole =3D -1; + pack_start =3D 0; + pack_end =3D 0; + + if (cat.middle_holes->len > 0) { + largest_middle =3D -1; + largest_size =3D 0; + for (mid_i =3D 0; mid_i < cat.middle_holes->len; mid_i++) { + h_idx =3D g_array_index(cat.middle_holes, int, mid_i); + holep =3D &g_array_index(holes, AddressInterval, h_idx); + hole_size =3D holep->end - holep->start + 1; + if (hole_size >=3D remaining_demand && hole_size > largest_siz= e) { + largest_size =3D hole_size; + largest_middle =3D h_idx; + } + } + if (largest_middle >=3D 0) { + selected_hole =3D largest_middle; + } + } + if (selected_hole < 0 && cat.rightmost_hole >=3D 0) { + holep =3D &g_array_index(holes, AddressInterval, cat.rightmost_hol= e); + hole_size =3D holep->end - holep->start + 1; + if (hole_size >=3D remaining_demand) { + selected_hole =3D cat.rightmost_hole; + } + } + if (selected_hole < 0 && cat.leftmost_hole >=3D 0) { + holep =3D &g_array_index(holes, AddressInterval, cat.leftmost_hole= ); + hole_size =3D holep->end - holep->start + 1; + if (hole_size >=3D remaining_demand) { + selected_hole =3D cat.leftmost_hole; + } + } + g_array_free(cat.middle_holes, true); + if (selected_hole < 0) { + error_report("bus [%02x] insufficient contiguous space for " + "remaining_demand=3D0x%"PRIx64, + pci_bus_num(bus), remaining_demand); + g_array_free(holes, true); + g_array_free(fixed_bars, true); + g_array_free(remaining_bars, true); + exit(1); + } + selected =3D &g_array_index(holes, AddressInterval, selected_hole); + pack_start =3D selected->start; + pack_end =3D selected->end; + g_array_free(holes, true); + if (!pack_bars_into_region(remaining_bars, pack_start, pack_end, + &bus_min_addr, &bus_max_addr)) { + error_report("bus [%02x] failed to pack BARs", pci_bus_num(bus)); + g_array_free(fixed_bars, true); + g_array_free(remaining_bars, true); + exit(1); + } + for (f =3D 0; f < fixed_bars->len; f++) { + holep =3D &g_array_index(fixed_bars, AddressInterval, f); + bus_min_addr =3D MIN(bus_min_addr, holep->start); + bus_max_addr =3D MAX(bus_max_addr, holep->end); + } + finalize_bridge_window(bus, bus_min_addr, bus_max_addr); + g_array_free(fixed_bars, true); + g_array_free(remaining_bars, true); +} + +static void pci_bus_phase2_pack_remaining_bars(PCIBus *bus, void *opaque) +{ + PciProgramCtx *pctx =3D (PciProgramCtx *)opaque; + GArray *fixed_bars, *remaining_bars; + uint64_t mmio_start, mmio_end, bus_min_addr, bus_max_addr; + bool bus_has_fixed; + + mmio_start =3D pctx->mmio64_base; + mmio_end =3D pctx->mmio64_base + pctx->mmio64_size - 1; + fixed_bars =3D g_array_new(false, false, sizeof(AddressInterval)); + remaining_bars =3D g_array_new(false, false, sizeof(BarEntry)); + bus_has_fixed =3D pci_bus_phase2_fill_bar_lists(bus, pctx, fixed_bars, + remaining_bars); + if (!bus_has_fixed) { + g_array_free(fixed_bars, true); + g_array_free(remaining_bars, true); + return; + } + if (remaining_bars->len =3D=3D 0) { + if (fixed_bars->len > 0) { + g_array_sort(fixed_bars, compare_intervals); + bus_min_addr =3D g_array_index(fixed_bars, AddressInterval, 0)= .start; + bus_max_addr =3D g_array_index(fixed_bars, AddressInterval, + fixed_bars->len - 1).end; + finalize_bridge_window(bus, bus_min_addr, bus_max_addr); + } + g_array_free(fixed_bars, true); + g_array_free(remaining_bars, true); + return; + } + pci_bus_phase2_hole_pack_and_update_bridge(bus, fixed_bars, remaining_= bars, + mmio_start, mmio_end); +} /* Phase 1: claim and program fixed BARs for one device (per-device callba= ck) */ static void pci_dev_claim_and_program_fixed_bars(PCIBus *bus, PCIDevice *d= ev, void *opaque) { @@ -247,7 +646,10 @@ void pci_fixed_bar_allocator(PCIBus *root, const PciFi= xedBarMmioParams *mmio) /* Phase 1: program all fixed BARs and claim them */ pci_for_each_bus(bus, pci_bus_claim_and_program_fixed_bars, &pctx); =20 - /* TODOs: Phases 2=E2=80=933, program remaining BARs, bridge window re= fresh etc,. */ + /* Phase 2: pack remaining 64-bit prefetchable BARs and size parent br= idge window */ + pci_for_each_bus(bus, pci_bus_phase2_pack_remaining_bars, &pctx); + + /* Phase 3: buses with no fixed-BAR devices; final bridge pass: follow= -up */ =20 /* Cleanup */ g_hash_table_destroy(pctx.had_fixed); diff --git a/hw/pci/pci-resource.h b/hw/pci/pci-resource.h index cc4d6f71cb..5155a7cefa 100644 --- a/hw/pci/pci-resource.h +++ b/hw/pci/pci-resource.h @@ -47,6 +47,23 @@ typedef struct FixedClaim { int bar; } FixedClaim; =20 +typedef struct { + uint64_t start; + uint64_t end; +} AddressInterval; + +typedef struct { + PCIDevice *dev; + int bar_idx; + uint64_t size; +} BarEntry; + +typedef struct { + int leftmost_hole; /* Index of hole before first anchor, or -1 */ + GArray *middle_holes; /* Array of hole indices between anchors */ + int rightmost_hole; /* Index of hole after last anchor, or -1 */ +} CategorizedHoles; + typedef struct { hwaddr mmio64_base; hwaddr mmio64_size; --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265543; cv=pass; d=zohomail.com; s=zohoarc; b=MCxnzrfaMemDAVbWVZGZza2Ddio14rpdVn2Ymku9FHtjhC7/v0BxvfPy/cl7o0RL68J4lwKwHj85D1S786rKo/pTfh0aBjp5PNyQvc0tECWc3ER0UucJ/aJTTBX5rqScvkdtgpEorsqtoiZpmcn6lSYMA/GRrsL94ekvXQqIuhs= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265543; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=cxDvV4LZ4ek8q78zLfgg06hLW8aN2srFmLdvM6m92Gc=; b=B3eR2Ao1HvCmUf9nGE1OePh+4BgBLXW9tgRDp0awHgIL5ffUQipt1m+hogOXZXZpOk6FM/gOWa5HYeQmBa+14k20YnrvovrzrkOnRJifcarAGj4/ru+X16kdwYKBLw8nRqSLSaJ9NuL5yKsgXWhjrnWcv271J/AX3CaAPMWCfvI= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265543731211.8535627079849; Fri, 8 May 2026 11:39:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5Y-0006hq-BA; Fri, 08 May 2026 14:38:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5O-0006gQ-Iq; Fri, 08 May 2026 14:38:06 -0400 Received: from mail-northcentralusazlp170100001.outbound.protection.outlook.com ([2a01:111:f403:c105::1] helo=CH1PR05CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5M-0002b2-3S; Fri, 08 May 2026 14:38:06 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by DM4PR12MB6205.namprd12.prod.outlook.com (2603:10b6:8:a8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.15; Fri, 8 May 2026 18:37:51 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:51 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=v8FtgfQspDt8XpIK1nXypmybTNcMbCPBIefl2mNoR4KCb1wyg2cGD1xnLvkqL2EuipfQhjLLMSJ3hMsdtWjAG5YExkha02xtXLdNfjHv+jFUtmgN/E5lp9j8m4omzjeMR0cbaNS3IXCePZDnF4PQxwXz/QVygxcs4eFLihjvsvmv3HRCw+DGIfJk8qy5Lu324TbX2IzdZEfK6CvPoq2i1oaVpiHwk8L9JnPWzLIyT4njErh15VIN1IF8fHnnp0c17CIJBUMyLh7SUnXIyhc+R3X4fFf7KSau2mHnXDjGCVP5GHt4NxjD7dLsrrJZRO0hSbgW6Ih8hKQOXxOCPrrA6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=cxDvV4LZ4ek8q78zLfgg06hLW8aN2srFmLdvM6m92Gc=; b=lN0MUQiOULMoNqBKgOjYgnKgndS5fmHnKczx3pc+tUYfxmQv8ooVdnlkOE5Y1fO4qvxO+inhllDxraIFK2X5N4W9qFJ5cxQ+hIyOVKMy6jZNrG/dmNfUp3KFZyXCIcudXEzsSXdFtb23EoYi/dxvx/4jB25rJmvQI3ihTFA68qADgQTyciPxshQKUnaV3x12x9s1Gx9Ipcdfk6uU41cpfUSUxiW+JFxDcAyJBQkzbhf1OHjnmORIOdmPSbd1WGfQHAwSUyRYYl6h62VXc+gGNyykJzcEz2+vjH5yYmD3H6L/Coc1B9V3KXlxd6VILosROOJ4IVRqnGjp5ntFET2Qdg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cxDvV4LZ4ek8q78zLfgg06hLW8aN2srFmLdvM6m92Gc=; b=VCuso00Tww8StwdHPE59Lp4G59sNgi27cxczFr4sd8zidx2DcPSdyklEfTDv2Qqa0p+1DB5H4gQ7jzgovaOTPNWXc6ST1LPLWnJLdFbSS/y+tvWm3Unvl6n9Vv8DUZ/jQ/62vP55YtJrMGF2Z3+e8Ydwe7Z6SVwVI2nOb+GbBRZxbAn+PudsrgXOnTY2uvup9hzL5Zq4aG7nm8hWawrbJMWa+mFFp6aes2V3m47IU2ZjIglOzoBPo4Otl4FY4gaBEr+W7/6x07StJGrfTQ9XP3z/iSDWMi7ZMq7tM0zRIUKpCnk7QacVTfnPUav5it669DUFOeUQFG5WQF1Hl0Xnzw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 5/8] hw/pci: allocate remaining BARs for buses without fixed BARs Date: Fri, 8 May 2026 13:37:14 -0500 Message-Id: <20260508183717.193630-6-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0P221CA0021.NAMP221.PROD.OUTLOOK.COM (2603:10b6:208:52a::25) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|DM4PR12MB6205:EE_ X-MS-Office365-Filtering-Correlation-Id: b889e638-85a6-49e0-485a-08dead30e8f2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|1800799024|376014|22082099003|18002099003|56012099003; X-Microsoft-Antispam-Message-Info: bAWKxHOpxI6m06hDAtwA7J3P1wk+6yDcVzKG9/BvJzJDja5YmZ3QpQ7noNdZO+GRKgeN2B9DaPCIz9362iBjWNy9Cdg/Non/keRg/uVBrggZCZPVyvDbcCNEuFsY4+AuPv+E+TmnEn/OR3g9eLQV70bdV81bqK6PbggYZCwhmns4zWTIy7hn5YpA2Yb2au4hPeZW9abv1CDh4ULW1dATdKbnEqgWJuBeskklTamPG4kFuzw8kGomhD+2IXW6OK9oo1rNK2/03trFWLPKtxZxOCALR9sJJdvtcrBvi06cfIuZbMSmBSkjcUj7qVrCRF9x9AT7XXw0sQlPSMshRkEbloxybZzMacRTMewyLIe925L7fk6ChfjakZkwecIOf4bbvxd/YperIgraoxrjYqeRGiFSQEN1u0LAlbVS6xyhFSBKU69bpjP8ttfE4yTJrnGvcvXgzWk3OfvWL0T8RbvQmOjqMF67YTGXP2RKpk4ot7p2IvVxxO5zWKVs00Z9XBH1XflzBFv5k3oJLnb9dPOhwV2cQnQgUMQn7hMZcWIi9tj1xhFVzoJjufGns+oQ6xCsvbM5e00DmYgb2JmwctyjS+rd3lJQYn6dyb/N6dAQlUMEtBVJTD79D2Mz4TwZkcDkJNyBu9CMmjEOTEk0x/t8ipKd/v7swfoyX6VDasvLzFIcIzHds866MpQbK4V4ED+f X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014)(22082099003)(18002099003)(56012099003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?rKNPOJvSY/g2FGYvckGMRzXy3nAT03LUHbK7zqTelcDw9Tay5di8HsJPojun?= =?us-ascii?Q?b59yrdj+HIcN9pb6qsbIoXRV2pbM20NP6yyS0CXumbGNsR7cCvriqAtUIbcR?= =?us-ascii?Q?/GJIvSpLvhTgxVfBuWStQoxB6pce04ppeqxWfzrtRB27TjKFMaM3nOHtvwna?= =?us-ascii?Q?5IQPzSbGoeaCZq4Y6Pbim9wITi2Ujn+vebbFEVW3VpCsfIaRmAzwyLUZr4Rk?= =?us-ascii?Q?CoJ5wGM3RNxZ2he1Fp0lgegNnpyfyMqS4+u+iSzWuZLBC3W/IGxzWoQv/djK?= =?us-ascii?Q?bfWcm30fomjqxC3n7bo3AtyxbDsLhrv6LrrOJdR9STcTmV1k5wajh6mfKmqm?= =?us-ascii?Q?eP2MNEAw7y5qYIhOdwvS/OlpkGRbtpQXZNXerQvZus3lN7kZkvAwBxz+Q7Jy?= =?us-ascii?Q?yZeCohg+o/vtSP/HSPzdY7bwpEDrKlhDFdQlvVSnR+/5uR+n8oOc24bXAWxS?= =?us-ascii?Q?Zn5i+Ke/yEZ7quZOszP8jYUh/fQj+JtFTRcEc5P9Q/9EWraHlIKJZoYvb0p1?= =?us-ascii?Q?ulB88rTt25uWYC9FnYVHWnQ/+FM6lqO3OhwYvby0yC+HDn3i3BumbCizAedm?= =?us-ascii?Q?Ap0XXKm+GeAG6RFs//U/yb/W3EdYx7LduJ0TrbauchmkknHcz+c6Q9oi+cUY?= =?us-ascii?Q?63lAqye3kmvlmYyztciXvkQVvT39VPRI87QVjXzyVijAhBzYjqQtnnh+DEjZ?= =?us-ascii?Q?SNGQEMX3XCynasg7w8pIAYV3kBSongzH6iaFyXFUQScYYZAhAYem+hwcJJ2o?= =?us-ascii?Q?jQrTNzFaSftPi20grPP8SbW/w14B+nJdHKInZGpsvP6OBqLnHWtO17BRfFsv?= =?us-ascii?Q?RCR9lV2e9s7jRwI9LFdglCNKs69TPje5bIJHrDEm7oS7jvQkQL6F7irbRUc1?= =?us-ascii?Q?WZHpPwDVrVRwB4xDI340k74gBxYCkt17inPjorNCr6KFEE/HtuXitVlYX6+C?= =?us-ascii?Q?JWBlPn03a640DufvUBjuA5thesWDyciOq/Z6lmeSo4uo08nk/mGvZ1Sa4qwW?= =?us-ascii?Q?1q7EM00m17fv/n13O2EK6MBCxQ2YrU9QSG0NunT+Zuh/biqJ3sWzR2JFNPrO?= =?us-ascii?Q?w4LEF9F9DvSyXRqyr6zsILN9t9a3j90Oht950J3CtgykKhDoRYuavH74XM5h?= =?us-ascii?Q?XkdYiM/nroH6GVzVZBYUnO5LABH3DuGDdRtrIud2gLbxEaDOz6nn0P/zBsWK?= =?us-ascii?Q?TiHb4HQ7rFIBiv4iUY7sNKObSruSDozWRau8g/dnDghDX5xtr6bvLM2S8nri?= =?us-ascii?Q?MOEajsFRBg6YAGZUZkgH1BhivV4Esp/UKN2SWOhu6VVQ3amCYGoJ7ACcgBue?= =?us-ascii?Q?7fD8oVsCn8SBnkdcLiib5jF4NGc5+YdyW3H4n3ssIj5gdxs7Z/xzTfB4rd5t?= =?us-ascii?Q?IE5mUsaqavsQVSpfsVBSzO1bbWidXwOLyhg+u6jJb7lXWfkSICLf609fn/mk?= =?us-ascii?Q?BidXnWNWpCESqV34CQd4NxDvHEq+s9ivpwhFP/kqbKvU9/E1xl+Cbq/zHkwM?= =?us-ascii?Q?EnQPiBU3INVb0Wl+pCdXFyHSXXpS3ce2ZemaOqRoCMj1Fc4jo1K5PTOH4rep?= =?us-ascii?Q?s6j/tHU/trphJWYKLwle6AuuZvN4c+WR7+ufMwGb+VFGehrII9dTC8AOjdyW?= =?us-ascii?Q?LvjCwYAAgHfNJYVcdFADQ+pO09jLeDTTn46+3N2gUkSeZxEyf8rtLM2UHtDU?= =?us-ascii?Q?0dlWR/8RK4zapTmtUgQV1E3PELxi4pTzATziRvfjjihiBTopHPCuiPlJjvk5?= =?us-ascii?Q?zDTzhN9Fmg=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: b889e638-85a6-49e0-485a-08dead30e8f2 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:51.2581 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: i63nodeRj54rYsPGA9Vvv1O1MysuFV7F28/j7mlsGAwa3QRHLiJzcgWurNMlzB1iyEh/IlmOSY1Tfb594Wh55Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6205 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c105::1; envelope-from=tdave@nvidia.com; helo=CH1PR05CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265544409158500 Content-Type: text/plain; charset="utf-8" This phase performs PCI BAR allocation for buses without fixed BAR assignments. It respects existing allocations and does not disturb already programmed BARs or bridge windows. It computes remaining MMIO64 requirements, assigns BARs, and extends bridge prefetch windows if required. Signed-off-by: Tushar Dave --- hw/pci/pci-resource.c | 355 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 354 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci-resource.c b/hw/pci/pci-resource.c index de98924aa6..e2d2adc7de 100644 --- a/hw/pci/pci-resource.c +++ b/hw/pci/pci-resource.c @@ -371,6 +371,358 @@ static void finalize_bridge_window(PCIBus *bus, uint6= 4_t min_addr, uint64_t max_ } } =20 +/* Returns true if this 64-bit pref BAR is already assigned */ +static bool bar_is_assigned(PCIDevice *dev, int bar_idx, GHashTable *had_f= ixed) +{ + PCIIORegion *r =3D &dev->io_regions[bar_idx]; + uint32_t lo; + uint32_t hi; + + if (!is_64bit_pref_bar(r)) { + return false; + } + if (dev->fixed_bar_addrs && + dev->fixed_bar_addrs[bar_idx] !=3D PCI_BAR_UNMAPPED) { + return true; + } + if (bar_idx >=3D PCI_ROM_SLOT - 1) { + return false; /* 64-bit BAR uses two slots */ + } + lo =3D pci_get_long(dev->config + PCI_BASE_ADDRESS_0 + bar_idx * 4); + if (!(lo & PCI_BASE_ADDRESS_MEM_TYPE_64)) { + return (lo & PCI_BASE_ADDRESS_MEM_MASK) !=3D 0; + } + hi =3D pci_get_long(dev->config + PCI_BASE_ADDRESS_0 + bar_idx * 4 + 4= ); + return (((uint64_t)hi << 32) | (lo & PCI_BASE_ADDRESS_MEM_MASK)) !=3D = 0; +} + +/* Return BAR address from config, or 0 if unassigned. */ +static uint64_t get_bar_addr_from_config(PCIDevice *dev, int bar_idx) +{ + PCIIORegion *r =3D &dev->io_regions[bar_idx]; + uint32_t lo; + uint32_t hi; + + if (!r->size || bar_idx >=3D PCI_ROM_SLOT - 1) { + return 0; + } + lo =3D pci_get_long(dev->config + PCI_BASE_ADDRESS_0 + bar_idx * 4); + if (lo & PCI_BASE_ADDRESS_MEM_TYPE_64) { + hi =3D pci_get_long(dev->config + PCI_BASE_ADDRESS_0 + bar_idx * 4= + 4); + return ((uint64_t)hi << 32) | (lo & PCI_BASE_ADDRESS_MEM_MASK); + } + return lo & PCI_BASE_ADDRESS_MEM_MASK; +} + +/* Total size of unassigned 64-bit pref BARs in this bus and its subtree. = */ +static uint64_t size_entire_subtree(PCIBus *bus, GHashTable *had_fixed) +{ + uint64_t total =3D 0; + + for (int devfn =3D 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d =3D bus->devices[devfn]; + if (!d) { + continue; + } + for (int i =3D 0; i < PCI_ROM_SLOT; i++) { + PCIIORegion *r =3D &d->io_regions[i]; + if (!is_64bit_pref_bar(r)) { + continue; + } + if (bar_is_assigned(d, i, had_fixed)) { + continue; + } + total +=3D r->size; + } + if (IS_PCI_BRIDGE(d)) { + total +=3D size_entire_subtree(pci_bridge_get_sec_bus(PCI_BRID= GE(d)), had_fixed); + } + } + return total; +} + +/* Highest end address of any assigned BAR or bridge window in this bus an= d subtree. */ +static uint64_t find_highest_assigned_in_bus(PCIBus *bus) +{ + uint64_t highest =3D 0; + uint64_t base; + uint64_t limit; + uint64_t addr; + + for (int devfn =3D 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d =3D bus->devices[devfn]; + if (!d) { + continue; + } + if (IS_PCI_BRIDGE(d)) { + PCIBus *sec =3D pci_bridge_get_sec_bus(PCI_BRIDGE(d)); + PCIDevice *bridge_dev =3D pci_bridge_get_device(sec); + if (bridge_dev) { + base =3D pci_bridge_get_base(bridge_dev, PCI_BASE_ADDRESS_= MEM_PREFETCH); + limit =3D pci_bridge_get_limit(bridge_dev, PCI_BASE_ADDRES= S_MEM_PREFETCH); + if (limit > base) { + highest =3D MAX(highest, limit); + } + highest =3D MAX(highest, find_highest_assigned_in_bus(sec)= ); + } + continue; + } + for (int i =3D 0; i < PCI_ROM_SLOT; i++) { + PCIIORegion *r =3D &d->io_regions[i]; + if (!is_64bit_pref_bar(r)) { + continue; + } + addr =3D 0; + if (d->fixed_bar_addrs && + d->fixed_bar_addrs[i] !=3D PCI_BAR_UNMAPPED) { + addr =3D d->fixed_bar_addrs[i]; + } else { + addr =3D get_bar_addr_from_config(d, i); + } + if (addr !=3D 0 && r->size) { + highest =3D MAX(highest, addr + r->size - 1); + } + } + } + return highest; +} + +/* Next free address in root MMIO64. */ +static uint64_t next_free_from_root(hwaddr mmio64_base, hwaddr mmio64_size) +{ + uint64_t mmio_start =3D mmio64_base; + uint64_t mmio_end =3D mmio64_base + mmio64_size - 1; + uint64_t highest; + + highest =3D mmio_start - 1; + if (fixed_claim_regions) { + for (guint i =3D 0; i < fixed_claim_regions->len; i++) { + FixedClaim *c =3D &g_array_index(fixed_claim_regions, FixedCla= im, i); + if (c->end >=3D mmio_start && c->start <=3D mmio_end) { + highest =3D MAX(highest, c->end); + } + } + } + return ROUND_UP(highest + 1, 0x1000); /* 4K align for new window */ +} + +static bool +pci_bus_phase3_ensure_parent_prefetch_window(PCIBus *bus, PciProgramCtx *p= ctx, + PCIDevice *parent_bridge, uin= t64_t mmio_end) +{ + PCIBus *parent_bus; + PCIDevice *grandparent; + uint64_t parent_win_base, parent_win_limit, next_in_subtree; + uint64_t required, window_base, window_limit; + bool window_not_programmed; + bool parent_in_mmio64; + + window_base =3D pci_bridge_get_base(parent_bridge, PCI_BASE_ADDRESS_ME= M_PREFETCH); + window_limit =3D pci_bridge_get_limit(parent_bridge, PCI_BASE_ADDRESS_= MEM_PREFETCH); + window_not_programmed =3D (window_base >=3D window_limit) || + (window_base < pctx->mmio64_base) || (window_l= imit > mmio_end); + if (!window_not_programmed) { + return true; + } + + required =3D size_entire_subtree(bus, pctx->had_fixed); + if (required =3D=3D 0) { + return false; + } + required =3D ROUND_UP(required, 0x1000); + + parent_bus =3D pci_get_bus(parent_bridge); + grandparent =3D parent_bus ? pci_bridge_get_device(parent_bus) : NULL; + if (!grandparent) { + window_base =3D next_free_from_root(pctx->mmio64_base, pctx->mmio6= 4_size); + window_limit =3D window_base + required - 1; + if (window_limit > mmio_end) { + error_report("bus [%02x] out of root MMIO64 space", pci_bus_nu= m(bus)); + exit(1); + } + } else { + parent_win_base =3D pci_bridge_get_base(grandparent, PCI_BASE_ADDR= ESS_MEM_PREFETCH); + parent_win_limit =3D pci_bridge_get_limit(grandparent, PCI_BASE_AD= DRESS_MEM_PREFETCH); + parent_in_mmio64 =3D (parent_win_limit > parent_win_base) && + (parent_win_base >=3D pctx->mmio64_base) && (pa= rent_win_limit <=3D mmio_end); + if (!parent_in_mmio64) { + window_base =3D next_free_from_root(pctx->mmio64_base, pctx->m= mio64_size); + window_limit =3D window_base + required - 1; + if (window_limit > mmio_end) { + error_report("bus [%02x] out of root MMIO64 space", pci_bu= s_num(bus)); + exit(1); + } + } else { + next_in_subtree =3D ROUND_UP( + find_highest_assigned_in_bus(parent_bus) + 1, 0x1000); + window_base =3D MAX(parent_win_base, next_in_subtree); + window_limit =3D window_base + required - 1; + if (window_limit > parent_win_limit) { + error_report("bus [%02x] no room in parent bridge window",= pci_bus_num(bus)); + exit(1); + } + } + } + finalize_bridge_window(bus, window_base, window_limit); + return true; +} + +static GArray *pci_bus_phase3_collect_unassigned_bars(PCIBus *bus, PciProg= ramCtx *pctx, + uint64_t *out_total_= size) +{ + PCIDevice *d; + PCIIORegion *r; + GArray *bars; + uint64_t required; + int devfn, i; + + required =3D 0; + bars =3D g_array_new(false, false, sizeof(BarEntry)); + for (devfn =3D 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + d =3D bus->devices[devfn]; + if (!d) { + continue; + } + for (i =3D 0; i < PCI_ROM_SLOT; i++) { + r =3D &d->io_regions[i]; + if (!is_64bit_pref_bar(r) || bar_is_assigned(d, i, pctx->had_f= ixed)) { + continue; + } + required +=3D r->size; + g_array_append_val( + bars, ((BarEntry){ .dev =3D d, .bar_idx =3D i, .size =3D r= ->size })); + } + } + *out_total_size =3D required; + return bars; +} + +static void +pci_bus_phase3_extend_window_for_bars(PCIBus *bus, PciProgramCtx *pctx, + PCIDevice *parent_bridge, uint64_t m= mio_end, + uint64_t current, uint64_t required, + uint64_t window_base, uint64_t *wind= ow_limit, + GArray *bars_this_bus) +{ + uint64_t parent_limit, gp_base, gp_limit, new_limit; + PCIBus *parent_bus; + PCIDevice *grandparent; + + if (current + required <=3D *window_limit) { + return; + } + + parent_bus =3D pci_get_bus(parent_bridge); + grandparent =3D parent_bus ? pci_bridge_get_device(parent_bus) : NULL; + parent_limit =3D mmio_end; + if (grandparent) { + gp_base =3D pci_bridge_get_base(grandparent, PCI_BASE_ADDRESS_MEM_= PREFETCH); + gp_limit =3D pci_bridge_get_limit(grandparent, PCI_BASE_ADDRESS_ME= M_PREFETCH); + if (gp_limit > gp_base && gp_base >=3D pctx->mmio64_base) { + parent_limit =3D gp_limit; + } + } + new_limit =3D current + required - 1; + if (new_limit > parent_limit) { + error_report("bus [%02x] out of MMIO space (required 0x%" PRIx64 "= )", pci_bus_num(bus), + required); + g_array_free(bars_this_bus, true); + exit(1); + } + if (new_limit > *window_limit) { + pci_update_prefetch_window(bus, window_base, new_limit); + fixed_claim_regions_add(*window_limit + 1, new_limit, parent_bridg= e, -1); + *window_limit =3D new_limit; + } +} + +static void +pci_bus_phase3_program_bars_and_update_bridge(PCIBus *bus, PCIDevice *pare= nt_bridge, + uint64_t window_base, uint64= _t window_limit, + uint64_t start_addr, GArray = *bars) +{ + guint b; + BarEntry *be; + PCIIORegion *r; + uint64_t addr, bar_end, high; + PhysBAR pbars_array[PCI_ROM_SLOT]; + + g_array_sort(bars, compare_bar_size_desc); + addr =3D start_addr; + for (b =3D 0; b < bars->len; b++) { + be =3D &g_array_index(bars, BarEntry, b); + r =3D &be->dev->io_regions[be->bar_idx]; + addr =3D ROUND_UP(addr, r->size); + bar_end =3D addr + r->size - 1; + memset(pbars_array, 0, sizeof(pbars_array)); + pbars_array[be->bar_idx].addr =3D addr; + pbars_array[be->bar_idx].end =3D bar_end; + pbars_array[be->bar_idx].flags =3D IORESOURCE_PREFETCH; + pci_program_prefetch_bars(be->dev, pbars_array); + addr =3D bar_end + 1; + } + high =3D find_highest_assigned_in_bus(bus); + if (high > window_limit) { + pci_update_prefetch_window(bus, window_base, high); + fixed_claim_regions_add(window_limit + 1, high, parent_bridge, -1); + } + g_array_free(bars, true); +} + +/* Allocate and program 64-bit pref BARs for a bus with no fixed-BAR devic= es. */ +static void pci_bus_phase3_allocate_bars(PCIBus *bus, PciProgramCtx *pctx) +{ + uint64_t mmio_end, window_base, window_limit, current, required; + PCIDevice *parent_bridge; + GArray *bars; + + parent_bridge =3D pci_bridge_get_device(bus); + if (!parent_bridge) { + return; /* Root bus has no bridge; skip */ + } + + mmio_end =3D pctx->mmio64_base + pctx->mmio64_size - 1; + if (!pci_bus_phase3_ensure_parent_prefetch_window(bus, pctx, parent_br= idge, mmio_end)) { + return; + } + window_base =3D pci_bridge_get_base(parent_bridge, PCI_BASE_ADDRESS_ME= M_PREFETCH); + window_limit =3D pci_bridge_get_limit(parent_bridge, PCI_BASE_ADDRESS_= MEM_PREFETCH); + current =3D ROUND_UP(find_highest_assigned_in_bus(bus) + 1, 0x1000); + if (current < window_base) { + current =3D window_base; + } + + bars =3D pci_bus_phase3_collect_unassigned_bars(bus, pctx, &required); + if (bars->len =3D=3D 0) { + g_array_free(bars, true); + return; + } + pci_bus_phase3_extend_window_for_bars(bus, pctx, parent_bridge, mmio_e= nd, current, + required, window_base, &wind= ow_limit, bars); + pci_bus_phase3_program_bars_and_update_bridge( + bus, parent_bridge, window_base, window_limit, current, bars); +} + +/* Run once per bus; act only when the bus has no fixed-BAR devices. */ +static void pci_bus_phase3_allocate_no_fixed_bars(PCIBus *bus, void *opaqu= e) +{ + PciProgramCtx *pctx =3D (PciProgramCtx *)opaque; + bool bus_has_fixed =3D false; + + for (int devfn =3D 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d =3D bus->devices[devfn]; + if (d && g_hash_table_contains(pctx->had_fixed, d)) { + bus_has_fixed =3D true; + break; + } + } + + if (bus_has_fixed) { + return; + } + pci_bus_phase3_allocate_bars(bus, pctx); +} + static bool pci_bus_phase2_fill_bar_lists(PCIBus *bus, PciProgramCtx *pctx, GArray *fixed_bars, GArray *rema= ining_bars) { @@ -649,7 +1001,8 @@ void pci_fixed_bar_allocator(PCIBus *root, const PciFi= xedBarMmioParams *mmio) /* Phase 2: pack remaining 64-bit prefetchable BARs and size parent br= idge window */ pci_for_each_bus(bus, pci_bus_phase2_pack_remaining_bars, &pctx); =20 - /* Phase 3: buses with no fixed-BAR devices; final bridge pass: follow= -up */ + /* Phase 3: allocate BARs for buses that have no fixed-BAR devices */ + pci_for_each_bus(bus, pci_bus_phase3_allocate_no_fixed_bars, &pctx); =20 /* Cleanup */ g_hash_table_destroy(pctx.had_fixed); --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265524; cv=pass; d=zohomail.com; s=zohoarc; b=lxQ1GDlS5lPqbGc++UTzDHuplY6l15ggCUC++AohvEHXuHiuC7DohtoqfqjSn+w026D6qlunJzVIBE/eefuaZul9CUUY73BUKz0g60+Py45RDvKs9nutZ19iylhK5RpCKQxkGf7snP20Hr2A9VyUZTipeWL/+xfXsdvhuIQpM+k= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265524; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=cj57KYpH+U+ZkBnHApaa/HFz/IbHpgaR9J4GKr3XX24=; b=IncDYZP0MF9F75xLwdya4r0i/zrJVQ8EWnJA9xfdl+8koKgWHtViFHgfu4YscI1RD/i2nOBlT1pJhayqFIgkfe11HZWfZ0AMj1OC8FhHn1jCBlR97XxmnGVBuVFnG2Gxly/x1DZwqjF41frzUre73WEVNAcSNj6sKf3QPkqxyAU= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17782655244371016.2639570663223; Fri, 8 May 2026 11:38:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5Y-0006jP-In; Fri, 08 May 2026 14:38:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5Q-0006h5-KZ; Fri, 08 May 2026 14:38:08 -0400 Received: from mail-northcentralusazlp170100001.outbound.protection.outlook.com ([2a01:111:f403:c105::1] helo=CH1PR05CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5P-0002b2-4Q; Fri, 08 May 2026 14:38:08 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by DM4PR12MB6205.namprd12.prod.outlook.com (2603:10b6:8:a8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.15; Fri, 8 May 2026 18:37:53 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:53 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=eT0FLiYrrnD8zhY2JlBq7gdL/O7SGz2cEQdyK1GniyjalQrxrOOZtsaBfR19//6eUU3Cw8eHtTcQwrQ+zD6/5nwjXNtRwMnnMUDqJQnW8tub5FSRHIzfaCT63DR6uSv/4vxskd+J58i8D0DT6dg/k8topfu+sIDwny9AYBCFRFOD3LYaV/zwZ/Gt5qCp2LSzXcn8yGZT+29eOn+5srUoGC6g3klj7ABqaZPZQ8IyFtFDW6Prllru8e9ceY4VLey8ZFOdhHtAGNpWQx7kJz6IkmuBUyMr6AYVB5HNhUTbR6RA3+aqBdgSq2Ih6AboQPOPgeL6cfIDShx7lkBIMn4o7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=cj57KYpH+U+ZkBnHApaa/HFz/IbHpgaR9J4GKr3XX24=; b=FOQXXh8F1xVQwOONNfqCvPbge9lCxQZCIoiGoYYESfzBXyqtN6ckMgr7nXf0XvLBWwWHk4YoKU2x0CLzrkwtH+jDDJ8285Yctijbg216Yf3W2c9rjdsonV43ipVsgFBq6ekiHG/DoRnrI0JUukixTMaW+QcsUshY44xXr3G88wLfNPXj/rdD1LpqLDS6osaE7j/dI8+ipDoGmdcJUEmzFWfwh3eEnfOp7WDITC0pG2U9uN6AxPx9+RyPfAnA5t7IxPyzh5KrYKOnIcTd/9J9bvtZ1fuozYGsWkppg5XILf1Ig24+BXEE4r6Y6xmH6F/E3g3BvkQvvpcmDxP5J68FXQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cj57KYpH+U+ZkBnHApaa/HFz/IbHpgaR9J4GKr3XX24=; b=pxEOEInbgSZ+oQ4NwA6FzN1NUNEqfQ9gc2a7FI5qklh4aVSZEEcvGRicQSAfhCCwInKZ04cYHXYyZuZJ3rvqauAhLRabPia5caFc2p9o168H570nwMAEAWg3ZS9zn7oDZ19XUT6dWhhnunxdPSkECy3CHpf69+FIlyMWqiqYL3yTRr3Um1R9lb9/qVG+4EGu41o5jfP64qidPBDrEFUWBZxlaQYQXl5ODoWLLhEtxEhI5x1HvhaNb4uivm95jsYz0g/J5Jf2+qj7wxwpQQKLZmp1hk6d5rGmL4phSZPnIVVaP0rs6V9GyX5zjJqjbIy5m4ZafdJNE7tzIvfObuRX9A== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 6/8] hw/pci: finalize bridge prefetch windows after BAR allocation Date: Fri, 8 May 2026 13:37:15 -0500 Message-Id: <20260508183717.193630-7-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BN9PR03CA0939.namprd03.prod.outlook.com (2603:10b6:408:108::14) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|DM4PR12MB6205:EE_ X-MS-Office365-Filtering-Correlation-Id: 929ce5f3-2add-4657-8224-08dead30ea64 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|1800799024|376014|22082099003|18002099003|56012099003; X-Microsoft-Antispam-Message-Info: h50peUehNe2TI53gNJnMaKv9Gb8kzNXGt30xVoVnLLinerphPhHRRSegMh56AYjdYOY/Kg9y9OeFao+cvcx2GqTeDQPSBkpQTkgDtmjIViuA+8/OzHMmT5kQObL7vk/mTUSaMMLI+PmcH2k31PPGoCGp5zDpCU8t2pz614feTF5oV79hKn5HyUgeSqoU+pHTUsnGSkHzlIh8hQO16aCgg2HaMIhkwtCBnsXQvfUEo9BCfOkYkz7ZClIJxKLaQXsfbcn+ffLtuFWEdC50Rb5ecGTZO0yLgPcoP+0u34Ye3liX2I0/ed7V2FOFSWcrU7fPh2yJZN++htn97fjQ+hmxXsoqiI0gbTI3Zz7u7oZYHl2Paih3CEwXFh/u/jutd46Zl1hZ/GEc/sw0F0Ri8ZhXCF2O5qygL058ZeFm0MAlbmfJbSJZTmhvRCYmgTNri4wJ5XtM0mwUMqHuCRbut5OGH7MBUJmrffG9m1NejN/ldezVKU3zk4qrs2gPxksrrrvg4kkVk/d/azOghxZzbpmFSz2+Ot1A7bm9PizRAA+22ZBIc1c46ZqnhagWK279oaOd5XVxFlQdrKfZEukmfjG1dlGjd6M1x2q8OE/6HOBJmXBQ4Z4LHVFuB92/aYMQyfpdj0CIeBuxkYWFDnpZg1UWHg5femBMAZ6KrUi5oN1KsU5EiqwoYhmc+xqIhrqjxvJd X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014)(22082099003)(18002099003)(56012099003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?xHXZRtrlz4OQ0TfPI23YJrURC4EVzZMqQuErw/qWe0pa5NcwH8NGM44SozCl?= =?us-ascii?Q?q394xXWYiFTrjD8tqU6X7eXOT5xgTuMp1uIygOXwjJPN9aHs/f0VraH7eR+r?= =?us-ascii?Q?bYdueMwYYn/EoCf7kMHKrmpEELvkNFegYU5XTS5TCJf/bqoRu+KchWlvIryl?= =?us-ascii?Q?A4GBsXN+w3OsoxZn74uT6ky06uUTNuEd7LJ1GiFmAaVatwb8rDZweLT/A3ux?= =?us-ascii?Q?LGQj2Ih6kRBVlOORgzOhUsrYHw0BIMX6SdkiXSxZkbigdFG+/keTZrkxnFez?= =?us-ascii?Q?rK/njA3QsoQJd+rj8HJoAoo7TIiVJKOy/RpzCIX9+1obBQlAexR3syOaVu0N?= =?us-ascii?Q?k+j9l4n0Hf1+E9QeS6f3OOgcGDwGm73kI3X3LNXWua9nWO6YNiv3wCBUysD1?= =?us-ascii?Q?pUlIl2AhHL4835mjesUmRIIAcRC+gMpwIUWzdmTxOmghXwqSa3TbNQ9e4lhW?= =?us-ascii?Q?SzSIEcrzqFfSsbZSVAtEbcEsPSJP4qE5O9GDMa1UJUekaXvgTE1oF/38cpFC?= =?us-ascii?Q?hGT5MhLMyJJ8YUa9xCLGmhWrOwuD/RF6U+NAsXpUMAxHo/sHbjUku21ZNAx0?= =?us-ascii?Q?cFxEH6fCAzT3RYlOLWs9EXM7gxxFNjinC9/ziLjuzS6EqOhK7sFlZIh+8bEm?= =?us-ascii?Q?Xw6pNCpXr/z5NCY1H3jc+tY1ad8WeNV6wKheRnWFRaY92MLDqww+FM6Dg/8z?= =?us-ascii?Q?z0unudIZ6u1UAIAjvkjD680qqqL2jDHJG7Px1OlQXGkYI3mM8k/VztAq47Sk?= =?us-ascii?Q?QVZU/uSJjBMtjkynTmDD0eWKN8bhyO38eG6UvD4y5sE8WY4S1mGJalduCmLg?= =?us-ascii?Q?KiUTJjn63QxjxD3FKLIovoAzZuh63illGaNmMq0QIqq3Ci340TrNvkfMtUJ4?= =?us-ascii?Q?0m+TaVIYjjaRlzgvEddjCna0EFdiWG9qsXFODhM+LfNcarQJejrTimq2WwiP?= =?us-ascii?Q?RH3tpKVFea4FbYfCaS2ROddFApYRrp5M4BwC4oI3a4kZyRilY2qpDFE0b/Qu?= =?us-ascii?Q?WsUJ0+dH9+//Ep1zgKbTBK3ZKKev9yphtzMV0WUrhefK/imzU+PfcIH+dOa6?= =?us-ascii?Q?q+c7M+rPww8Jj1iYuqO72OxwQJCHT4YgaF7ZLCk4B1v3IW83WYR+4BY5B83C?= =?us-ascii?Q?o2+Z7aUg/TTnN/+Hur8z+AmjzoIrvihi+ctvEgWOiajwNCMhUObmtSGYh2Oz?= =?us-ascii?Q?mMgeLapNzmOZ3rbfmvmAYOdB2dYlF8MAeMw3xDnOjzDX5687JQeQwOYt/NOa?= =?us-ascii?Q?MQTqjunDDyzfVsUKSoyRnjvlwmGWmmoahRDEVEVSO2d0sbEN8GgyT1MkQ95D?= =?us-ascii?Q?PcLkrSobQB1o33h2wMaCpF2l3rsGXNp0WRPR+blAMKmYoKO6n5SwNHVLR3TQ?= =?us-ascii?Q?Oz953Bpp5WydCBcoSclc0B3K9j0s+6cgrqn4j1Lgv84krdagZ3TMC28J56N6?= =?us-ascii?Q?uB49MigSt4RDSPzlpuiLQyEnLxnCVcqSBYaxC8HJQCZgybkUhWdcFUh+X4M0?= =?us-ascii?Q?J9m8eW6EoMPiLesyQRxxrF1I6ugJLoYtdtrw+8BSjmwtyBGx1lscKCYQ/8mI?= =?us-ascii?Q?/Fz3EGM30LRYxIEgT/reKo3je28Ae2JeHVo+4FBaT8Rw1rvU2EwDsxyVDX48?= =?us-ascii?Q?J20XJjYkvO0o5bSUMLTfQRs4QZRqjk2YGv76E1KRuVFxci3RLkqbLIBJdT/X?= =?us-ascii?Q?/xdG3CtGxBvYudKf4UfE1BjQtyIducVpkdImoP35oamPWChH75KwyIFv61d1?= =?us-ascii?Q?Yx96MY3+YA=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 929ce5f3-2add-4657-8224-08dead30ea64 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:53.7701 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: qNznszFYscpEfsMg7ZUlRvbzYEJvYkhdvTvvEifwQTvU0KbwX9Em9W+admZWEsJQcienTFTQKfnDkHcVMYMq3w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6205 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c105::1; envelope-from=tdave@nvidia.com; helo=CH1PR05CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265526911154100 Content-Type: text/plain; charset="utf-8" Add a final reconciliation pass to update bridge prefetch windows after all BARs have been assigned across all phases. This ensures bridge windows accurately reflect final BAR placement across all buses. SR-IOV virtual functions are not included when sizing bridge prefetch apertures and may require additional work. Signed-off-by: Tushar Dave --- hw/pci/pci-resource.c | 89 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/hw/pci/pci-resource.c b/hw/pci/pci-resource.c index e2d2adc7de..01db59c4af 100644 --- a/hw/pci/pci-resource.c +++ b/hw/pci/pci-resource.c @@ -190,6 +190,76 @@ static void pci_update_prefetch_window(PCIBus *bus, ui= nt64_t base, uint64_t limi 4); } =20 +static void pci_get_bridge_window(PCIBus *bus, void *opaque) +{ + PCIDevice *bridge =3D pci_bridge_get_device(bus); + PciAllocCfg *pci_res =3D (PciAllocCfg *)opaque; + + if (!bridge) { + pci_res->wbase =3D pci_res->mmio32_base; + pci_res->wlimit =3D pci_res->mmio32_base + pci_res->mmio32_size - = 1; + pci_res->wbase64 =3D pci_res->mmio64_base; + pci_res->wlimit64 =3D pci_res->mmio64_base + pci_res->mmio64_size = - 1; + } else { + pci_res->wbase =3D pci_bridge_get_base(bridge, PCI_BASE_ADDRESS_ME= M_TYPE_32); + pci_res->wlimit =3D pci_bridge_get_limit(bridge, PCI_BASE_ADDRESS_= MEM_TYPE_32); + pci_res->wbase64 =3D pci_bridge_get_base(bridge, PCI_BASE_ADDRESS_= MEM_PREFETCH); + pci_res->wlimit64 =3D pci_bridge_get_limit(bridge, PCI_BASE_ADDRES= S_MEM_PREFETCH); + } +} + +static void pci_collect_mmio64_window(PCIBus *bus, PCIDevice *dev, void *o= paque) +{ + PciAllocCfg *pci_res =3D (PciAllocCfg *)opaque; + uint64_t rbase, rlimit; + uint32_t idx; + + for (idx =3D 0; idx < PCI_ROM_SLOT; idx++) { + PCIIORegion *res =3D &dev->io_regions[idx]; + + if (!res->size) { + continue; + } + rbase =3D res->addr; + rlimit =3D res->addr + res->size - 1; + /* Entire BAR must lie in the window; do not count partial overlap= . */ + if (rbase < pci_res->wbase64 || rlimit > pci_res->wlimit64) { + continue; + } + pci_res->rbase =3D MIN(pci_res->rbase, rbase); + pci_res->rlimit =3D MAX(pci_res->rlimit, rlimit); + } + + if (IS_PCI_BRIDGE(dev)) { + rbase =3D pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); + rlimit =3D pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH= ); + + if ((rbase < pci_res->wbase64) || + (rbase > pci_res->wlimit64) || + (rlimit < pci_res->wbase64) || + (rlimit > pci_res->wlimit64)) { + return; + } + + pci_res->rbase =3D MIN(pci_res->rbase, rbase); + pci_res->rlimit =3D MAX(pci_res->rlimit, rlimit); + } +} + +static void pci_bus_update_prefetch_window(PCIBus *bus, void *opaque) +{ + PciAllocCfg *pci_res =3D (PciAllocCfg *)opaque; + pci_res->rbase =3D ~0; + pci_res->rlimit =3D 0; + + assert(pci_bridge_get_device(bus)); + pci_for_each_device_under_bus(bus, pci_collect_mmio64_window, pci_res); + + if (pci_res->rlimit > pci_res->rbase) { + pci_update_prefetch_window(bus, pci_res->rbase, pci_res->rlimit); + } +} + static inline bool is_64bit_pref_bar(PCIIORegion *r) { if (!r->size) { @@ -1004,6 +1074,25 @@ void pci_fixed_bar_allocator(PCIBus *root, const Pci= FixedBarMmioParams *mmio) /* Phase 3: allocate BARs for buses that have no fixed-BAR devices */ pci_for_each_bus(bus, pci_bus_phase3_allocate_no_fixed_bars, &pctx); =20 + memset(pci_res, 0, sizeof(PciAllocCfg)); + pci_resource_init_from_mmio(pci_res, mmio); + + /* TODO: 32-bit MMIO/ROM adjustment */ + /* TODO: PIO assignment */ + /* TODO: 64-bit non-prefetchable */ + + /* Align bridge prefetch window with assigned BAR ranges */ + pci_get_bridge_window(bus, pci_res); + + QLIST_FOREACH(bus, &bus->child, sibling) { + pci_res->bus =3D bus; + /* Use the full mmio64 window */ + pci_res->wbase64 =3D pci_res->mmio64_base; + pci_res->wlimit64 =3D pci_res->mmio64_base + pci_res->mmio64_size = - 1; + + pci_for_each_bus(bus, pci_bus_update_prefetch_window, pci_res); + } + /* Cleanup */ g_hash_table_destroy(pctx.had_fixed); fixed_claim_regions_reset(); --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265575; cv=pass; d=zohomail.com; s=zohoarc; b=UXCLsvTtc/WIY45oR6HWzQrEsDaZHpwsl0PCPOH5MjmnDREsbDOxgCFKTho+tL9/THnXQdPkfpuTPmV6CPtvEuuvUt5T0mhcWl036p9HyNVpWp6G9vKX41KnNx30iGdWcc4l8pn6qRsr9GiUxGHG0UaJqRmTrJ2mIm8QIYEM8O0= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265575; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s1a9TJhPNEvWPxcpxTaxPFxtgFtp645kI9A9RF51YJg=; b=eV+sgpzWLahhnPsUs94rAMQS61WDYEDfL2pgqNjLHlNp1ILEemWVZyA0Aa0mXjs5eGarTV3a6T//s8VQ6Ij05NoxVX3n8169C5/mIl5y9hh4InVv41piLppNNXqIedxSez1N42ZFLy4DABpc2eJkVCHIO9QyIvtDizDtpT17OAk= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1778265575423775.6223228770499; Fri, 8 May 2026 11:39:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5g-0006lw-Bd; Fri, 08 May 2026 14:38:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5T-0006ho-9R; Fri, 08 May 2026 14:38:16 -0400 Received: from mail-northcentralusazlp170100001.outbound.protection.outlook.com ([2a01:111:f403:c105::1] helo=CH1PR05CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5R-0002b2-AT; Fri, 08 May 2026 14:38:10 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by DM4PR12MB6205.namprd12.prod.outlook.com (2603:10b6:8:a8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.15; Fri, 8 May 2026 18:37:56 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:56 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=rI97G3liEXjcNSlX6jLZjuPcqx7mZRKXA5bNCd7/8uABHQ0DbzgREhOKq4EbwS+xiRet1QO2JOR+7utpAx5A3YpSbDrZUZxbR27tKNHD0+IOnb97ULxzqdvvOx70EmpqkPcNCBCh9O1AFc4/BOPP+ofCLXHhLT3X+PYP75SIwihuFqjNICwB7sOb02BCJu6r+qOEB1/5w4DRsI/Qh5p+cFOjJVNEpD4OoyT655CT5x72mCzoJMkI/vPn5JLSuwjRpI+f6RAcOK4sj/LT+0QvY8VFkEXTKBNnFPUEfPnIq0ZoR4kMfJlf8d/QDAZha2O93JbLxZspbwkAMdrjTAnIVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=s1a9TJhPNEvWPxcpxTaxPFxtgFtp645kI9A9RF51YJg=; b=pSrSpDZcWcKBnN6jQQAxQtLqc8ZCJSNYn3hwUNamZDr2LKhszqEhPIiWIKSgJord0YIa18k/FvcxtGOhlYjU0neVGmiuCEBwJr2aPmK6SIhjbWVAuaWRR+7odzVLLIqvOqrAMvFjpkbA0ySngkYJZTADgzlbb+SKor6ZD6ITATh+N6c4SoQ7w4lhW4TSoQa50owBPOQl5RsEy0fIgXBy+eDFJR6kSBbzwSdrwzgTm1ff+dWWoT6A77DaTi9mb2z6Qw9wXOTfr0oRf6BDXcNVG2dHXcIUzWRNsVH+vj+IYhEXNm8w3L5MztX/A0MZBBNIe5GdQRPEBPtQgchqhjy7Ow== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=s1a9TJhPNEvWPxcpxTaxPFxtgFtp645kI9A9RF51YJg=; b=feqEb2E1s/rOB9OFvD3kmtK7n1z1WDpHDf9Ds6lwv/egWfjoW4nJmaEPowXF2fN80bYjz9JGgouM+0a/OwJbti4AP4SVhzmv0ChA2wS+2qJeqi4wXMhqp3wFq4ghdLgWAi8IsoBw9bWrHYHOKL3FJhdkK4j948OtHJUldzbLqVT5Veh96+wrY4t0ToSYyETH0C4juRdmXZgfdJlRwTKdRa11vE3KD7uUdagVbnktIueo5naWajQfuCO5ZxcrFX/vDxpi9ZoGiGGwO4+5EtVmoILxud6MSff8vLiKRlC0uGglfmO/s0x2MOZll6VRtAfVl0+ho0I+KTv43QWoklqQpQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 7/8] hw/arm/virt: add pcie-mmio-window machine property Date: Fri, 8 May 2026 13:37:16 -0500 Message-Id: <20260508183717.193630-8-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0PR04CA0024.namprd04.prod.outlook.com (2603:10b6:208:52d::14) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|DM4PR12MB6205:EE_ X-MS-Office365-Filtering-Correlation-Id: 7de8b9c6-6042-4703-44ea-08dead30ebda X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|1800799024|376014|22082099003|18002099003|56012099003|3023799003; X-Microsoft-Antispam-Message-Info: GxoKxB7fpRQqfXpWR3JGb/CDaKGusN4OgSPu+OVi+CbatVBG+AXw2jpOCJxJcbBvx46sYMs15iEPmvCYY1BIVUa25sjUh8Mva/v82v5DnxH9g5CiqSCagCPZDyID9+qQ6C76mSdvcte0KUjUtLAtws+dN0+etbTcsQThftlDdONoezz+AvwbjCvAT7iT9yw3mRuXAkkjpugl///3T5OxdFMyYr5styaSacDpfOd54H4teBzXiPeVjraaNnn+NT/cyyASekevbYJxC/fyh6V8s2DjlBbExcLmWkaxnNLZgYgzTSZ6z4rdIkuPgFM00ysRLdI3RvsyGPRQIEC9bTs5NuXgoglLfA7iP+4g9TileyrKhFIwZkxaU0Px7k26KJFxF6+kir7CQJfEgF2oUCqzupej58kelZ9a439S3nGmBKdq1beLq4J2k5n3240TWzXC08uG2uVhcTJzPgwViLN9OgdRe6RwQSErhX57ZtZZ73l/PPR39VBPH2IAfbKCg05bVHdFdk5tipUZ1oSne+1NPFZZDD+ENBkJwureDRI6fXnoYII4usi5ZPzGplXw1O4C4SZOzKn8pzOuCPd0Iuj1TJzlim5oLBQksHpIikqNe6pUX+HXIf7bksjpoj81dkggL76GBysWg1PgwBiqCRFsNGJB1ACBNKYC6QJA1od6MdblznM0XlIF+gVCK0ABBkIV X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014)(22082099003)(18002099003)(56012099003)(3023799003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?UnKVJdV7U8spuyhlSHLHMSp70pdOzOg9HYAAcjDU347pP4D0fDbYpnfDTjv6?= =?us-ascii?Q?j2X/+5OX+vmsA7xPIrweIZWBFjwLZuYh+aOZ9E5+zsRL/+/d1N24/Djfv8eG?= =?us-ascii?Q?mhez3jWG7fATlhR8VQnGXxCF10tFNUJ+1PexYWqpQ/O5BMAje7wmi9YFU1XD?= =?us-ascii?Q?zPKgikGVXyYJlaSYbjCvmAuLbNZxRVaP7kR2/4pKYW4m3HNZOvy7Lq57tqBH?= =?us-ascii?Q?E+/wkD/eXtZFtWf3+aVyMAoQX5SBHf1KvYJhNNi5U4XeVaGi3hqsWAmgmykz?= =?us-ascii?Q?XLhM8r7ePQzBNq/9RszwkfnXpwo/KpWfBfEZ8wPyx6K+UivK3TO2n3iObwsE?= =?us-ascii?Q?92Fqpmp7JppflEd8tvKcJFb+zjf3fJdZ2hiLV9ri0i0o7gX7gJDtMg+cYODz?= =?us-ascii?Q?A8X3mpk4vWRf7kBoEOSnbMLm//txo0d+/1OAwkSp/o/TWEPl/EAqAZipNCxO?= =?us-ascii?Q?DXQS94UmikhpbFSYPu4a/ZnsYJssYgGeJDHwTLoaECQbrMbpuZM6QRqOLhRE?= =?us-ascii?Q?mfqtrAn+AnQAubqsFpWnvnLawozBxUYcsxlUiCY9ZowEOt6ch/HMT12ca4WN?= =?us-ascii?Q?yK5xoXI3YIB13GkrN8RU43dtjX/8W09nlHgxPjLkm/kFb7ZARmSKwcHXY+i/?= =?us-ascii?Q?KXZFXHbD2lMVbmdQyO5yVkISy05LSCRjJiytJX+grzIH/RbQTRxhm08CZ3qw?= =?us-ascii?Q?QC+BpxQH42sE6e4V0PcK0ekj26iR8qR1GoSKRr0ChH7CeJmjmIo4aoG0NxpS?= =?us-ascii?Q?Og7GXW00zVQm44AuZoBvHSFhq8rU5VonQ85CP5QewQPIrSg1uFQTyWTzvsh5?= =?us-ascii?Q?llxUW/ynzSH6tZmaKvoX9krQNYY6g62tE3mPAav8S+rY580BqDl5KOnZE4sY?= =?us-ascii?Q?L7qrQ1q5SgRdPgXZwzIyO3MTJrlARQh1ADtVV0I1zAFlP0jDMDxSe4lZMZsp?= =?us-ascii?Q?a80nvuLKUIjHKvv41Hu6aGuQeITXmzSevQLu1KGCj9xs3d+yzXVp7yHRz/KI?= =?us-ascii?Q?IkUwonfnmoZwZ8F6phbwJBYefptqE/B/UzUSb4iESNgdbWySnyc1yPFIHaSG?= =?us-ascii?Q?mGiKao+7FQx+TphilSL/GUjTlBNAmgdd8ArpWKPHXenfr8LBjP9kkbsrwOXD?= =?us-ascii?Q?SKZoTZGXID7EB7xlDT+w534le89fpxXblp6L5aZLZuv0onoCUTRSc5Nn2A3T?= =?us-ascii?Q?LOSFFu8KZL11GEZc/WH/+vWnZSNf1yi3YquP7SATRGC4JMnEBs2H/X0vKJC3?= =?us-ascii?Q?RmuGCKX4lIufvQbjeJrsG0My3zPI/UWXbMRIHv1cX5MU7+H4FlUCMNkvZxNg?= =?us-ascii?Q?+dr3ORSshavOKwq/+6zzi8jkLG9IDa1b99dcsa3hti2neUa/Zh3kVKI8CX2X?= =?us-ascii?Q?aNlBPecUA9Zf9o+qjNZR/b8Q9HvLC+/M4qyBqcQVbM/w6Zxwe0Rb4uDEay2n?= =?us-ascii?Q?OH2Wd1eaObRLYwO0JViRc1mYnjAoiKKbT6adkdx6YwSYugJAuJ5yUpf8xRlN?= =?us-ascii?Q?ayiOUVzhiC/TH4/osZaUCegTLYSxrhdPvC/swWPqbuQ8UoJRIyUqqMlXDhPw?= =?us-ascii?Q?TQblLmejd3bBggF0znjnNeaJwDDmL1/nO6mbVajcE6unSHmP0jDJcBlrX52T?= =?us-ascii?Q?8p/srvbhb2rt3+hIu28WbWNH6YW1IVYr+m8TxTZzjQCb36bfmf8YyrvHQU+X?= =?us-ascii?Q?oV6TEPYdv0xJIZyu65xYlgVI6gwebVpBNgzYR/QgqRFCeiIzH24XebUl8T7Y?= =?us-ascii?Q?bNj9QDsO0A=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7de8b9c6-6042-4703-44ea-08dead30ebda X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:56.1197 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: g8FcgVU0Zmzzj940pP7QltM/ZojV6KikAbnsHR9YcyTPZBHQlPEB9G4zBVjEHGhDTloya6dZD6yOFESvyDfC+g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6205 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c105::1; envelope-from=tdave@nvidia.com; helo=CH1PR05CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265576303158500 Content-Type: text/plain; charset="utf-8" Introduce a machine property to explicitly set the high PCIe MMIO window as BASE:SIZE, and apply it in the high memory map. Usage: -machine pcie-mmio-window=3D0x400000000000:0x400000000000 When using the fixed-bars property to assign guest physical addresses to PCI BARs, those addresses must fall within the machine's MMIO64 window. The default aperture may be too small or not cover the required range. This property allows the aperture to be resized or repositioned so that all fixed BAR addresses are accessible to the guest. Signed-off-by: Tushar Dave --- hw/arm/virt.c | 87 ++++++++++++++++++++++++++++++++++++++++++- include/hw/arm/virt.h | 2 + 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ec0d8475ca..55f41c7e46 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1915,8 +1915,31 @@ static void virt_set_high_memmap(VirtMachineState *v= ms, =20 for (i =3D VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { region_enabled =3D virt_get_high_memmap_enabled(vms, i); - region_base =3D ROUND_UP(base, extended_memmap[i].size); - region_size =3D extended_memmap[i].size; + + if (i =3D=3D VIRT_HIGH_PCIE_MMIO && vms->override_pcie_mmio_size) { + region_base =3D vms->override_pcie_mmio_base; + region_size =3D vms->override_pcie_mmio_size; + + /* Check for overlap with prior high regions */ + if (region_base < base) { + error_report("pcie-mmio-window base 0x%" PRIx64 " overlaps= " + "high memory layout (must be >=3D 0x%" PRIx64 = ")", + (uint64_t)region_base, (uint64_t)base); + exit(1); + } + /* Must not exceed the PA space */ + if (region_base + region_size > BIT_ULL(pa_bits)) { + error_report("pcie-mmio-window [0x%" PRIx64 ", 0x%" PRIx64= ") " + "exceeds %d-bit PA space", + (uint64_t)region_base, + (uint64_t)(region_base + region_size), + pa_bits); + exit(1); + } + } else { + region_base =3D ROUND_UP(base, extended_memmap[i].size); + region_size =3D extended_memmap[i].size; + } =20 vms->memmap[i].base =3D region_base; vms->memmap[i].size =3D region_size; @@ -3004,6 +3027,60 @@ static void virt_set_gic_version(Object *obj, const = char *value, Error **errp) } } =20 +static char *virt_get_pcie_mmio_window(Object *obj, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + + if (!vms->override_pcie_mmio_size) { + return g_strdup(""); + } + return g_strdup_printf("0x%" PRIx64 ":0x%" PRIx64, + (uint64_t)vms->override_pcie_mmio_base, + (uint64_t)vms->override_pcie_mmio_size); +} + +static void virt_set_pcie_mmio_window(Object *obj, const char *value, Erro= r **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + uint64_t base =3D 0, size =3D 0; + const char *endptr; + int ret; + + if (!value || !*value) { + return; + } + + ret =3D qemu_strtou64(value, &endptr, 0, &base); + if (ret || base =3D=3D 0) { + error_setg(errp, "pcie-mmio-window base must be a positive number"= ); + return; + } + if (*endptr !=3D ':' || !*(endptr + 1)) { + error_setg(errp, "pcie-mmio-window expects BASE:SIZE"); + return; + } + + ret =3D qemu_strtou64(endptr + 1, NULL, 0, &size); + if (ret || size =3D=3D 0) { + error_setg(errp, "pcie-mmio-window size must be a positive number"= ); + return; + } + + if (!is_power_of_2(size)) { + error_setg(errp, "pcie-mmio-window size 0x%" PRIx64 " must be a po= wer of 2", + (uint64_t)size); + return; + } + if (base % size !=3D 0) { + error_setg(errp, "pcie-mmio-window base 0x%" PRIx64 " must be alig= ned to size 0x%" PRIx64, + (uint64_t)base, (uint64_t)size); + return; + } + + vms->override_pcie_mmio_base =3D base; + vms->override_pcie_mmio_size =3D size; +} + static char *virt_get_iommu(Object *obj, Error **errp) { VirtMachineState *vms =3D VIRT_MACHINE(obj); @@ -3582,6 +3659,12 @@ static void virt_machine_class_init(ObjectClass *oc,= const void *data) "Set the IOMMU type. " "Valid values are none and smmuv= 3"); =20 + object_class_property_add_str(oc, "pcie-mmio-window", + virt_get_pcie_mmio_window, + virt_set_pcie_mmio_window); + object_class_property_set_description(oc, "pcie-mmio-window", + "Override the high PCIe MMIO win= dow as BASE:SIZE"); + object_class_property_add_bool(oc, "default-bus-bypass-iommu", virt_get_default_bus_bypass_iommu, virt_set_default_bus_bypass_iommu); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 5fcbd1c76f..410df857c7 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -187,6 +187,8 @@ struct VirtMachineState { MemoryRegion *sysmem; MemoryRegion *secure_sysmem; bool pci_preserve_config; + hwaddr override_pcie_mmio_base; + hwaddr override_pcie_mmio_size; }; =20 #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) --=20 2.34.1 From nobody Sun May 24 21:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass(p=reject dis=none) header.from=nvidia.com ARC-Seal: i=2; a=rsa-sha256; t=1778265561; cv=pass; d=zohomail.com; s=zohoarc; b=EgLIrP7mK+NLZq9icTJ4Ls5DvSTdIdxiiKtyzT2CgrmGLtiCJbaIqumuoebbIgt0Yz2QJUI+mB1tzmImanO1flMaPA2oqMtcSmmYWTd++HvkE60h8vCMyKW92JEEZThDR2GDVnJpu0hz/cAuYtXro28eTQ0qDvzy4Dr9cTb1F84= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1778265561; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3BmZzqD5g0RjTtepjL+pk+Y22ANUW4q9Gg58vJr4ggA=; b=SDa3TcahQEnd8y2PdY57EFFAhSI3COMFylzEPmE4mwM37wARVoVz51tYi0SSfGBptz6K3XFKyLoxJ+G/RxGWjdf8gTbzMSxbuJH8tGspVc+ZgIbKaMYMk8AegVI+xojf5iYy1Ymgf3wthUVRWJkbrQSAKbqnRm1CT1kZ6wrY1Vc= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=nvidia.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 177826556185261.89874048496404; Fri, 8 May 2026 11:39:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wLQ5e-0006lZ-9g; Fri, 08 May 2026 14:38:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5Y-0006jj-Nt; Fri, 08 May 2026 14:38:16 -0400 Received: from mail-northcentralusazlp170100001.outbound.protection.outlook.com ([2a01:111:f403:c105::1] helo=CH1PR05CU001.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wLQ5T-0002b2-Kj; Fri, 08 May 2026 14:38:14 -0400 Received: from BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) by DM4PR12MB6205.namprd12.prod.outlook.com (2603:10b6:8:a8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.15; Fri, 8 May 2026 18:37:59 +0000 Received: from BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325]) by BY5PR12MB4179.namprd12.prod.outlook.com ([fe80::2036:e8b:9b3:f325%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 18:37:58 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=eqZq4FdQOzqMOFoVmld+5x5yfQmATNoFIcvPuIxQDb0RXN6mL1oZnnuc5YSZ829B6CxqzQ14xVCPMmk4Eu5lZTQfXhsZ4uduVQwrnzACZIxCsEt+uKBz+nXZjkKYOI2TBHXGYgfDPVa6wBSlIXaMdSmX+XQOEpX7v0wiQ1f4hGBWvMzBij6lWqPyAjDFVLb8YSTO2i6c4Ie9/0uwOxRB0sxMeey5G/E5v5Bunqyd+41CyVGsUnRgMYR/8vhgahRqW/60w+QUCHAKQEPjFDSanK02l2h+mS+i/a8zSvmu1oXYRve3BXipYDoGVW+WNuNbUTAzncSka43FpbgJgpAbjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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; bh=3BmZzqD5g0RjTtepjL+pk+Y22ANUW4q9Gg58vJr4ggA=; b=qF8FC3Y6navVIjEIw4rtZwYWnV1znESVZtk9hjzlreE9IBW1LT3QuhWw9SYoMarxXa+Frm8jUOUNkc0GEETKuPVa6GViBMeqpLzK7kAifrieFV7E6qba8sFnKMZ6YIS8hV9d22lRRMKaHSBYjUXhaKsNN1R1xiTiFvVbFYbo4coAdUyFomDz5CHzJfwopZLDgGdPXRxPjHRRKlmRinHvDCyu9wyw9vcq5t9LYXvh0ifruq6/UscZU0jEfKzVui1g+cncdBRRAxgNvYvjrNSSkRV8swNgL5y0a6XNUHMRE+XZQiy0WNvzpcwRC/9GI4gxCxGnyeZV1sS4lzoLepKUOQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=3BmZzqD5g0RjTtepjL+pk+Y22ANUW4q9Gg58vJr4ggA=; b=mQtH6eN9/dvf3QPdvkbqREk9lxTSD1Cv6Jk8HssoyOkiNNV7Cvxq3n+BFCz91lmEVkoSiKayLRlUQY0VDexDaDicFybNFxF5XsM83Gkvn8y0IqW8WFHfEU0dMHYOnF1NBwI23BIeNK6jyGDwBvrirGZngOQeIHmlTwESVPeejC39sVnWJr1PQNLv9Hvuy2ioWTerrKN/EeQjmLIc5tVm1rKvZIiRBe+weAbzo74y41gyX0ypgrhXkjv3pLEp921I3YFRot1BLDggjyeGs6xNIuw1H+eGx7OZBYiQ2G3cLIgu80LzKhBRabeT4TN+MgwTwrdtC0wuaj2hDeDvwDJgzA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; From: Tushar Dave To: qemu-devel@nongnu.org Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com, qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com, marcel.apfelbaum@gmail.com, devel@edk2.groups.io Subject: [RFC PATCH 8/8] hw/arm/virt: add pci-pre-enum machine property Date: Fri, 8 May 2026 13:37:17 -0500 Message-Id: <20260508183717.193630-9-tdave@nvidia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com> References: <20260508183717.193630-1-tdave@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN0PR04CA0024.namprd04.prod.outlook.com (2603:10b6:208:52d::14) To BY5PR12MB4179.namprd12.prod.outlook.com (2603:10b6:a03:211::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY5PR12MB4179:EE_|DM4PR12MB6205:EE_ X-MS-Office365-Filtering-Correlation-Id: 10276576-64e8-4e5f-0acc-08dead30ed16 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|1800799024|376014|22082099003|18002099003|56012099003|3023799003; X-Microsoft-Antispam-Message-Info: 1mbtS108Ad2Im9h41cs0MDVzTO84ku6mE+4M6jA03+Mzsl6vlSx5kDHb4QRMltoKeMCLDQcsf7pjtL/YUfSgcJ+x7hK9dcJSf6zmvQXsAq8nqUmeQ9nQPAEA1KFtG4wwKOPUwwz7P//biab/4qPGowJHmoc/19Oc06AqyyH5udUZiUvBs9G4/XVplddY8YxWPYrc3PnUUi9rtpvCtvDX+pSyDkD59g0T8ZdYV33LSk1/gmITQj2Z9bhLku1ww4qCbdmAEsAiLO7KZBKYfp1XhPZ+jnwUstB17yOJ21VCBGsZ7xlN31GtMIS9zlSQVvpTeywCYiq9HL/PfiHskl22/Sy0FfxVPYOA8RtdMV+6YuR45x37ldUzMUpKcjlXymTVyIl7YlO6aI93As9XtM9Miq1sKk4fay5ZkvCbLF018g6aKTAk9n3diYAsLkXQKqgxDipMcKE+C9o5WraIKr3jeVo8E6pzzJpOqZ5O/7FpnrNmvIAqYlpMTa8m6jweS+WjI19Q0vEpblOOk6N0OxUa5/PalxdJ17jdUp5jbXa3SBvx5GO4ieei6bRge71RjrIwowzYV+li0P66IFwFhKWdrq5ea2peWB1nY75hRpoQfmMnjGr55MTmT2ZN/WxJNiWb0iWpPopfcZjF8v90pgkip3T9LO4XAp97NjhiclS18+xq2M7A2QzydKXRVfOmmiZI X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR12MB4179.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014)(22082099003)(18002099003)(56012099003)(3023799003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?wUdyKEgwyAvbMyuX2X1tp+MnZi0ajBKONOrzBRgrRSBgOSmWdn0LBaYHwYsx?= =?us-ascii?Q?9MGteLvsqk0iOAf5skDadkfDtEXWF55FPKT3CtDsW5QRQaqZdUpT581ox+Zw?= =?us-ascii?Q?xgLGdYK79rdafv/sLdnZUclV0GoHdfSGvdR1rMoEJpAtJ1C4qUPa52mqqvV1?= =?us-ascii?Q?jofMQxUoQa0+JGdq24y5CPOSDk+RaY4EDXwt6Ipq482p5zgvELckA2dzou6N?= =?us-ascii?Q?QAPLH73KzrUCh3mNdUYh3dRVps9O0fPRZcjLQ4Jr597jefzRg++iMVqvHXwM?= =?us-ascii?Q?BAlvyLLY1l/JxqlGfn33qPpkcgr9bMcs0c3KAjArMjOtNDpAsU6+b/tdm2cM?= =?us-ascii?Q?TXXGNsIUyYC8TMSYIa3WHJYjoKBG4FFNNWjnxcFU3GuNxVYycLjeExSbARAT?= =?us-ascii?Q?BYAF089Z7k40sKk4E3Le4z7QjVYFYXjyuOhdslbXr85K7qLBy+ftbTS2BIGK?= =?us-ascii?Q?9bq1vn5T8qQHA3zyaPbKSiGEHEwah/y/GYHaE+KXpYZYesrrvlbCUBPHP6i5?= =?us-ascii?Q?jimzLrlisVqnwysXR/PZOr+E/R+wvN4Kt4cAYn6+I247pK1I2717krXv4oQG?= =?us-ascii?Q?YCNfG4ttdoFMRXdMNwsDPPVyaMlWkwDfGUpUAmXhOjPoHWCscreQ48FmOSEU?= =?us-ascii?Q?rNGKMTc1zwQalvUF41FVp+tSIGPwn7MYuATVS3uG7xNZTtlYorzyeV6dC5oa?= =?us-ascii?Q?xTLJDyshBqzNZekkQ/5oPSB5SIPLDOTzC+38mKKLh/x/iVZHvyLslrfqSt3U?= =?us-ascii?Q?JuMJxeW4veQxxAhxzcKGiUza3WrGcmtD6SPsqPpitM71oLsB5BU4mwgkhCyY?= =?us-ascii?Q?o1ERBhv87i/b1+YhNfjQ5WwFVER46pc2008Dbv+UfpAWWD2+zqc0FmzckMK+?= =?us-ascii?Q?MnFjeUTNj0icSVM2ijZtrKYaH7zTNy+1MPCdkcchNs0BPSMslR1oUmtmfsUc?= =?us-ascii?Q?nkr0lxNlFDARoflnHASyhq/3hioqMwwtn4amOlMuiuQmvZ8BSXsxbjYc386f?= =?us-ascii?Q?Mk+l4YuaOr8u/ixvgphDKvpiloLl2nfFBvLsfxD4bzB8tigkpxOYslUNvTj+?= =?us-ascii?Q?sCWwCFME1nAnnr3FxNOGLyqV6XTATHpkQwK85bIFB4mpec0xdadhcEl3iySK?= =?us-ascii?Q?8IETGbOlOce8Ph5IqYTjGGaVdoap3JTuQnWVmNLZ3Yr1HZxlmytrB98Gjo+w?= =?us-ascii?Q?r7Va3x33mE2Sr+j7kqVOWVP0FkimzHIWLehVWfG4sqvAuNFWiyzHElOWaeOI?= =?us-ascii?Q?/53TtFsO4zKTMrUDx2VVQULJhkwzOK9jtCQiq1bGuznMc7m8sUoGTvAIJz0O?= =?us-ascii?Q?H2th12m9JhL8bXAQnJgebhNspWAVX5fmZc1hzlu/5E9sUU7LqObmSOXWO7+9?= =?us-ascii?Q?6z3UZ5wb4MxY7m3HdSh+WVQ193oYpviQ/JaYzeB5jLnK0uNUR0ULYXdiYtG3?= =?us-ascii?Q?sf0thVwSAVkEnqqbF2RQRZx+mxYS+2me+nc+Hze90uQvrndHkdwKqZ2IAOms?= =?us-ascii?Q?nNEQCoZOtGo4stX6ZAlAxCSfXa46rsWHnoazATDyH4kejo/LGn49/fPsSqwA?= =?us-ascii?Q?wODxJQSMDzUd1YHKjz4SK1Bew6RdKYjOjuxrimJUIbETxpicWIR1t8uZalFk?= =?us-ascii?Q?PlHbnH1Vi31DwiXrF6j+LXuu6w/71Q0ZFlkaQwSigJHG5E1mb/n+2GYkCRlS?= =?us-ascii?Q?sUB+DpyOAiUBSq8yeY/F6oF8M1xFgeyxqLMuR6FlGEb7IfZVpdmi+L68B2Mu?= =?us-ascii?Q?CPMWKeJTJA=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 10276576-64e8-4e5f-0acc-08dead30ed16 X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB4179.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 18:37:58.2351 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: x79vPuThMU3c+/VYYEvq+Z3Xa++cVmi9yOjltDZ+Sj5Puyr/MlKfi7bpr6su/fn1YfN0dpxZTnrqLMTzztYuxg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB6205 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=2a01:111:f403:c105::1; envelope-from=tdave@nvidia.com; helo=CH1PR05CU001.outbound.protection.outlook.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.44, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_SPF_HELO=1, RCVD_IN_DNSWL_NONE=-0.0001, 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @Nvidia.com) X-ZM-MESSAGEID: 1778265563726154100 Content-Type: text/plain; charset="utf-8" Add a "pci-pre-enum" option for the virt machine. When enabled, QEMU performs PCI enumeration and programs BARs before handing control to firmware. This is intended for use with the "fixed-bars" property, where the user assigns fixed BAR addresses and expects firmware to preserve the configuration. pci-pre-enum is exposed as a separate machine property rather than being implied by the presence of fixed-bars. This allows QEMU's PCI enumeration path to be exercised independently (for example, to verify that QEMU produces the same device enumeration as EDK2) without requiring any device to specify fixed BARs. When enabled, a "pci-enum-done" property is added to the PCI node in the device tree to indicate to firmware (e.g. EDK2) that PCI enumeration has already been performed. When disabled (default), behavior is unchanged. Signed-off-by: Tushar Dave --- hw/arm/virt.c | 70 +++++++++++++++++++++++++++++++++++++++++-- include/hw/arm/virt.h | 1 + 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 55f41c7e46..7d41bfc457 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -52,6 +52,7 @@ #include "system/whpx.h" #include "system/qtest.h" #include "system/system.h" +#include "system/reset.h" #include "hw/core/loader.h" #include "qapi/error.h" #include "qemu/bitops.h" @@ -94,6 +95,8 @@ #include "hw/cxl/cxl.h" #include "hw/cxl/cxl_host.h" #include "qemu/guest-random.h" +#include "hw/pci/pci-resource.h" +#include "hw/pci/pci-enumerate.h" =20 static GlobalProperty arm_virt_compat_defaults[] =3D { { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" }, @@ -1697,6 +1700,10 @@ static void create_pcie(VirtMachineState *vms) qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1); create_pcie_irq_map(ms, vms->gic_phandle, irq, nodename); =20 + if (vms->pci_pre_enum) { + qemu_fdt_setprop_cell(ms->fdt, nodename, "pci-enum-done", 1); + } + if (vms->iommu) { vms->iommu_phandle =3D qemu_fdt_alloc_phandle(ms->fdt); =20 @@ -1832,6 +1839,20 @@ static void virt_build_smbios(VirtMachineState *vms) } } =20 +static void virt_pci_apply_fix_bar_after_reset(void *opaque) +{ + VirtMachineState *vms =3D opaque; + PciFixedBarMmioParams mmio =3D { + .mmio32_base =3D vms->memmap[VIRT_PCIE_MMIO].base, + .mmio32_size =3D vms->memmap[VIRT_PCIE_MMIO].size, + .mmio64_base =3D vms->memmap[VIRT_HIGH_PCIE_MMIO].base, + .mmio64_size =3D vms->memmap[VIRT_HIGH_PCIE_MMIO].size, + }; + + pci_enumerate_bus(vms->bus); + pci_fixed_bar_allocator(vms->bus, &mmio); +} + static void virt_machine_done(Notifier *notifier, void *data) { @@ -1864,11 +1885,30 @@ void virt_machine_done(Notifier *notifier, void *da= ta) if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms, cpu) = < 0) { exit(1); } - - pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus, - &error_abort); + /* + * In pci-pre-enum mode, EDK2 does not perform PCI enumeration or + * resource assignment (PcdPciDisableBusEnumeration =3D TRUE). All root + * bridges are marked ResourceAssigned, meaning the topology and + * MMIO/MMIO64 apertures provided by QEMU are treated as final. + * + * In this mode, each root bridge is consumed as an independent resour= ce + * domain. Exposing additional root bridges (e.g. PXB extra roots) that + * share identical MMIO/MMIO64 apertures creates duplicate resource do= mains + * with overlapping address spaces, which is invalid in this mode. + * + * Therefore, extra root bridges are not exposed in pre-enumeration mo= de. + */ + if (!vms->pci_pre_enum) { + pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus, + &error_abort); + } =20 virt_acpi_setup(vms); + + if (vms->pci_pre_enum) { + qemu_register_reset(virt_pci_apply_fix_bar_after_reset, vms); + } + virt_build_smbios(vms); } =20 @@ -2988,6 +3028,20 @@ static void virt_set_mte(Object *obj, bool value, Er= ror **errp) vms->mte =3D value; } =20 +static bool virt_get_pci_pre_enum(Object *obj, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + + return vms->pci_pre_enum; +} + +static void virt_set_pci_pre_enum(Object *obj, bool value, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + + vms->pci_pre_enum =3D value; +} + static char *virt_get_gic_version(Object *obj, Error **errp) { VirtMachineState *vms =3D VIRT_MACHINE(obj); @@ -3726,6 +3780,13 @@ static void virt_machine_class_init(ObjectClass *oc,= const void *data) "in ACPI table header." "The string may be up to 8 bytes= in size"); =20 + object_class_property_add_bool(oc, "pci-pre-enum", + virt_get_pci_pre_enum, + virt_set_pci_pre_enum); + object_class_property_set_description(oc, "pci-pre-enum", + "Set on/off to enable/disable PC= I enumeration and resource assignment" + " in QEMU. When enabled, QEMU pr= ograms BARs (including fixed-bars" + " addresses) before handing cont= rol to firmware."); } =20 static void virt_instance_init(Object *obj) @@ -3768,6 +3829,9 @@ static void virt_instance_init(Object *obj) /* MTE is disabled by default. */ vms->mte =3D false; =20 + /* PCI pre-enumeration disabled by default */ + vms->pci_pre_enum =3D false; + /* Supply kaslr-seed and rng-seed by default */ vms->dtb_randomness =3D true; =20 diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 410df857c7..0786f4a4fc 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -187,6 +187,7 @@ struct VirtMachineState { MemoryRegion *sysmem; MemoryRegion *secure_sysmem; bool pci_preserve_config; + bool pci_pre_enum; hwaddr override_pcie_mmio_base; hwaddr override_pcie_mmio_size; }; --=20 2.34.1