From: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org,
Madhavan Srinivasan <maddy@linux.ibm.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Nicholas Piggin <npiggin@gmail.com>,
Christophe Leroy <chleroy@kernel.org>,
Mahesh J Salgaonkar <mahesh@linux.ibm.com>,
Oliver O'Halloran <oohall@gmail.com>,
Niklas Schnelle <schnelle@linux.ibm.com>,
Gerald Schaefer <gerald.schaefer@linux.ibm.com>,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Alex Williamson <alex@shazbot.org>,
Jason Gunthorpe <jgg@ziepe.ca>, Kevin Tian <kevin.tian@intel.com>,
Ankit Agrawal <ankita@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
Juergen Gross <jgross@suse.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>,
Keith Busch <kbusch@kernel.org>,
Alexander Duyck <alexanderduyck@fb.com>,
Jakub Kicinski <kuba@kernel.org>,
Dimitri Daskalakis <daskald@meta.com>,
linuxppc-dev@lists.ozlabs.org, linux-s390@vger.kernel.org,
kvm@vger.kernel.org, xen-devel@lists.xenproject.org
Subject: [RFC 11/12] PCI: Initialize and release SIOV capability
Date: Thu, 4 Jun 2026 08:01:52 -0700 [thread overview]
Message-ID: <20260604150153.3619662-12-dimitri.daskalakis1@gmail.com> (raw)
In-Reply-To: <20260604150153.3619662-1-dimitri.daskalakis1@gmail.com>
From: Dimitri Daskalakis <daskald@meta.com>
Modify pci_init_capabilities() to discover the SIOV extended capability
(cap ID 0x38). When present, allocate struct pci_siov that records the
capability position, total SDI count, routing ID offset and stride, and
the maximum bus range the SDIs can span.
The init path mirrors sriov_init(): read the capability registers,
compute the worst-case bus consumption from total_SDIs, and stash the
result in the PF's pci_dev. Release frees the structure on teardown.
If is_physfn was already set (by sriov_init), it will not be cleared if
siov_init() fails. This prevents clobbering the flag for devices that
enable both virtualization types.
The SR-IOV code does not unset the is_physfn bit of a pci device
when disabled, and the SIOV code follows that pattern.
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Dimitri Daskalakis <daskald@meta.com>
---
drivers/pci/Makefile | 1 +
drivers/pci/pci.h | 16 ++++++
drivers/pci/probe.c | 2 +
drivers/pci/siov.c | 113 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 132 insertions(+)
create mode 100644 drivers/pci/siov.c
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 41ebc3b9a518..a584cd1bf08a 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_PCI_QUIRKS) += quirks.o
obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
obj-$(CONFIG_PCI_ATS) += ats.o
obj-$(CONFIG_PCI_IOV) += iov.o
+obj-$(CONFIG_PCI_SIOV) += siov.o
obj-$(CONFIG_PCI_BRIDGE_EMUL) += pci-bridge-emul.o
obj-$(CONFIG_PCI_LABEL) += pci-label.o
obj-$(CONFIG_X86_INTEL_MID) += pci-mid.o
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index fd7c04e26c16..a516db996aab 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1042,6 +1042,22 @@ static inline u16 pci_virtfn_routing_id(struct pci_dev *pf, u16 offset,
}
#endif
+#ifdef CONFIG_PCI_SIOV
+int pci_siov_init(struct pci_dev *dev);
+void pci_siov_release(struct pci_dev *dev);
+int pci_siov_bus_range(struct pci_bus *bus);
+#else
+static inline int pci_siov_init(struct pci_dev *dev)
+{
+ return -ENODEV;
+}
+static inline void pci_siov_release(struct pci_dev *dev) { }
+static inline int pci_siov_bus_range(struct pci_bus *bus)
+{
+ return 0;
+}
+#endif
+
#ifdef CONFIG_PCIE_TPH
void pci_restore_tph_state(struct pci_dev *dev);
void pci_save_tph_state(struct pci_dev *dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..bebc32c8d374 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2473,6 +2473,7 @@ static void pci_release_capabilities(struct pci_dev *dev)
pci_aer_exit(dev);
pci_rcec_exit(dev);
pci_iov_release(dev);
+ pci_siov_release(dev);
pci_free_cap_save_buffers(dev);
}
@@ -2666,6 +2667,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
pci_vpd_init(dev); /* Vital Product Data */
pci_configure_ari(dev); /* Alternative Routing-ID Forwarding */
pci_iov_init(dev); /* Single Root I/O Virtualization */
+ pci_siov_init(dev); /* Scalable I/O Virtualization */
pci_ats_init(dev); /* Address Translation Services */
pci_pri_init(dev); /* Page Request Interface */
pci_pasid_init(dev); /* Process Address Space ID */
diff --git a/drivers/pci/siov.c b/drivers/pci/siov.c
new file mode 100644
index 000000000000..7372ce95714b
--- /dev/null
+++ b/drivers/pci/siov.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Express Scalable I/O Virtualization (SIOV) support
+ */
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include "pci.h"
+
+static int pci_siov_sdi_bus(struct pci_dev *dev, int sdi_id)
+{
+ if (!dev->siov)
+ return -EINVAL;
+ return pci_virtfn_routing_id(dev, dev->siov->offset,
+ dev->siov->stride, sdi_id) >> 8;
+}
+
+static int compute_max_sdi_buses(struct pci_dev *dev)
+{
+ struct pci_siov *siov = dev->siov;
+
+ if (!siov->offset || (siov->total_SDIs > 1 && !siov->stride))
+ return -EIO;
+
+ siov->max_SDI_buses = pci_siov_sdi_bus(dev, siov->total_SDIs - 1);
+ return 0;
+}
+
+static int siov_init(struct pci_dev *dev, int pos)
+{
+ struct pci_siov *siov;
+ bool was_physfn;
+ u16 total;
+ u8 status;
+ int rc;
+
+ pci_read_config_byte(dev, pos + PCI_SIOV_STATUS, &status);
+ if (status & PCI_SIOV_STATUS_ENABLED)
+ pci_warn(dev, "SIOV: SDIs active at init, FLR may be required\n");
+
+ pci_read_config_word(dev, pos + PCI_SIOV_TOTAL_SDI, &total);
+ if (!total)
+ return 0;
+
+ siov = kzalloc_obj(*siov);
+ if (!siov)
+ return -ENOMEM;
+
+ siov->pos = pos;
+ siov->total_SDIs = total;
+ siov->driver_max_SDIs = total;
+ siov->self = dev;
+ pci_read_config_dword(dev, pos + PCI_SIOV_CAP, &siov->cap);
+ pci_read_config_word(dev, pos + PCI_SIOV_SDI_OFFSET, &siov->offset);
+ pci_read_config_word(dev, pos + PCI_SIOV_SDI_STRIDE, &siov->stride);
+
+ was_physfn = dev->is_physfn;
+
+ dev->siov = siov;
+ dev->is_physfn = 1;
+ dev->is_siov = 1;
+ rc = compute_max_sdi_buses(dev);
+ if (rc) {
+ dev->siov = NULL;
+ dev->is_siov = 0;
+ if (!was_physfn)
+ dev->is_physfn = 0;
+ kfree(siov);
+ return rc;
+ }
+
+ return 0;
+}
+
+static void siov_release(struct pci_dev *dev)
+{
+ WARN_ON_ONCE(dev->siov->num_SDIs);
+
+ kfree(dev->siov);
+ dev->siov = NULL;
+ dev->is_siov = 0;
+}
+
+/**
+ * pci_siov_init - initialize the Scalable IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_siov_init(struct pci_dev *dev)
+{
+ int pos;
+
+ if (!pci_is_pcie(dev))
+ return -ENODEV;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SIOV);
+ if (pos)
+ return siov_init(dev, pos);
+
+ return -ENODEV;
+}
+
+/**
+ * pci_siov_release - release resources used by the SIOV capability
+ * @dev: the PCI device
+ */
+void pci_siov_release(struct pci_dev *dev)
+{
+ if (dev->siov)
+ siov_release(dev);
+}
--
2.52.0
next prev parent reply other threads:[~2026-06-05 2:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-04 15:01 [RFC 00/12] PCI: Add support for Scalable I/O Virtualization Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 01/12] PCI: Add helpers to identify SR-IOV PFs/VFs Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 02/12] PCI: Convert iov.c to pci_is_sriov_* helpers Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 03/12] PCI: Convert pci.h " Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 04/12] PCI: Convert arch/powerpc " Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 05/12] PCI: Convert s390/pci/pci.c " Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 06/12] PCI: Convert vfio_pci_core.c " Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 07/12] PCI: Convert xen-pciback and pci-driver " Dimitri Daskalakis
2026-06-04 15:11 ` Juergen Gross
2026-06-04 15:01 ` [RFC 08/12] PCI: Add is_sriov bit to struct pci_dev Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 09/12] PCI: Add helper to compute VF Routing ID to pci.h Dimitri Daskalakis
2026-06-04 15:01 ` [RFC 10/12] PCI: Add Scalable I/O Virtualization data structure definitions Dimitri Daskalakis
2026-06-04 15:01 ` Dimitri Daskalakis [this message]
2026-06-04 15:01 ` [RFC 12/12] PCI: Reserve bus range for SIOV devices Dimitri Daskalakis
2026-06-04 18:20 ` [RFC 00/12] PCI: Add support for Scalable I/O Virtualization Jason Gunthorpe
2026-06-04 23:49 ` Dimitri Daskalakis
2026-06-04 23:53 ` Jason Gunthorpe
2026-06-05 0:59 ` Jakub Kicinski
2026-06-05 4:14 ` Christoph Hellwig
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=20260604150153.3619662-12-dimitri.daskalakis1@gmail.com \
--to=dimitri.daskalakis1@gmail.com \
--cc=agordeev@linux.ibm.com \
--cc=alex@shazbot.org \
--cc=alexanderduyck@fb.com \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=borntraeger@linux.ibm.com \
--cc=chleroy@kernel.org \
--cc=daskald@meta.com \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=jgg@ziepe.ca \
--cc=jgross@suse.com \
--cc=kbusch@kernel.org \
--cc=kevin.tian@intel.com \
--cc=kuba@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mahesh@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=oleksandr_tyshchenko@epam.com \
--cc=oohall@gmail.com \
--cc=schnelle@linux.ibm.com \
--cc=sstabellini@kernel.org \
--cc=svens@linux.ibm.com \
--cc=xen-devel@lists.xenproject.org \
/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