[RFC PATCH] pci: add hook for architectures to disble SR-IOV at runtime

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We have observed the following on Power systems with SR-IOV capable
adapters:

lpfc 0002:01:00.0: device not available because of BAR 7 [0x000000-0x00ffff] collisions

The issue is that on Power systems, PCI BARs cannot be remapped and VF
BARs might have values that collide. As far as I can tell, the current
SR-IOV code cannot be supported on Power and so it seems like we could
provide a hook for an architecture that might set CONFIG_PCI_IOV to
disable SR-IOV support (potentially at run-time).

I defined a weak version of this function that returns true if
CONFIG_PCI_IOV is set (which I think should reflect the current setup
that CONFIG_PCI_IOV represents an unconditional support of SR-IOV) and
false otherwise. The only architecture that implements the hook is
powerpc, which uses a machine callback to decide if a platform supports
SR-IOV or not. I only defined one such callback, for the pseries
platform, and return false unconditionally there.

This was tested to not result in BAR collisions against
3.1.0-rc9-00012-g6367f17.

Signed-off-by: Nishanth Aravamudan <nacc@xxxxxxxxxx>

---

Bjorn, FWIW, this also fixes the issue I was seeing, independent of the
other change, as now the BARs aren't even touched. This is probably a
"safer" change, too, as it doesn't assume that the path I was changing
in the other patches was the only one to be touched for SR-IOV.


diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 47cacdd..c11618e 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -211,6 +211,8 @@ struct machdep_calls {
 	 * allow assignment/enabling of the device. */
 	int  (*pcibios_enable_device_hook)(struct pci_dev *);
 
+	bool (*pcibios_supports_sriov)(struct pci_dev *);
+
 	/* Called to shutdown machine specific hardware not already controlled
 	 * by other drivers.
 	 */
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 49c3de5..03dd50f 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -192,6 +192,8 @@ extern pgprot_t	pci_phys_mem_access_prot(struct file *file,
 					 unsigned long size,
 					 pgprot_t prot);
 
+extern bool pcibios_supports_sriov(struct pci_dev *);
+
 #define HAVE_ARCH_PCI_RESOURCE_TO_USER
 extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
 				 const struct resource *rsrc,
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 32656f1..aefc8a7 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1732,6 +1732,17 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
 		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 }
 
+bool pcibios_supports_sriov(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCI_IOV
+	if (ppc_md.pcibios_supports_sriov)
+		return ppc_md.pcibios_supports_sriov(dev);
+	return true;
+#else
+	return false;
+#endif
+}
+
 static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
 {
 	int i, class = dev->class >> 8;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 2c6ded2..3d75308 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -76,6 +76,11 @@ void __init pSeries_final_fixup(void)
 	pci_addr_cache_build();
 }
 
+bool pSeries_supports_sriov(struct pci_dev *dev)
+{
+	return false;
+}
+
 /*
  * Assume the winbond 82c105 is the IDE controller on a
  * p610/p615/p630. We should probably be more careful in case
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 24c7162..9aeb176 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -43,6 +43,7 @@ static inline void setup_kexec_cpu_down_mpic(void) { }
 #endif
 
 extern void pSeries_final_fixup(void);
+extern bool pSeries_supports_sriov(struct pci_dev *);
 
 /* Poweron flag used for enabling auto ups restart */
 extern unsigned long rtas_poweron_auto;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 0969fd9..f0e9f8f 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -697,6 +697,10 @@ static void pSeries_power_off(void)
 
 #ifndef CONFIG_PCI
 void pSeries_final_fixup(void) { }
+bool pSeries_supports_sriov(struct pci_dev *)
+{
+	return false;
+}
 #endif
 
 define_machine(pseries) {
@@ -707,6 +711,7 @@ define_machine(pseries) {
 	.show_cpuinfo		= pSeries_show_cpuinfo,
 	.log_error		= pSeries_log_error,
 	.pcibios_fixup		= pSeries_final_fixup,
+	.pcibios_supports_sriov	= pSeries_supports_sriov,
 	.pci_probe_mode		= pSeries_pci_probe_mode,
 	.restart		= rtas_restart,
 	.power_off		= pSeries_power_off,
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 42fae47..8f800bd 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -557,6 +557,9 @@ int pci_iov_init(struct pci_dev *dev)
 {
 	int pos;
 
+	if (!pcibios_supports_sriov(dev))
+		return -ENODEV;
+
 	if (!pci_is_pcie(dev))
 		return -ENODEV;
 
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e9651f0..22c7416 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3330,6 +3330,15 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 	return 0;
 }
 
+bool __attribute__((weak)) pcibios_supports_sriov(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCI_IOV
+	return true;
+#else
+	return false;
+#endif
+}
+
 /* Some architectures require additional programming to enable VGA */
 static arch_set_vga_state_t arch_set_vga_state;

-- 
Nishanth Aravamudan <nacc@xxxxxxxxxx>
IBM Linux Technology Center

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux