|
|
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 |
|