summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/vlib/physmem.c34
-rw-r--r--src/vlib/physmem.h1
-rw-r--r--src/vppinfra/pmalloc.c12
-rw-r--r--src/vppinfra/pmalloc.h2
-rw-r--r--src/vppinfra/test_pmalloc.c2
5 files changed, 45 insertions, 6 deletions
diff --git a/src/vlib/physmem.c b/src/vlib/physmem.c
index 21fe44fc1ca..64920e1ebe2 100755
--- a/src/vlib/physmem.c
+++ b/src/vlib/physmem.c
@@ -29,6 +29,15 @@
#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
*
diff --git a/src/vlib/physmem.h b/src/vlib/physmem.h
index a986a50b1cb..7b7a3af3dfa 100644
--- a/src/vlib/physmem.h
+++ b/src/vlib/physmem.h
@@ -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;
diff --git a/src/vppinfra/pmalloc.c b/src/vppinfra/pmalloc.c
index 41309dd1d99..9c5f475e8dd 100644
--- a/src/vppinfra/pmalloc.c
+++ b/src/vppinfra/pmalloc.c
@@ -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)
{
diff --git a/src/vppinfra/pmalloc.h b/src/vppinfra/pmalloc.h
index 25c46783f8c..2a3bde2acc4 100644
--- a/src/vppinfra/pmalloc.h
+++ b/src/vppinfra/pmalloc.h
@@ -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);
diff --git a/src/vppinfra/test_pmalloc.c b/src/vppinfra/test_pmalloc.c
index 90b1775bb4f..a59ff32db05 100644
--- a/src/vppinfra/test_pmalloc.c
+++ b/src/vppinfra/test_pmalloc.c
@@ -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);