From nobody Tue Mar 3 03:21:03 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1772016262; cv=none; d=zohomail.com; s=zohoarc; b=Upynrulnj677y08IJRSZhv0vTj2AI6kVaZTH9UCwZVk8pMXh87/s/axUpKNGd6kC5KZLo0+t18MD/YCJ9mPfAQtt7M4ThTfmHz0bBGpHPYnFOO22lVj5L6YU2gJa5PBiVblqZUgspykyvnlaA5sYOla27gx0wEvup0RCJabD6k4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772016262; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:Subject:Subject:To:To:Message-Id; bh=X/mrNlqsJXmPadCMESdvpMZvGnUw9K5gqwSvKnHVZI8=; b=CX1PudRe/EuI+0CymQ4opwRQO6vcec8MNYaPbS6/BNT/C8Lmv+g4PgNfI43cKgtM9E78tJtBnXx5QpN12FrQb/yqtOF7XD4odvHHDznbGzDKuOidQ4S2XuNqCNPDBbb1XAQvYB7GVqafMj8F5b+T+CmcGEi2II8idK3AnZuwD4Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1772016262294314.2699849968443; Wed, 25 Feb 2026 02:44:22 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 6DE4541DC4; Wed, 25 Feb 2026 05:44:22 -0500 (EST) Received: from [172.19.199.9] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 5514541DC9; Wed, 25 Feb 2026 05:43:40 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 5AC0F41AE4; Wed, 25 Feb 2026 05:43:36 -0500 (EST) Received: from mail-4327.protonmail.ch (mail-4327.protonmail.ch [185.70.43.27]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id CC54F41A9F for ; Wed, 25 Feb 2026 05:43:35 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HELO_MISC_IP,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 471 seconds by postgrey-1.37 at lists.libvirt.org; Wed, 25 Feb 2026 05:43:35 EST DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1772015742; x=1772274942; bh=X/mrNlqsJXmPadCMESdvpMZvGnUw9K5gqwSvKnHVZI8=; h=Date:To:From:Cc:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector; b=yoN1zQ25eJMmGYFdaDzXaIG8LL/GURgBvFkJU/WAqdMr33gx9g6afA6GYa3UDxoQs WroHcjTsX6dMdIbW+8IjUBLqJx6pSfTNwpfSbh4MCYPeym2hDEpmKZGLzLGrJ8cvB+ en+Fjohuy8BQu4cHxQVkVvazkU+1PfwdknIruhU88nUqtVSP+y0h2sp7YmK9mBMnx5 0igThXFzV38VxayAkBkcRb3s11ghsxF11TPYsfrhdarnD3gM1UcofhBU10CLOJ1fyI fEfd+uzewHcKaiYjYYi6CXgkxdVEVcc6l2ctTvBMeCeh9G/IKC86Y8ka/hz1N5XCxi kYacF1MlwjU5A== Date: Wed, 25 Feb 2026 10:35:37 +0000 To: devel@lists.libvirt.org Subject: [PATCH] util: Fix secondary bus reset check for multi-root PCI systems Message-ID: <20260225103530.109221-1-ehanoc@protonmail.com> Feedback-ID: 4792375:user:proton X-Pm-Message-ID: ddb6b3bbb79c8f8330a88e30c8da830f0826796c MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: RDF5XXCNO6TILGFUO4A3AFMG5T2UTNJN X-Message-ID-Hash: RDF5XXCNO6TILGFUO4A3AFMG5T2UTNJN X-MailFrom: ehanoc@protonmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: ehanoc X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: ehanoc via Devel Reply-To: ehanoc X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1772016264366158500 Content-Type: text/plain; charset="utf-8" The virPCIDeviceReset() function was using a hardcoded check for bus !=3D 0 to determine if a device is on a root bus before attempting a secondary bus reset. This breaks on multi-root systems like Intel Arrow Lake where devices can be on non-zero root buses (e.g., Bus 0x80 for the PCH root complex). Update the logic to use virPCIDeviceIsOnRootBus() which detects root bus attachment via sysfs topology, making it work correctly on any PCI-compliant system regardless of bus numbers. This ensures secondary bus reset is never attempted on ANY root bus (0x00, 0x80, etc.), only on devices behind PCI bridges where it's safe. Signed-off-by: Bruno Martins --- src/util/virpci.c | 106 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/src/util/virpci.c b/src/util/virpci.c index 2348a98003..f2ce24e6aa 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -1081,6 +1081,81 @@ virPCIDeviceInit(virPCIDevice *dev, int cfgfd) return 0; } =20 +/* + * Check if a PCI device is directly attached to a root bus (no parent bri= dge). + * + * Modern systems like Intel Arrow Lake (Core Ultra 200) can have multiple + * root buses (e.g., bus 0x00 for CPU devices and bus 0x80 for PCH devices= ). + * We detect root bus attachment by examining the sysfs topology: a device + * is on a root bus if its sysfs path is a direct child of a pciXXXX:YY + * directory (e.g., /sys/devices/pci0000:80/0000:80:14.0). + * + * Returns 1 if on root bus, 0 if not, -1 on error. + */ +static int +virPCIDeviceIsOnRootBus(virPCIDevice *dev) +{ + unsigned int domain, bus; + g_autofree char *devPath =3D NULL; + g_autofree char *realPath =3D NULL; + g_autofree char *parentDir =3D NULL; + const char *parentName; + + /* Get the sysfs symlink path for this device */ + devPath =3D g_strdup_printf(PCI_SYSFS "devices/%s", dev->name); + + /* Resolve the symlink to get the real path in /sys/devices/... */ + if (virFileResolveLink(devPath, &realPath) < 0) { + VIR_DEBUG("%s %s: failed to resolve sysfs path %s", + dev->id, dev->name, devPath); + return -1; + } + + parentDir =3D g_path_get_dirname(realPath); + if (!parentDir) + return -1; + + parentName =3D strrchr(parentDir, '/'); + if (!parentName) + return -1; + parentName++; // skip the '/' + + /* + * Detect root bus by parsing the parent directory name using sscanf. + * + * PCI root buses in sysfs follow the naming convention: + * pci: + * + * - : number (0000-ffff, hex) + * - : number within the domain (00-ff, hex) + * + * This format is defined in: + * https://www.kernel.org/doc/html/latest/PCI/sysfs-pci.html + * + * Examples from Intel Arrow Lake systems: + * - pci0000:00 (CPU root bus) + * - pci0000:80 (PCH root bus - the problematic case on Arrow Lake) + * + * sscanf pattern "pci%x:%x" matches: + * - "pci" : literal prefix + * - "%x" : hex domain (stops at ':') + * - ":" : literal separator + * - "%x" : hex bus (must reach end of string) + * + * Returns 2 if both domain and bus were successfully parsed, + * confirming the device is a direct child of a root bus. + */ + if (sscanf(parentName, "pci%x:%x", &domain, &bus) =3D=3D 2) { + VIR_DEBUG("%s %s: device is on root bus (parent=3D%s)", + dev->id, dev->name, parentName); + return 1; + } + + VIR_DEBUG("%s %s: device is not on root bus (parent=3D%s)", + dev->id, dev->name, parentName); + return 0; +} + int virPCIDeviceReset(virPCIDevice *dev, virPCIDeviceList *activeDevs, @@ -1146,9 +1221,17 @@ virPCIDeviceReset(virPCIDevice *dev, if (dev->has_pm_reset) ret =3D virPCIDeviceTryPowerManagementReset(dev, fd); =20 - /* Bus reset is not an option with the root bus */ - if (ret < 0 && dev->address.bus !=3D 0) - ret =3D virPCIDeviceTrySecondaryBusReset(dev, fd, inactiveDevs); + /* Bus reset is not an option with the root bus. On multi-root + * systems like Intel Arrow Lake, root buses can be non-zero (e.g., 0x= 80), + * so we use sysfs topology detection instead of checking bus =3D=3D 0. + */ + if (ret < 0) { + int onRootBus =3D virPCIDeviceIsOnRootBus(dev); + if (onRootBus < 0) + goto cleanup; + if (!onRootBus) + ret =3D virPCIDeviceTrySecondaryBusReset(dev, fd, inactiveDevs= ); + } =20 if (ret < 0) { virErrorPtr err =3D virGetLastError(); @@ -2531,15 +2614,24 @@ static int virPCIDeviceIsBehindSwitchLackingACS(virPCIDevice *dev) { g_autoptr(virPCIDevice) parent =3D NULL; + int onRootBus; =20 if (virPCIDeviceGetParent(dev, &parent) < 0) return -1; if (!parent) { - /* if we have no parent, and this is the root bus, ACS doesn't come - * into play since devices on the root bus can't P2P without going - * through the root IOMMU. + /* If we have no parent bridge, check if the device is directly + * attached to a root bus. Systems like Intel Arrow Lake can have + * multiple root buses (e.g., 0x00 and 0x80), so we can't just + * check for bus =3D=3D 0. Instead, use sysfs topology to detect + * root bus attachment. + * + * ACS doesn't come into play for devices on root buses since + * they can't P2P without going through the root IOMMU. */ - if (dev->address.bus =3D=3D 0) { + onRootBus =3D virPCIDeviceIsOnRootBus(dev); + if (onRootBus < 0) + return -1; + if (onRootBus) { return 0; } else { virReportError(VIR_ERR_INTERNAL_ERROR, --=20 2.47.3