physmem: keep physmem VA in 39-bit address space on x86_64 54/17754/3
authorDamjan Marion <damarion@cisco.com>
Thu, 21 Feb 2019 13:44:59 +0000 (14:44 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 21 Feb 2019 17:35:35 +0000 (17:35 +0000)
Some x86 CPUs have IOMMU capable dealing only with 39-bit address space
This patch also adds option to specify physmem base address from
startup.conf

Change-Id: I9e8abd26efb60e9c4ad54c035fb1751a4a61f4dc
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vlib/physmem.c
src/vlib/physmem.h
src/vppinfra/pmalloc.c
src/vppinfra/pmalloc.h
src/vppinfra/test_pmalloc.c

index 21fe44f..64920e1 100755 (executable)
 #include <vlib/pci/pci.h>
 #include <vlib/linux/vfio.h>
 
+#ifdef __x86_64__
+/* we keep physmem in low 38 bits of VA address space as some
+   IOMMU implamentation cannot map above that range */
+#define VLIB_PHYSMEM_DEFAULT_BASE_ADDDR                (1ULL << 36)
+#else
+/* let kernel decide */
+#define VLIB_PHYSMEM_DEFAULT_BASE_ADDDR                0
+#endif
+
 clib_error_t *
 vlib_physmem_shared_map_create (vlib_main_t * vm, char *name, uword size,
                                u32 log2_page_sz, u32 numa_node,
@@ -102,7 +111,11 @@ vlib_physmem_init (vlib_main_t * vm)
                              CLIB_CACHE_LINE_BYTES);
   memset (p, 0, sizeof (clib_pmalloc_main_t));
   vpm->pmalloc_main = (clib_pmalloc_main_t *) p;
-  clib_pmalloc_init (vpm->pmalloc_main, 0);
+
+  if (vpm->base_addr == 0)
+    vpm->base_addr = VLIB_PHYSMEM_DEFAULT_BASE_ADDDR;
+
+  clib_pmalloc_init (vpm->pmalloc_main, vpm->base_addr, 0);
 
   return error;
 }
@@ -151,6 +164,25 @@ VLIB_CLI_COMMAND (show_physmem_command, static) = {
 };
 /* *INDENT-ON* */
 
+static clib_error_t *
+vlib_physmem_config (vlib_main_t * vm, unformat_input_t * input)
+{
+  vlib_physmem_main_t *vpm = &vm->physmem_main;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "base-addr 0x%lx", &vpm->base_addr))
+       ;
+      else
+       return unformat_parse_error (input);
+    }
+
+  unformat_free (input);
+  return 0;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (vlib_physmem_config, "physmem");
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
index a986a50..7b7a3af 100644 (file)
@@ -56,6 +56,7 @@ typedef struct
 typedef struct
 {
   u32 flags;
+  uword base_addr;
 #define VLIB_PHYSMEM_MAIN_F_HAVE_PAGEMAP       (1 << 0)
 #define VLIB_PHYSMEM_MAIN_F_HAVE_IOMMU         (1 << 1)
   vlib_physmem_map_t *maps;
index 5662a36..dd772f3 100644 (file)
@@ -59,10 +59,11 @@ pmalloc_validate_numa_node (u32 * numa_node)
 }
 
 int
-clib_pmalloc_init (clib_pmalloc_main_t * pm, uword size)
+clib_pmalloc_init (clib_pmalloc_main_t * pm, uword base_addr, uword size)
 {
   uword off, pagesize;
   u64 *pt = 0;
+  int mmap_flags;
 
   ASSERT (pm->error == 0);
 
@@ -82,8 +83,13 @@ clib_pmalloc_init (clib_pmalloc_main_t * pm, uword size)
   pm->max_pages = size >> pm->def_log2_page_sz;
 
   /* reserve VA space for future growth */
-  pm->base = mmap (0, size + pagesize, PROT_NONE,
-                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+
+  if (base_addr)
+    mmap_flags |= MAP_FIXED;
+
+  pm->base = mmap (uword_to_pointer (base_addr, void *), size + pagesize,
+                  PROT_NONE, mmap_flags, -1, 0);
 
   if (pm->base == MAP_FAILED)
     {
index 25c4678..2a3bde2 100644 (file)
@@ -103,7 +103,7 @@ typedef struct
 } clib_pmalloc_main_t;
 
 
-int clib_pmalloc_init (clib_pmalloc_main_t * pm, uword size);
+int clib_pmalloc_init (clib_pmalloc_main_t * pm, uword base_addr, uword size);
 void *clib_pmalloc_alloc_aligned_on_numa (clib_pmalloc_main_t * pm,
                                          uword size, uword align,
                                          u32 numa_node);
index 90b1775..a59ff32 100644 (file)
@@ -44,7 +44,7 @@ test_palloc (test_main_t * tm)
   int i;
   uword *va;
 
-  if (clib_pmalloc_init (pm, 0) != 0)
+  if (clib_pmalloc_init (pm, 0, 0) != 0)
     return clib_error_return (0, "pmalloc init failure");
 
   fformat (stdout, "Allocate %d items...\n", tm->nitems);