From 903c21b47073860c53f93d17870cf78c12c51629 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Thu, 21 Feb 2019 14:44:59 +0100 Subject: physmem: keep physmem VA in 39-bit address space on x86_64 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 --- src/vlib/physmem.c | 34 +++++++++++++++++++++++++++++++++- src/vlib/physmem.h | 1 + src/vppinfra/pmalloc.c | 12 +++++++++--- src/vppinfra/pmalloc.h | 2 +- src/vppinfra/test_pmalloc.c | 2 +- 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 #include +#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); -- cgit 1.2.3-korg