Blame SOURCES/0003-eal-fix-IOVA-mode-selection-as-VA-for-PCI-drivers.patch

eb2664
From 6054dd5fe1750b52381b9ee83858fe8db1765179 Mon Sep 17 00:00:00 2001
eb2664
From: David Marchand <david.marchand@redhat.com>
eb2664
Date: Mon, 22 Jul 2019 14:56:51 +0200
eb2664
Subject: [PATCH 3/4] eal: fix IOVA mode selection as VA for PCI drivers
eb2664
eb2664
The incriminated commit broke the use of RTE_PCI_DRV_IOVA_AS_VA which
eb2664
was intended to mean "driver only supports VA" but had been understood
eb2664
as "driver supports both PA and VA" by most net drivers and used to let
eb2664
dpdk processes to run as non root (which do not have access to physical
eb2664
addresses on recent kernels).
eb2664
eb2664
The check on physical addresses actually closed the gap for those
eb2664
drivers. We don't need to mark them with RTE_PCI_DRV_IOVA_AS_VA and this
eb2664
flag can retain its intended meaning.
eb2664
Document explicitly its meaning.
eb2664
eb2664
We can check that a driver requirement wrt to IOVA mode is fulfilled
eb2664
before trying to probe a device.
eb2664
eb2664
Finally, document the heuristic used to select the IOVA mode and hope
eb2664
that we won't break it again.
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: Jerin Jacob <jerinj@marvell.com>
eb2664
Tested-by: Jerin Jacob <jerinj@marvell.com>
eb2664
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
eb2664
eb2664
(cherry picked from commit b76fafb174d2cd5247c3573bb3d49444e195e760)
eb2664
Signed-off-by: David Marchand <david.marchand@redhat.com>
eb2664
eb2664
Conflicts:
eb2664
	drivers/net/avf/avf_ethdev.c
eb2664
	drivers/net/ice/ice_ethdev.c
eb2664
	drivers/net/mlx4/mlx4.c
eb2664
	drivers/net/mlx5/mlx5.c
eb2664
	drivers/net/octeontx2/otx2_ethdev.c
eb2664
	drivers/raw/ioat/ioat_rawdev.c
eb2664
---
eb2664
 doc/guides/prog_guide/env_abstraction_layer.rst | 31 +++++++++++++++++++++++++
eb2664
 drivers/bus/pci/linux/pci.c                     | 16 +++++--------
eb2664
 drivers/bus/pci/pci_common.c                    | 30 +++++++++++++++++++-----
eb2664
 drivers/bus/pci/rte_bus_pci.h                   |  4 ++--
eb2664
 drivers/net/atlantic/atl_ethdev.c               |  3 +--
eb2664
 drivers/net/avf/avf_ethdev.c                    |  3 +--
eb2664
 drivers/net/bnxt/bnxt_ethdev.c                  |  3 +--
eb2664
 drivers/net/e1000/em_ethdev.c                   |  3 +--
eb2664
 drivers/net/e1000/igb_ethdev.c                  |  5 ++--
eb2664
 drivers/net/enic/enic_ethdev.c                  |  3 +--
eb2664
 drivers/net/fm10k/fm10k_ethdev.c                |  3 +--
eb2664
 drivers/net/i40e/i40e_ethdev.c                  |  3 +--
eb2664
 drivers/net/i40e/i40e_ethdev_vf.c               |  2 +-
eb2664
 drivers/net/ixgbe/ixgbe_ethdev.c                |  5 ++--
eb2664
 drivers/net/nfp/nfp_net.c                       |  6 ++---
eb2664
 drivers/net/qede/qede_ethdev.c                  |  6 ++---
eb2664
 lib/librte_eal/common/eal_common_bus.c          | 30 +++++++++++++++++++++---
eb2664
 17 files changed, 106 insertions(+), 50 deletions(-)
eb2664
eb2664
diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst
eb2664
index 2bb77b0..a29a435 100644
eb2664
--- a/doc/guides/prog_guide/env_abstraction_layer.rst
eb2664
+++ b/doc/guides/prog_guide/env_abstraction_layer.rst
eb2664
@@ -344,6 +344,37 @@ Misc Functions
eb2664
 
eb2664
 Locks and atomic operations are per-architecture (i686 and x86_64).
eb2664
 
eb2664
+IOVA Mode Detection
eb2664
+~~~~~~~~~~~~~~~~~~~
eb2664
+
eb2664
+IOVA Mode is selected by considering what the current usable Devices on the
eb2664
+system require and/or support.
eb2664
+
eb2664
+Below is the 2-step heuristic for this choice.
eb2664
+
eb2664
+For the first step, EAL asks each bus its requirement in terms of IOVA mode
eb2664
+and decides on a preferred IOVA mode.
eb2664
+
eb2664
+- if all buses report RTE_IOVA_PA, then the preferred IOVA mode is RTE_IOVA_PA,
eb2664
+- if all buses report RTE_IOVA_VA, then the preferred IOVA mode is RTE_IOVA_VA,
eb2664
+- if all buses report RTE_IOVA_DC, no bus expressed a preferrence, then the
eb2664
+  preferred mode is RTE_IOVA_DC,
eb2664
+- if the buses disagree (at least one wants RTE_IOVA_PA and at least one wants
eb2664
+  RTE_IOVA_VA), then the preferred IOVA mode is RTE_IOVA_DC (see below with the
eb2664
+  check on Physical Addresses availability),
eb2664
+
eb2664
+The second step checks if the preferred mode complies with the Physical
eb2664
+Addresses availability since those are only available to root user in recent
eb2664
+kernels.
eb2664
+
eb2664
+- if the preferred mode is RTE_IOVA_PA but there is no access to Physical
eb2664
+  Addresses, then EAL init fails early, since later probing of the devices
eb2664
+  would fail anyway,
eb2664
+- if the preferred mode is RTE_IOVA_DC then based on the Physical Addresses
eb2664
+  availability, the preferred mode is adjusted to RTE_IOVA_PA or RTE_IOVA_VA.
eb2664
+  In the case when the buses had disagreed on the IOVA Mode at the first step,
eb2664
+  part of the buses won't work because of this decision.
eb2664
+
eb2664
 IOVA Mode Configuration
eb2664
 ~~~~~~~~~~~~~~~~~~~~~~~
eb2664
 
eb2664
diff --git a/drivers/bus/pci/linux/pci.c b/drivers/bus/pci/linux/pci.c
eb2664
index b12f10a..1a2f99b 100644
eb2664
--- a/drivers/bus/pci/linux/pci.c
eb2664
+++ b/drivers/bus/pci/linux/pci.c
eb2664
@@ -578,12 +578,10 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
eb2664
 			else
eb2664
 				is_vfio_noiommu_enabled = 0;
eb2664
 		}
eb2664
-		if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) == 0) {
eb2664
+		if (is_vfio_noiommu_enabled != 0)
eb2664
 			iova_mode = RTE_IOVA_PA;
eb2664
-		} else if (is_vfio_noiommu_enabled != 0) {
eb2664
-			RTE_LOG(DEBUG, EAL, "Forcing to 'PA', vfio-noiommu mode configured\n");
eb2664
-			iova_mode = RTE_IOVA_PA;
eb2664
-		}
eb2664
+		else if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) != 0)
eb2664
+			iova_mode = RTE_IOVA_VA;
eb2664
 #endif
eb2664
 		break;
eb2664
 	}
eb2664
@@ -594,8 +592,8 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
eb2664
 		break;
eb2664
 
eb2664
 	default:
eb2664
-		RTE_LOG(DEBUG, EAL, "Unsupported kernel driver? Defaulting to IOVA as 'PA'\n");
eb2664
-		iova_mode = RTE_IOVA_PA;
eb2664
+		if ((pdrv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) != 0)
eb2664
+			iova_mode = RTE_IOVA_VA;
eb2664
 		break;
eb2664
 	}
eb2664
 
eb2664
@@ -607,10 +605,8 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
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
-			RTE_LOG(DEBUG, EAL, "Forcing to 'PA', IOMMU does not support IOVA as 'VA'\n");
eb2664
+		if (iommu_no_va != 0)
eb2664
 			iova_mode = RTE_IOVA_PA;
eb2664
-		}
eb2664
 	}
eb2664
 	return iova_mode;
eb2664
 }
eb2664
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
eb2664
index b8cc6d3..ee5d321 100644
eb2664
--- a/drivers/bus/pci/pci_common.c
eb2664
+++ b/drivers/bus/pci/pci_common.c
eb2664
@@ -169,8 +169,22 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
eb2664
 	 * This needs to be before rte_pci_map_device(), as it enables to use
eb2664
 	 * driver flags for adjusting configuration.
eb2664
 	 */
eb2664
-	if (!already_probed)
eb2664
+	if (!already_probed) {
eb2664
+		enum rte_iova_mode dev_iova_mode;
eb2664
+		enum rte_iova_mode iova_mode;
eb2664
+
eb2664
+		dev_iova_mode = pci_device_iova_mode(dr, dev);
eb2664
+		iova_mode = rte_eal_iova_mode();
eb2664
+		if (dev_iova_mode != RTE_IOVA_DC &&
eb2664
+		    dev_iova_mode != iova_mode) {
eb2664
+			RTE_LOG(ERR, EAL, "  Expecting '%s' IOVA mode but current mode is '%s', not initializing\n",
eb2664
+				dev_iova_mode == RTE_IOVA_PA ? "PA" : "VA",
eb2664
+				iova_mode == RTE_IOVA_PA ? "PA" : "VA");
eb2664
+			return -EINVAL;
eb2664
+		}
eb2664
+
eb2664
 		dev->driver = dr;
eb2664
+	}
eb2664
 
eb2664
 	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
eb2664
 		/* map resources for devices that use igb_uio */
eb2664
@@ -583,12 +597,16 @@ rte_pci_get_iommu_class(void)
eb2664
 				devices_want_va = true;
eb2664
 		}
eb2664
 	}
eb2664
-	if (devices_want_pa) {
eb2664
-		iova_mode = RTE_IOVA_PA;
eb2664
-		if (devices_want_va)
eb2664
-			RTE_LOG(WARNING, EAL, "Some devices want 'VA' but forcing 'PA' because other devices want it\n");
eb2664
-	} else if (devices_want_va) {
eb2664
+	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
+	} else {
eb2664
+		iova_mode = RTE_IOVA_DC;
eb2664
+		if (devices_want_va) {
eb2664
+			RTE_LOG(WARNING, EAL, "Some devices want 'VA' but forcing 'DC' because other devices want 'PA'.\n");
eb2664
+			RTE_LOG(WARNING, EAL, "Depending on the final decision by the EAL, not all devices may be able to initialize.\n");
eb2664
+		}
eb2664
 	}
eb2664
 	return iova_mode;
eb2664
 }
eb2664
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
eb2664
index f0d6d81..f0fa3a1 100644
eb2664
--- a/drivers/bus/pci/rte_bus_pci.h
eb2664
+++ b/drivers/bus/pci/rte_bus_pci.h
eb2664
@@ -147,8 +147,8 @@ struct rte_pci_bus {
eb2664
 #define RTE_PCI_DRV_INTR_RMV 0x0010
eb2664
 /** Device driver needs to keep mapped resources if unsupported dev detected */
eb2664
 #define RTE_PCI_DRV_KEEP_MAPPED_RES 0x0020
eb2664
-/** Device driver supports IOVA as VA */
eb2664
-#define RTE_PCI_DRV_IOVA_AS_VA 0X0040
eb2664
+/** Device driver only supports IOVA as VA and cannot work with IOVA as PA */
eb2664
+#define RTE_PCI_DRV_IOVA_AS_VA 0x0040
eb2664
 
eb2664
 /**
eb2664
  * Map the PCI device resources in user space virtual memory address
eb2664
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
eb2664
index 2d05bb4..d3b4b67 100644
eb2664
--- a/drivers/net/atlantic/atl_ethdev.c
eb2664
+++ b/drivers/net/atlantic/atl_ethdev.c
eb2664
@@ -155,8 +155,7 @@ static const struct rte_pci_id pci_id_atl_map[] = {
eb2664
 
eb2664
 static struct rte_pci_driver rte_atl_pmd = {
eb2664
 	.id_table = pci_id_atl_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_atl_pci_probe,
eb2664
 	.remove = eth_atl_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/avf/avf_ethdev.c b/drivers/net/avf/avf_ethdev.c
eb2664
index 4dc61d9..6dde939 100644
eb2664
--- a/drivers/net/avf/avf_ethdev.c
eb2664
+++ b/drivers/net/avf/avf_ethdev.c
eb2664
@@ -1329,8 +1329,7 @@ static int eth_avf_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 /* Adaptive virtual function driver struct */
eb2664
 static struct rte_pci_driver rte_avf_pmd = {
eb2664
 	.id_table = pci_id_avf_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_avf_pci_probe,
eb2664
 	.remove = eth_avf_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
eb2664
index e26b9e3..7e764e0 100644
eb2664
--- a/drivers/net/bnxt/bnxt_ethdev.c
eb2664
+++ b/drivers/net/bnxt/bnxt_ethdev.c
eb2664
@@ -3545,8 +3545,7 @@ static int bnxt_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver bnxt_rte_pmd = {
eb2664
 	.id_table = bnxt_pci_id_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING |
eb2664
-		RTE_PCI_DRV_INTR_LSC | RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = bnxt_pci_probe,
eb2664
 	.remove = bnxt_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
eb2664
index 8230824..bdee7bc 100644
eb2664
--- a/drivers/net/e1000/em_ethdev.c
eb2664
+++ b/drivers/net/e1000/em_ethdev.c
eb2664
@@ -351,8 +351,7 @@ static int eth_em_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_em_pmd = {
eb2664
 	.id_table = pci_id_em_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_em_pci_probe,
eb2664
 	.remove = eth_em_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
eb2664
index 87c9aed..7bd0c29 100644
eb2664
--- a/drivers/net/e1000/igb_ethdev.c
eb2664
+++ b/drivers/net/e1000/igb_ethdev.c
eb2664
@@ -1113,8 +1113,7 @@ static int eth_igb_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_igb_pmd = {
eb2664
 	.id_table = pci_id_igb_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_igb_pci_probe,
eb2664
 	.remove = eth_igb_pci_remove,
eb2664
 };
eb2664
@@ -1137,7 +1136,7 @@ static int eth_igbvf_pci_remove(struct rte_pci_device *pci_dev)
eb2664
  */
eb2664
 static struct rte_pci_driver rte_igbvf_pmd = {
eb2664
 	.id_table = pci_id_igbvf_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
eb2664
 	.probe = eth_igbvf_pci_probe,
eb2664
 	.remove = eth_igbvf_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
eb2664
index 996bb55..1b8d74d 100644
eb2664
--- a/drivers/net/enic/enic_ethdev.c
eb2664
+++ b/drivers/net/enic/enic_ethdev.c
eb2664
@@ -1077,8 +1077,7 @@ static int eth_enic_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_enic_pmd = {
eb2664
 	.id_table = pci_id_enic_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_enic_pci_probe,
eb2664
 	.remove = eth_enic_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
eb2664
index caf4d1b..98583c6 100644
eb2664
--- a/drivers/net/fm10k/fm10k_ethdev.c
eb2664
+++ b/drivers/net/fm10k/fm10k_ethdev.c
eb2664
@@ -3258,8 +3258,7 @@ static const struct rte_pci_id pci_id_fm10k_map[] = {
eb2664
 
eb2664
 static struct rte_pci_driver rte_pmd_fm10k = {
eb2664
 	.id_table = pci_id_fm10k_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_fm10k_pci_probe,
eb2664
 	.remove = eth_fm10k_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
eb2664
index df6eaec..c8d01ac 100644
eb2664
--- a/drivers/net/i40e/i40e_ethdev.c
eb2664
+++ b/drivers/net/i40e/i40e_ethdev.c
eb2664
@@ -699,8 +699,7 @@ static int eth_i40e_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_i40e_pmd = {
eb2664
 	.id_table = pci_id_i40e_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_i40e_pci_probe,
eb2664
 	.remove = eth_i40e_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
eb2664
index 551f6fa..58c1c36 100644
eb2664
--- a/drivers/net/i40e/i40e_ethdev_vf.c
eb2664
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
eb2664
@@ -1510,7 +1510,7 @@ static int eth_i40evf_pci_remove(struct rte_pci_device *pci_dev)
eb2664
  */
eb2664
 static struct rte_pci_driver rte_i40evf_pmd = {
eb2664
 	.id_table = pci_id_i40evf_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
eb2664
 	.probe = eth_i40evf_pci_probe,
eb2664
 	.remove = eth_i40evf_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
eb2664
index e9533e5..fca15be 100644
eb2664
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
eb2664
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
eb2664
@@ -1807,8 +1807,7 @@ static int eth_ixgbe_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_ixgbe_pmd = {
eb2664
 	.id_table = pci_id_ixgbe_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_ixgbe_pci_probe,
eb2664
 	.remove = eth_ixgbe_pci_remove,
eb2664
 };
eb2664
@@ -1830,7 +1829,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_device *pci_dev)
eb2664
  */
eb2664
 static struct rte_pci_driver rte_ixgbevf_pmd = {
eb2664
 	.id_table = pci_id_ixgbevf_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
eb2664
 	.probe = eth_ixgbevf_pci_probe,
eb2664
 	.remove = eth_ixgbevf_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
eb2664
index 68c853c..ddd9d9f 100644
eb2664
--- a/drivers/net/nfp/nfp_net.c
eb2664
+++ b/drivers/net/nfp/nfp_net.c
eb2664
@@ -3297,16 +3297,14 @@ static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_nfp_net_pf_pmd = {
eb2664
 	.id_table = pci_id_nfp_pf_net_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = nfp_pf_pci_probe,
eb2664
 	.remove = eth_nfp_pci_remove,
eb2664
 };
eb2664
 
eb2664
 static struct rte_pci_driver rte_nfp_net_vf_pmd = {
eb2664
 	.id_table = pci_id_nfp_vf_net_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = eth_nfp_pci_probe,
eb2664
 	.remove = eth_nfp_pci_remove,
eb2664
 };
eb2664
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
eb2664
index 0b2f305..518673d 100644
eb2664
--- a/drivers/net/qede/qede_ethdev.c
eb2664
+++ b/drivers/net/qede/qede_ethdev.c
eb2664
@@ -2735,8 +2735,7 @@ static int qedevf_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_qedevf_pmd = {
eb2664
 	.id_table = pci_id_qedevf_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = qedevf_eth_dev_pci_probe,
eb2664
 	.remove = qedevf_eth_dev_pci_remove,
eb2664
 };
eb2664
@@ -2755,8 +2754,7 @@ static int qede_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
eb2664
 
eb2664
 static struct rte_pci_driver rte_qede_pmd = {
eb2664
 	.id_table = pci_id_qede_map,
eb2664
-	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
eb2664
-		     RTE_PCI_DRV_IOVA_AS_VA,
eb2664
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
eb2664
 	.probe = qede_eth_dev_pci_probe,
eb2664
 	.remove = qede_eth_dev_pci_remove,
eb2664
 };
eb2664
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
eb2664
index 77f1be1..0459048 100644
eb2664
--- a/lib/librte_eal/common/eal_common_bus.c
eb2664
+++ b/lib/librte_eal/common/eal_common_bus.c
eb2664
@@ -228,13 +228,37 @@ rte_bus_find_by_device_name(const char *str)
eb2664
 enum rte_iova_mode
eb2664
 rte_bus_get_iommu_class(void)
eb2664
 {
eb2664
-	int mode = RTE_IOVA_DC;
eb2664
+	enum rte_iova_mode mode = RTE_IOVA_DC;
eb2664
+	bool buses_want_va = false;
eb2664
+	bool buses_want_pa = false;
eb2664
 	struct rte_bus *bus;
eb2664
 
eb2664
 	TAILQ_FOREACH(bus, &rte_bus_list, next) {
eb2664
+		enum rte_iova_mode bus_iova_mode;
eb2664
 
eb2664
-		if (bus->get_iommu_class)
eb2664
-			mode |= bus->get_iommu_class();
eb2664
+		if (bus->get_iommu_class == NULL)
eb2664
+			continue;
eb2664
+
eb2664
+		bus_iova_mode = bus->get_iommu_class();
eb2664
+		RTE_LOG(DEBUG, EAL, "Bus %s wants IOVA as '%s'\n",
eb2664
+			bus->name,
eb2664
+			bus_iova_mode == RTE_IOVA_DC ? "DC" :
eb2664
+			(bus_iova_mode == RTE_IOVA_PA ? "PA" : "VA"));
eb2664
+		if (bus_iova_mode == RTE_IOVA_PA)
eb2664
+			buses_want_pa = true;
eb2664
+		else if (bus_iova_mode == RTE_IOVA_VA)
eb2664
+			buses_want_va = true;
eb2664
+	}
eb2664
+	if (buses_want_va && !buses_want_pa) {
eb2664
+		mode = RTE_IOVA_VA;
eb2664
+	} else if (buses_want_pa && !buses_want_va) {
eb2664
+		mode = RTE_IOVA_PA;
eb2664
+	} else {
eb2664
+		mode = RTE_IOVA_DC;
eb2664
+		if (buses_want_va) {
eb2664
+			RTE_LOG(WARNING, EAL, "Some buses want 'VA' but forcing 'DC' because other buses want 'PA'.\n");
eb2664
+			RTE_LOG(WARNING, EAL, "Depending on the final decision by the EAL, not all buses may be able to initialize.\n");
eb2664
+		}
eb2664
 	}
eb2664
 
eb2664
 	return mode;
eb2664
-- 
eb2664
1.8.3.1
eb2664