From nobody Mon Feb 9 19:06:03 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DED332D7F1 for ; Thu, 5 Feb 2026 21:00:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770325224; cv=none; b=gDuIgT6uSy8HhfmQiTfYXamyrzpPA2pRDXlsKo1MdCuehbkP21rLsskiPHvuhGgO5Dpwo6CW6ym3761kalD9TOZtRd3JwphmkZyaMPQDR1MmJqW4uLc5/8vVs+W0WUT0hnKQYdf7J25kd8C95xeXWiK8mUzUqLLzmEypk3zFY3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770325224; c=relaxed/simple; bh=O9mLxT+roBXO/RmpnwI+KoBGja1TUjQ0eNURQ1PhU0s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TvtG7EgztkeZ3Q0RqdOZco03qI04MNFU5oasJ3FL69OC0NwOLm7mvEygTMCng2FdGzu+zF7mHYKoN9h51IU021Newa9EnSYPHCGgzGkwPj5+GL3n80f1l3mC74Em90b/A42HNkQjWIfe1MqN+yztpDo9aM4l+6xRLr4prmN1xRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LdHqN68o; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=l63Hji6B; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LdHqN68o"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="l63Hji6B" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770325223; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aJ0fgGiJg3nMFc2XePDEX8wab9GDsnp8jWnAJ4AGTN4=; b=LdHqN68opCoSgzb+dsyWblg2ZcRcFHaWg/1Bq1b6STfHTwLLSWon7VzcscsFoaKt7bhuSw hKrpgv7xP/lTAhGbBeKVqGg+WJdc7dxUKqK5tLR7DZYs1NLKYDGFyxTsUSZN4PnqEXq5gg qwSGP5uIGEBHop8Th/+1wD82iAWs0dg= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-628-hflwXgE8N0SZzcH9hvXfEg-1; Thu, 05 Feb 2026 16:00:22 -0500 X-MC-Unique: hflwXgE8N0SZzcH9hvXfEg-1 X-Mimecast-MFC-AGG-ID: hflwXgE8N0SZzcH9hvXfEg_1770325222 Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-8c6b315185aso574006085a.2 for ; Thu, 05 Feb 2026 13:00:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1770325222; x=1770930022; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=aJ0fgGiJg3nMFc2XePDEX8wab9GDsnp8jWnAJ4AGTN4=; b=l63Hji6BoB+gi5w9+vH+QOiMSrTaBkovo7wlFr9QrBSpNQx1PMtfiVF8aSNhSZdop1 gHgF6SFjveuaG3P/pEhboRU7+te0EKaKX2J0Yf07V0eDTJhbBzwlPfyBzoZJ/EFX1FuK AAKueD239fXy8qJe418NzkqlicNjDaowWCGDsDXSeGoOuWIdpoTBbmUZP/4i5ct9KTg6 DtQRwAyArq3F+4C23iccquX9x6DfAGXRouA1gbqLKcj6PQhc6PXrEdVIxVyh1UlBdQR2 84Afe0bwx6eJnq1C++gyuyQeD1WfHmuPfei/7ZZqG97XyPlFWMsImB+dMCQJB80Z1+Z4 yUaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770325222; x=1770930022; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=aJ0fgGiJg3nMFc2XePDEX8wab9GDsnp8jWnAJ4AGTN4=; b=MWei0HGy7OULxTRfgSkct18z0Ro0a8okw9qymQgaJfBYRcElV0IfYdaqoi8PBE5wQM x7krsByDnmJTver9n7IRmv4dsnmg8jsc1JpVm50rY4oPzpRvdvS1fsNLM9cQv33wCgCy x4TeRNdwcn0zKguN23BaqwK5oEQTh32w0EASJObTuskvTChv2p5B2nwPVg8uIsD22d0s r5FybtGNgEjrlUxXsKMuoa5jK2XL8sN17q8ZgG1OKjWo1ce9TJY2tgA8jgSWbfkYi6l9 UedHaV8z2H3VA4tfLa+AKnaMDfdcnBgsd9vC5wvrT8JqYPOPfu0FKmrG+k9c54rHLwtV XXng== X-Forwarded-Encrypted: i=1; AJvYcCVQnDHpDTdVAACDY7fk+h8LY4sF56mD8uYMdnGaKbnHVtp0Pxiom/5NBaxPKXxPxNrHPiQCRz5IVMGmUN4=@vger.kernel.org X-Gm-Message-State: AOJu0YyznMf0qekXPRZ3aVBmWC87b9Y8pMFcXaEZlKtLWQPufV/D2fdn b1jHl75TSVsfSrTPV94sE2ttxq7PFjPQTQMM8+S4+I6mDADGwHITn14vfqD+jHr58w9rF4qu+CN 9ZfNHXU7wGPi0sYuzy5cSbWFI8oYV8LaI9MpSW0//H+/KFCieHof7+AOXddt0Q5OgAg== X-Gm-Gg: AZuq6aJ6eCFNtUUOwHeEODXVF6ddyRSkj+jvv+1i1E7UxwWSlFoj6FZtJMJfc1z4J6u tKXgFfVNSgXLp3A6ya+RrVjDLRZvJ6cMF4I1kvNedWlqEbpJOyy1asvl/ezARQSjazVv7c3TV8k EhupXHTj5o3afmq5hSsMTKI+CAPwrq+Hicck9rDkNoYwrFM7pFai7KlrZTJda/jutrDeMcbYJjV /2rLsgN/rN59EnNRWBeqt80vxbyuq0nwEVDhezsrVrgglG2SecBZkfxA2tk3nqNq0TdWJJGFcMQ KgBTvnnETo8arI5YnxzA98hSDT7TS+m1iY4Nhll6cbVdo1xaGlxZ6Uut2AgHA86Cn+X9A4DqXmR K7VfJDIoSumMJXwY= X-Received: by 2002:a05:620a:7085:b0:8b2:e70c:427a with SMTP id af79cd13be357-8caf0d3d77cmr64317285a.44.1770325221696; Thu, 05 Feb 2026 13:00:21 -0800 (PST) X-Received: by 2002:a05:620a:7085:b0:8b2:e70c:427a with SMTP id af79cd13be357-8caf0d3d77cmr64305385a.44.1770325220994; Thu, 05 Feb 2026 13:00:20 -0800 (PST) Received: from [172.16.1.8] ([2607:f2c0:b010:9000:4c85:f148:4c91:943a]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8caf9fdf692sm17571285a.44.2026.02.05.13.00.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Feb 2026 13:00:20 -0800 (PST) From: Peter Colberg Date: Thu, 05 Feb 2026 15:59:48 -0500 Subject: [PATCH v2 01/10] PCI: add driver flag to opt into disabling SR-IOV on remove() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260205-rust-pci-sriov-v2-1-ef9400c7767b@redhat.com> References: <20260205-rust-pci-sriov-v2-0-ef9400c7767b@redhat.com> In-Reply-To: <20260205-rust-pci-sriov-v2-0-ef9400c7767b@redhat.com> To: Danilo Krummrich , Bjorn Helgaas , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Abdiel Janulgue , Daniel Almeida , Robin Murphy , Greg Kroah-Hartman , Dave Ertman , Ira Weiny , Leon Romanovsky , David Airlie , Simona Vetter , Jonathan Corbet , Xu Yilun , Tom Rix , Moritz Fischer , "Rafael J. Wysocki" Cc: linux-pci@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandre Courbot , Alistair Popple , Joel Fernandes , John Hubbard , Zhi Wang , nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org, linux-fpga@vger.kernel.org, driver-core@lists.linux.dev, Peter Colberg , Jason Gunthorpe X-Mailer: b4 0.14.2 Add a flag managed_sriov to the pci_driver structure that allows a driver to opt into disabling the Single Root I/O Virtualization (SR-IOV) capability of the device when the driver is unbound. Add a new function pci_iov_disable() that is invoked before the remove() callback of a PCI driver and checks for the presence of the new flag. If the flag is set, invoke the sriov_configure() callback to allow the driver to gracefully disable SR-IOV. Warn if the driver fails to do so and forcibly disable SR-IOV using sriov_disable(). Since a (broken) driver may theoretically re-enable SR-IOV during its remove() callback, extend pci_iov_remove() to forcibly disable SR-IOV after remove() if needed and only if the flag managed_sriov is set. Altogether the flag ensures that when a Virtual Function (VF) is bound to a driver, the corresponding Physical Function (PF) is bound to a driver, too, since the VF devices are destroyed when the PF driver is unbound. This guarantee is a prerequisite for exposing a safe Rust API that allows a VF driver to obtain the PF device for a VF device and subsequently access the device private data of the PF device. Suggested-by: Danilo Krummrich Signed-off-by: Peter Colberg --- Changes in v2: - Move logic to disable SR-IOV on remove() from Rust to C. - Add driver flag managed_sriov to opt into disabling SR-IOV on remove(). --- drivers/pci/iov.c | 41 ++++++++++++++++++++++++++++++++++++++++- drivers/pci/pci-driver.c | 3 ++- drivers/pci/pci.h | 2 ++ include/linux/pci.h | 8 ++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 00784a60ba80bb55ff2790d8f87e15a90c652a24..5b6ed251b4b1e940ec5781bb10d= d5c58d3609fc8 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -1011,20 +1011,59 @@ void pci_iov_release(struct pci_dev *dev) sriov_release(dev); } =20 +/** + * pci_iov_disable - disable SR-IOV before PF driver is detached + * @dev: the PCI device + * + * Invoke sriov_configure() callback to allow the driver to gracefully dis= able + * SR-IOV. Warn if the driver fails to do so and forcibly disable SR-IOV. + */ +void pci_iov_disable(struct pci_dev *dev) +{ + struct pci_driver *drv =3D dev->driver; + struct pci_sriov *iov =3D dev->sriov; + + if (WARN_ON(!drv)) + return; + + if (!dev->is_physfn || !iov->num_VFs || !drv->managed_sriov) + return; + + if (!drv->sriov_configure) { + sriov_disable(dev); + return; + } + + drv->sriov_configure(dev, 0); + + if (WARN_ON(iov->num_VFs)) + sriov_disable(dev); +} + /** * pci_iov_remove - clean up SR-IOV state after PF driver is detached * @dev: the PCI device */ void pci_iov_remove(struct pci_dev *dev) { + struct pci_driver *drv =3D dev->driver; struct pci_sriov *iov =3D dev->sriov; =20 + if (WARN_ON(!drv)) + return; + if (!dev->is_physfn) return; =20 iov->driver_max_VFs =3D iov->total_VFs; - if (iov->num_VFs) + + if (iov->num_VFs && !drv->managed_sriov) { pci_warn(dev, "driver left SR-IOV enabled after remove\n"); + return; + } + + if (WARN_ON(iov->num_VFs)) + sriov_disable(dev); } =20 /** diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 7c2d9d59625868886d61d8d4045d656ee0165776..e44593c67d147cd70d2d1a8a436= a26857b0e446a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -462,6 +462,7 @@ static void pci_device_remove(struct device *dev) struct pci_dev *pci_dev =3D to_pci_dev(dev); struct pci_driver *drv =3D pci_dev->driver; =20 + pci_iov_disable(pci_dev); if (drv->remove) { pm_runtime_get_sync(dev); /* @@ -475,8 +476,8 @@ static void pci_device_remove(struct device *dev) pm_runtime_put_noidle(dev); } pcibios_free_irq(pci_dev); - pci_dev->driver =3D NULL; pci_iov_remove(pci_dev); + pci_dev->driver =3D NULL; =20 /* Undo the runtime PM settings in local_pci_probe() */ pm_runtime_put_sync(dev); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0e67014aa0013a7086c3a45d576d4b1ca2bb159f..53692e138ed347bfcf6d5923ddd= 418e9860399d7 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -826,6 +826,7 @@ static inline void pci_restore_pasid_state(struct pci_d= ev *pdev) { } #ifdef CONFIG_PCI_IOV int pci_iov_init(struct pci_dev *dev); void pci_iov_release(struct pci_dev *dev); +void pci_iov_disable(struct pci_dev *dev); void pci_iov_remove(struct pci_dev *dev); void pci_iov_update_resource(struct pci_dev *dev, int resno); resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resn= o); @@ -860,6 +861,7 @@ static inline int pci_iov_init(struct pci_dev *dev) return -ENODEV; } static inline void pci_iov_release(struct pci_dev *dev) { } +static inline void pci_iov_disable(struct pci_dev *dev) { } static inline void pci_iov_remove(struct pci_dev *dev) { } static inline void pci_iov_update_resource(struct pci_dev *dev, int resno)= { } static inline resource_size_t pci_sriov_resource_alignment(struct pci_dev = *dev, diff --git a/include/linux/pci.h b/include/linux/pci.h index b5cc0c2b99065d4a1ee4581275362e79726a2145..768a02b12ff73aeb4dc3dc33fcc= a7c46b524c3c0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -997,6 +997,13 @@ struct module; * how to manage the DMA themselves and set this flag so that * the IOMMU layer will allow them to setup and manage their * own I/O address space. + * @managed_sriov: Disable SR-IOV on remove(). + * If set, the Single Root I/O Virtualization (SR-IOV) + * capability of the device is disabled when the driver is + * unbound from the device, by calling sriov_configure() + * before remove(). The presence of this flag guarantees + * that when a Virtual Function (VF) is bound to a driver, + * the Physical Function (PF) is bound to a driver, too. */ struct pci_driver { const char *name; @@ -1015,6 +1022,7 @@ struct pci_driver { struct device_driver driver; struct pci_dynids dynids; bool driver_managed_dma; + bool managed_sriov; }; =20 #define to_pci_driver(__drv) \ --=20 2.52.0