Blame SOURCES/0004-bus-pci-always-check-IOMMU-capabilities.patch

eb2664
From 3729b66e42e1a11bdd3ee080a86c07adede8b3b2 Mon Sep 17 00:00:00 2001
eb2664
From: David Marchand <david.marchand@redhat.com>
eb2664
Date: Mon, 5 Aug 2019 08:23:26 +0200
eb2664
Subject: [PATCH 4/4] bus/pci: always check IOMMU capabilities
eb2664
eb2664
IOMMU capabilities won't change and must be checked even if no PCI device
eb2664
seem to be supported yet when EAL initialised.
eb2664
eb2664
This is to accommodate with SPDK that registers its drivers after
eb2664
rte_eal_init(), especially on PPC platform where the IOMMU does not
eb2664
support VA.
eb2664
eb2664
Fixes: 703458e19c16 ("bus/pci: consider only usable devices for IOVA mode")
eb2664
eb2664
Signed-off-by: David Marchand <david.marchand@redhat.com>
eb2664
Reviewed-by: David Christensen <drc@linux.vnet.ibm.com>
eb2664
Acked-by: Jerin Jacob <jerinj@marvell.com>
eb2664
Tested-by: Jerin Jacob <jerinj@marvell.com>
eb2664
Tested-by: Takeshi Yoshimura <tyos@jp.ibm.com>
eb2664
eb2664
(cherry picked from commit 66d3724b2c87e6fcdf3851ca191683696a91b901)
eb2664
Signed-off-by: David Marchand <david.marchand@redhat.com>
eb2664
---
eb2664
 drivers/bus/pci/bsd/pci.c    |  6 ++++++
eb2664
 drivers/bus/pci/linux/pci.c  | 25 ++++++-------------------
eb2664
 drivers/bus/pci/pci_common.c | 16 +++++++++++++++-
eb2664
 drivers/bus/pci/private.h    |  5 ++++-
eb2664
 4 files changed, 31 insertions(+), 21 deletions(-)
eb2664
eb2664
diff --git a/drivers/bus/pci/bsd/pci.c b/drivers/bus/pci/bsd/pci.c
eb2664
index 0f23f12..42f4353 100644
eb2664
--- a/drivers/bus/pci/bsd/pci.c
eb2664
+++ b/drivers/bus/pci/bsd/pci.c
eb2664
@@ -376,6 +376,12 @@ error:
eb2664
 	return -1;
eb2664
 }
eb2664
 
eb2664
+bool
eb2664
+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
eb2664
+{
eb2664
+	return false;
eb2664
+}
eb2664
+
eb2664
 enum rte_iova_mode
eb2664
 pci_device_iova_mode(const struct rte_pci_driver *pdrv __rte_unused,
eb2664
 		     const struct rte_pci_device *pdev)
eb2664
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
eb2664
index 1a2f99b..6a6f78b 100644
eb2664
--- a/drivers/bus/pci/linux/pci.c
eb2664
+++ b/drivers/bus/pci/linux/pci.c
eb2664
@@ -498,8 +498,8 @@ error:
eb2664
 }
eb2664
 
eb2664
 #if defined(RTE_ARCH_X86)
eb2664
-static bool
eb2664
-pci_one_device_iommu_support_va(const struct rte_pci_device *dev)
eb2664
+bool
eb2664
+pci_device_iommu_support_va(const struct rte_pci_device *dev)
eb2664
 {
eb2664
 #define VTD_CAP_MGAW_SHIFT	16
eb2664
 #define VTD_CAP_MGAW_MASK	(0x3fULL << VTD_CAP_MGAW_SHIFT)
eb2664
@@ -547,14 +547,14 @@ pci_one_device_iommu_support_va(const struct rte_pci_device *dev)
eb2664
 	return true;
eb2664
 }
eb2664
 #elif defined(RTE_ARCH_PPC_64)
eb2664
-static bool
eb2664
-pci_one_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
eb2664
+bool
eb2664
+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
eb2664
 {
eb2664
 	return false;
eb2664
 }
eb2664
 #else
eb2664
-static bool
eb2664
-pci_one_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
eb2664
+bool
eb2664
+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
eb2664
 {
eb2664
 	return true;
eb2664
 }
eb2664
@@ -565,7 +565,6 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
eb2664
 		     const struct rte_pci_device *pdev)
eb2664
 {
eb2664
 	enum rte_iova_mode iova_mode = RTE_IOVA_DC;
eb2664
-	static int iommu_no_va = -1;
eb2664
 
eb2664
 	switch (pdev->kdrv) {
eb2664
 	case RTE_KDRV_VFIO: {
eb2664
@@ -596,18 +595,6 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
eb2664
 			iova_mode = RTE_IOVA_VA;
eb2664
 		break;
eb2664
 	}
eb2664
-
eb2664
-	if (iova_mode != RTE_IOVA_PA) {
eb2664
-		/*
eb2664
-		 * We can check this only once, because the IOMMU hardware is
eb2664
-		 * the same for all of them.
eb2664
-		 */
eb2664
-		if (iommu_no_va == -1)
eb2664
-			iommu_no_va = pci_one_device_iommu_support_va(pdev)
eb2664
-					? 0 : 1;
eb2664
-		if (iommu_no_va != 0)
eb2664
-			iova_mode = RTE_IOVA_PA;
eb2664
-	}
eb2664
 	return iova_mode;
eb2664
 }
eb2664
 
eb2664
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
eb2664
index ee5d321..9e7106f 100644
eb2664
--- a/drivers/bus/pci/pci_common.c
eb2664
+++ b/drivers/bus/pci/pci_common.c
eb2664
@@ -570,8 +570,16 @@ rte_pci_get_iommu_class(void)
eb2664
 	const struct rte_pci_driver *drv;
eb2664
 	bool devices_want_va = false;
eb2664
 	bool devices_want_pa = false;
eb2664
+	int iommu_no_va = -1;
eb2664
 
eb2664
 	FOREACH_DEVICE_ON_PCIBUS(dev) {
eb2664
+		/*
eb2664
+		 * We can check this only once, because the IOMMU hardware is
eb2664
+		 * the same for all of them.
eb2664
+		 */
eb2664
+		if (iommu_no_va == -1)
eb2664
+			iommu_no_va = pci_device_iommu_support_va(dev)
eb2664
+					? 0 : 1;
eb2664
 		if (pci_ignore_device(dev))
eb2664
 			continue;
eb2664
 		if (dev->kdrv == RTE_KDRV_UNKNOWN ||
eb2664
@@ -597,7 +605,13 @@ rte_pci_get_iommu_class(void)
eb2664
 				devices_want_va = true;
eb2664
 		}
eb2664
 	}
eb2664
-	if (devices_want_va && !devices_want_pa) {
eb2664
+	if (iommu_no_va == 1) {
eb2664
+		iova_mode = RTE_IOVA_PA;
eb2664
+		if (devices_want_va) {
eb2664
+			RTE_LOG(WARNING, EAL, "Some devices want 'VA' but IOMMU does not support 'VA'.\n");
eb2664
+			RTE_LOG(WARNING, EAL, "The devices that want 'VA' won't initialize.\n");
eb2664
+		}
eb2664
+	} else if (devices_want_va && !devices_want_pa) {
eb2664
 		iova_mode = RTE_IOVA_VA;
eb2664
 	} else if (devices_want_pa && !devices_want_va) {
eb2664
 		iova_mode = RTE_IOVA_PA;
eb2664
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
eb2664
index 8a55240..a205d4d 100644
eb2664
--- a/drivers/bus/pci/private.h
eb2664
+++ b/drivers/bus/pci/private.h
eb2664
@@ -173,9 +173,12 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
eb2664
 	      const struct rte_pci_device *pci_dev);
eb2664
 
eb2664
 /**
eb2664
- * OS specific callback for rte_pci_get_iommu_class
eb2664
+ * OS specific callbacks for rte_pci_get_iommu_class
eb2664
  *
eb2664
  */
eb2664
+bool
eb2664
+pci_device_iommu_support_va(const struct rte_pci_device *dev);
eb2664
+
eb2664
 enum rte_iova_mode
eb2664
 pci_device_iova_mode(const struct rte_pci_driver *pci_drv,
eb2664
 		     const struct rte_pci_device *pci_dev);
eb2664
-- 
eb2664
1.8.3.1
eb2664