linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] PCI/IOV: Make VF config reads match PCIe 7.0 spec
@ 2026-09-10 17:36 Logan Odell
  2026-09-10 17:50 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Logan Odell @ 2026-09-10 17:36 UTC (permalink / raw)
  To: karahmed, bhelgaas; +Cc: linux-pci, linux-kernel, Logan Odell

The revision and subsystem ID of the VFs for a given PF do not all have
to match per 7.5.1.1.5 and 7.5.1.2.3[1]. Read these values from the
config space instead of using cached values from VF0. Class codes and
subsystem vendor IDs do need to match per 7.5.1.1.6 and 7.5.1.2.3. Use
the PF's value instead of reading from the VF config space. Per
7.5.1.1.9, the header type for a VF should be 0, so hardcode that
assignment.

[1] https://members.pcisig.com/wg/PCI-SIG/document/previewpdf/22464

Fixes: cf0921bea66c ("PCI/IOV: Use VF0 cached config registers for other VFs")
Signed-off-by: Logan Odell <loganodell@google.com>
---
 drivers/pci/iov.c   | 25 -------------------------
 drivers/pci/pci.h   |  4 ----
 drivers/pci/probe.c | 14 +++++++++-----
 3 files changed, 9 insertions(+), 34 deletions(-)

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 9d408fb8ac25..9185934a900f 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -179,29 +179,6 @@ bool pci_iov_is_memory_decoding_enabled(struct pci_dev *dev)
 	return cmd & PCI_SRIOV_CTRL_MSE;
 }
 
-static void pci_read_vf_config_common(struct pci_dev *virtfn)
-{
-	struct pci_dev *physfn = virtfn->physfn;
-
-	/*
-	 * Some config registers are the same across all associated VFs.
-	 * Read them once from VF0 so we can skip reading them from the
-	 * other VFs.
-	 *
-	 * PCIe r4.0, sec 9.3.4.1, technically doesn't require all VFs to
-	 * have the same Revision ID and Subsystem ID, but we assume they
-	 * do.
-	 */
-	pci_read_config_dword(virtfn, PCI_CLASS_REVISION,
-			      &physfn->sriov->class);
-	pci_read_config_byte(virtfn, PCI_HEADER_TYPE,
-			     &physfn->sriov->hdr_type);
-	pci_read_config_word(virtfn, PCI_SUBSYSTEM_VENDOR_ID,
-			     &physfn->sriov->subsystem_vendor);
-	pci_read_config_word(virtfn, PCI_SUBSYSTEM_ID,
-			     &physfn->sriov->subsystem_device);
-}
-
 int pci_iov_sysfs_link(struct pci_dev *dev,
 		struct pci_dev *virtfn, int id)
 {
@@ -329,8 +306,6 @@ static struct pci_dev *pci_iov_scan_device(struct pci_dev *dev, int id,
 	virtfn->physfn = pci_dev_get(dev);
 	virtfn->no_command_memory = 1;
 
-	if (id == 0)
-		pci_read_vf_config_common(virtfn);
 
 	rc = pci_setup_device(virtfn);
 	if (rc) {
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index ba3c3fddddc2..5b3dd1adbf35 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -711,10 +711,6 @@ struct pci_sriov {
 	u16		driver_max_VFs;	/* Max num VFs driver supports */
 	struct pci_dev	*dev;		/* Lowest numbered PF */
 	struct pci_dev	*self;		/* This PF */
-	u32		class;		/* VF device */
-	u8		hdr_type;	/* VF header type */
-	u16		subsystem_vendor; /* VF subsystem vendor */
-	u16		subsystem_device; /* VF subsystem device */
 	resource_size_t	barsz[PCI_SRIOV_NUM_BARS];	/* VF BAR size */
 	u16		vf_rebar_cap;	/* VF Resizable BAR capability offset */
 	bool		drivers_autoprobe; /* Auto probing of VFs by driver */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 27008e2ea5af..693c07cf45ff 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1888,10 +1888,14 @@ int pci_cfg_space_size(struct pci_dev *dev)
 static u32 pci_class(struct pci_dev *dev)
 {
 	u32 class;
+	u8 rev;
 
 #ifdef CONFIG_PCI_IOV
-	if (dev->is_virtfn)
-		return dev->physfn->sriov->class;
+	if (dev->is_virtfn) {
+		if (pci_read_config_byte(dev, PCI_REVISION_ID, &rev))
+			rev = 0;
+		return (dev->physfn->class << 8) | rev;
+	}
 #endif
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
 	return class;
@@ -1901,8 +1905,8 @@ static void pci_subsystem_ids(struct pci_dev *dev, u16 *vendor, u16 *device)
 {
 #ifdef CONFIG_PCI_IOV
 	if (dev->is_virtfn) {
-		*vendor = dev->physfn->sriov->subsystem_vendor;
-		*device = dev->physfn->sriov->subsystem_device;
+		*vendor = dev->physfn->subsystem_vendor;
+		pci_read_config_word(dev, PCI_SUBSYSTEM_ID, device);
 		return;
 	}
 #endif
@@ -1916,7 +1920,7 @@ static u8 pci_hdr_type(struct pci_dev *dev)
 
 #ifdef CONFIG_PCI_IOV
 	if (dev->is_virtfn)
-		return dev->physfn->sriov->hdr_type;
+		return 0;
 #endif
 	pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
 	return hdr_type;
-- 
2.55.0.1007.g17ff1f9808-goog


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] PCI/IOV: Make VF config reads match PCIe 7.0 spec
  2026-09-10 17:36 [PATCH] PCI/IOV: Make VF config reads match PCIe 7.0 spec Logan Odell
@ 2026-09-10 17:50 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-09-10 17:50 UTC (permalink / raw)
  To: Logan Odell; +Cc: linux-pci

> The revision and subsystem ID of the VFs for a given PF do not all have
> to match per 7.5.1.1.5 and 7.5.1.2.3[1]. Read these values from the
> config space instead of using cached values from VF0. Class codes and
> subsystem vendor IDs do need to match per 7.5.1.1.6 and 7.5.1.2.3. Use
> the PF's value instead of reading from the VF config space. Per
> 7.5.1.1.9, the header type for a VF should be 0, so hardcode that
> assignment.
> 
> [1] https://members.pcisig.com/wg/PCI-SIG/document/previewpdf/22464
> 
> Fixes: cf0921bea66c ("PCI/IOV: Use VF0 cached config registers for other VFs")
> Signed-off-by: Logan Odell <loganodell@google.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260910173648.1304517-1-loganodell@google.com?part=1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-10 17:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 17:36 [PATCH] PCI/IOV: Make VF config reads match PCIe 7.0 spec Logan Odell
2026-09-10 17:50 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).