mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Shameer Kolothum <skolothumtho@nvidia.com>
To: <kvm@vger.kernel.org>, <linux-pci@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Cc: <alex@shazbot.org>, <jgg@ziepe.ca>, <kevin.tian@intel.com>,
	<kbusch@meta.com>, <michal.winiarski@intel.com>,
	<satyanarayana.k.v.p@intel.com>, <sonangp@nvidia.com>,
	<ankita@nvidia.com>, <nathanc@nvidia.com>, <mochs@nvidia.com>,
	<skolothumtho@nvidia.com>
Subject: [RFC PATCH v3 20/20] vfio/pci: Enable recovery for supported native PCIe endpoints
Date: Thu, 12 Nov 2026 14:16:32 +0000	[thread overview]
Message-ID: <20261112141632.918954-21-skolothumtho@nvidia.com> (raw)
In-Reply-To: <20261112141632.918954-1-skolothumtho@nvidia.com>

Enable recovery for generic vfio-pci endpoints on the subordinate bus of
a PCIe Root Port or Downstream Port.

The recovery power helpers require pci_bus_sem held for reading. Native
PCI recovery provides this through its bus walk. Check the endpoint's
bus as well as its upstream port, since synthetic VF buses are outside
that walk. Exclude direct RCiEP and root-bus endpoints.

Exclude EEH-enabled builds and Xen PV because their callbacks do not
provide the required locking. Exclude s390 and CXL memory devices
because their recovery paths can omit completion callbacks. Variant
drivers remain unsupported until their hardware accesses are protected.

Exclude functions with VPD redirected to function zero. The lookup takes
pci_bus_sem inside SRCU and can deadlock with recovery when a bus writer
is queued.

Also exclude Intel Ethernet function zero devices with VPD. Redirected
accesses from sibling functions bypass the target's access checks.
Exclude potential targets even before siblings are probed so support
does not depend on probe order.

These restrictions affect only the new recovery feature. Ordinary
assignment and existing error notifications remain available.

Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
 include/uapi/linux/vfio.h   |  6 +++-
 drivers/vfio/pci/vfio_pci.c | 61 +++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 86a3952ee302..f855d064c4b0 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1558,7 +1558,11 @@ struct vfio_device_feature_zpci_err {
 /*
  * Report host PCI error recovery state for this device.
  *
- * Userspace must probe the feature on each device before enabling it.
+ * Support is limited to PCIe endpoints on a Root Port or Downstream Port
+ * subordinate bus, using native PCI error recovery. Direct RCiEP, EEH, Xen
+ * PV, s390 and CXL memory recovery are not supported. Functions with
+ * VPD redirected to function zero, and Intel Ethernet function zero
+ * devices with VPD are excluded. Userspace must probe each device.
  *
  * VFIO_DEVICE_FEATURE_SET with a valid eventfd enables recovery for this
  * open and requests notifications when each event starts and ends. SET
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index a5ba4bb11638..fe9b8b8decca 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -126,10 +126,70 @@ static int vfio_pci_open_device(struct vfio_device *core_vdev)
 	return 0;
 }
 
+static bool vfio_pci_supports_recovery(struct pci_dev *pdev)
+{
+	struct pci_dev *bridge = pci_upstream_bridge(pdev);
+
+	/*
+	 * Looking up function zero for VPD takes pci_bus_sem inside access_srcu.
+	 * Recovery holds the bus read lock while waiting for these SRCU readers.
+	 * A queued bus writer can leave both paths waiting for each other.
+	 */
+	if (pdev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0)
+		return false;
+
+	/*
+	 * quirk_f0_vpd_link() can redirect sibling VPD accesses to these devices
+	 * without checking whether recovery has blocked function zero. Exclude
+	 * them even if no redirecting sibling is present at probe.
+	 */
+	if (!PCI_FUNC(pdev->devfn) && pdev->vpd.cap &&
+	    pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    (pdev->class >> 8) == PCI_CLASS_NETWORK_ETHERNET)
+		return false;
+
+	/*
+	 * EEH and Xen PV can call recovery without the required bus locking.
+	 * s390 recovery can omit completion callbacks.
+	 */
+	if (IS_ENABLED(CONFIG_S390) || IS_ENABLED(CONFIG_EEH) ||
+	    xen_pv_domain())
+		return false;
+
+	/*
+	 * Recovery power helpers require pci_bus_sem held for reading.
+	 * The native recovery walk holds it on a port's subordinate bus.
+	 * Direct RCiEP recovery does not use that walk.
+	 */
+	if (!pci_is_pcie(pdev))
+		return false;
+
+	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT &&
+	    pci_pcie_type(pdev) != PCI_EXP_TYPE_LEG_END)
+		return false;
+
+	if (!bridge || !pci_is_pcie(bridge))
+		return false;
+
+	if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT &&
+	    pci_pcie_type(bridge) != PCI_EXP_TYPE_DOWNSTREAM)
+		return false;
+
+	if (pdev->bus != bridge->subordinate)
+		return false;
+
+	/* CXL RCH recovery can omit completion callbacks. */
+	if ((pdev->class >> 8) == PCI_CLASS_MEMORY_CXL)
+		return false;
+
+	return true;
+}
+
 static int vfio_pci_init_dev(struct vfio_device *core_vdev)
 {
 	struct vfio_pci_core_device *vdev =
 		container_of(core_vdev, struct vfio_pci_core_device, vdev);
+	struct pci_dev *pdev = to_pci_dev(core_vdev->dev);
 
 	/*
 	 * These behaviors originated in vfio-pci and moved into
@@ -140,6 +200,7 @@ static int vfio_pci_init_dev(struct vfio_device *core_vdev)
 	 */
 	vdev->nointxmask = nointxmask;
 	vdev->disable_idle_d3 = disable_idle_d3;
+	vdev->pci_recovery_supported = vfio_pci_supports_recovery(pdev);
 #ifdef CONFIG_VFIO_PCI_VGA
 	vdev->disable_vga = disable_vga;
 #endif
-- 
2.43.0


      parent reply	other threads:[~2026-11-12 14:20 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12 14:16 [RFC PATCH v3 00/20] vfio/pci: Handle PCI error recovery and report state to userspace Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 01/20] vfio/pci: Add SRCU-protected access ops Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 02/20] PCI/PM: Add a power-state helper that tries the bus lock Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 03/20] vfio/pci: Avoid waiting for the bus lock when preparing D0 Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 04/20] vfio/pci: Use access ops for config-space accesses Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 05/20] vfio/pci: Buffer ROM reads before copying to userspace Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 06/20] vfio/pci: Use access ops for BAR and ROM accesses Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 07/20] vfio/pci: Use access ops when mapping BAR pages Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 08/20] vfio/pci: Use access ops for hardware IRQ operations Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 09/20] vfio/pci: Use access ops for function reset Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 10/20] vfio/pci: Use access ops for runtime-PM requests Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 11/20] vfio/pci: Use access ops for hardware information queries Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 12/20] vfio/pci: Use access ops for DMA-BUF export and restoration Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 13/20] vfio/pci: Track PCI recovery state Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 14/20] vfio/pci: Add INTx recovery operations Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 15/20] vfio/pci: Use access ops for SR-IOV configuration and shared reset Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 16/20] vfio/pci: Restore device state from slot_reset() Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 17/20] vfio/pci: Complete recovery in resume() Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 18/20] vfio/pci: Block device access during host recovery Shameer Kolothum
2026-11-12 14:16 ` [RFC PATCH v3 19/20] vfio/pci: Add VFIO_DEVICE_FEATURE_PCI_ERROR_RECOVERY Shameer Kolothum
2026-11-12 14:16 ` Shameer Kolothum [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261112141632.918954-21-skolothumtho@nvidia.com \
    --to=skolothumtho@nvidia.com \
    --cc=alex@shazbot.org \
    --cc=ankita@nvidia.com \
    --cc=jgg@ziepe.ca \
    --cc=kbusch@meta.com \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=michal.winiarski@intel.com \
    --cc=mochs@nvidia.com \
    --cc=nathanc@nvidia.com \
    --cc=satyanarayana.k.v.p@intel.com \
    --cc=sonangp@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®