Blame SOURCES/0001-mem-add-function-for-checking-memsegs-IOVAs-addresse.patch

dd2e6b
From 3a80bc50c949760f7159b59ba30a70f95c223448 Mon Sep 17 00:00:00 2001
dd2e6b
From: Alejandro Lucero <alejandro.lucero@netronome.com>
dd2e6b
Date: Tue, 10 Jul 2018 18:25:48 +0100
dd2e6b
Subject: [1/5] mem: add function for checking memsegs IOVAs addresses
dd2e6b
dd2e6b
A device can suffer addressing limitations. This functions checks
dd2e6b
memsegs have iovas within the supported range based on dma mask.
dd2e6b
dd2e6b
PMD should use this during initialization if supported devices
dd2e6b
suffer addressing limitations, returning an error if this function
dd2e6b
returns memsegs out of range.
dd2e6b
dd2e6b
Another potential usage is for emulated IOMMU hardware with addressing
dd2e6b
limitations.
dd2e6b
dd2e6b
Applicable to v17.11.3 only.
dd2e6b
dd2e6b
Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
dd2e6b
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
dd2e6b
Acked-by: Eelco Chaudron <echaudro@redhat.com>
dd2e6b
---
dd2e6b
 lib/librte_eal/common/eal_common_memory.c  | 48 ++++++++++++++++++++++++++++++
dd2e6b
 lib/librte_eal/common/include/rte_memory.h |  3 ++
dd2e6b
 lib/librte_eal/rte_eal_version.map         |  1 +
dd2e6b
 3 files changed, 52 insertions(+)
dd2e6b
dd2e6b
diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c
dd2e6b
index fc6c44d..00ab393 100644
dd2e6b
--- a/lib/librte_eal/common/eal_common_memory.c
dd2e6b
+++ b/lib/librte_eal/common/eal_common_memory.c
dd2e6b
@@ -109,6 +109,54 @@ rte_dump_physmem_layout(FILE *f)
dd2e6b
 	}
dd2e6b
 }
dd2e6b
 
dd2e6b
+#if defined(RTE_ARCH_X86)
dd2e6b
+#define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */
dd2e6b
+#define MAX_DMA_MASK_BITS X86_VA_WIDTH
dd2e6b
+#else
dd2e6b
+/* 63 bits is good enough for a sanity check */
dd2e6b
+#define MAX_DMA_MASK_BITS 63
dd2e6b
+#endif
dd2e6b
+
dd2e6b
+/* check memseg iovas are within the required range based on dma mask */
dd2e6b
+int
dd2e6b
+rte_eal_check_dma_mask(uint8_t maskbits)
dd2e6b
+{
dd2e6b
+
dd2e6b
+	const struct rte_mem_config *mcfg;
dd2e6b
+	uint64_t mask;
dd2e6b
+	int i;
dd2e6b
+
dd2e6b
+	/* sanity check */
dd2e6b
+	if (maskbits > MAX_DMA_MASK_BITS) {
dd2e6b
+		RTE_LOG(INFO, EAL, "wrong dma mask size %u (Max: %u)\n",
dd2e6b
+				   maskbits, MAX_DMA_MASK_BITS);
dd2e6b
+		return -1;
dd2e6b
+	}
dd2e6b
+
dd2e6b
+	/* create dma mask */
dd2e6b
+	mask = ~((1ULL << maskbits) - 1);
dd2e6b
+
dd2e6b
+	/* get pointer to global configuration */
dd2e6b
+	mcfg = rte_eal_get_configuration()->mem_config;
dd2e6b
+
dd2e6b
+	for (i = 0; i < RTE_MAX_MEMSEG; i++) {
dd2e6b
+		if (mcfg->memseg[i].addr == NULL)
dd2e6b
+			break;
dd2e6b
+
dd2e6b
+		if (mcfg->memseg[i].iova & mask) {
dd2e6b
+			RTE_LOG(INFO, EAL,
dd2e6b
+				"memseg[%d] iova %"PRIx64" out of range:\n",
dd2e6b
+				i, mcfg->memseg[i].iova);
dd2e6b
+
dd2e6b
+			RTE_LOG(INFO, EAL, "\tusing dma mask %"PRIx64"\n",
dd2e6b
+				mask);
dd2e6b
+			return -1;
dd2e6b
+		}
dd2e6b
+	}
dd2e6b
+
dd2e6b
+	return 0;
dd2e6b
+}
dd2e6b
+
dd2e6b
 /* return the number of memory channels */
dd2e6b
 unsigned rte_memory_get_nchannel(void)
dd2e6b
 {
dd2e6b
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
dd2e6b
index 80a8fc0..b2a0168 100644
dd2e6b
--- a/lib/librte_eal/common/include/rte_memory.h
dd2e6b
+++ b/lib/librte_eal/common/include/rte_memory.h
dd2e6b
@@ -209,6 +209,9 @@ unsigned rte_memory_get_nchannel(void);
dd2e6b
  */
dd2e6b
 unsigned rte_memory_get_nrank(void);
dd2e6b
 
dd2e6b
+/* check memsegs iovas are within a range based on dma mask */
dd2e6b
+int rte_eal_check_dma_mask(uint8_t maskbits);
dd2e6b
+
dd2e6b
 /**
dd2e6b
  * Drivers based on uio will not load unless physical
dd2e6b
  * addresses are obtainable. It is only possible to get
dd2e6b
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
dd2e6b
index f4f46c1..aa6cf87 100644
dd2e6b
--- a/lib/librte_eal/rte_eal_version.map
dd2e6b
+++ b/lib/librte_eal/rte_eal_version.map
dd2e6b
@@ -184,6 +184,7 @@ DPDK_17.11 {
dd2e6b
 
dd2e6b
 	rte_eal_create_uio_dev;
dd2e6b
 	rte_bus_get_iommu_class;
dd2e6b
+	rte_eal_check_dma_mask;
dd2e6b
 	rte_eal_has_pci;
dd2e6b
 	rte_eal_iova_mode;
dd2e6b
 	rte_eal_mbuf_default_mempool_ops;
dd2e6b
-- 
dd2e6b
1.8.3.1
dd2e6b