diff options
author | Damjan Marion <damarion@cisco.com> | 2018-01-08 16:35:35 +0100 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2018-01-10 02:17:31 +0000 |
commit | aec8f8984771cabc79a8ed64f56afcf61465d00a (patch) | |
tree | 5c870e08fc7f9e2104d42664b4a826c1efb9073b | |
parent | 618c94a83f0a76734b69f829a417fdd0f87e6887 (diff) |
svm: calc base address on AArch64 based on autodetected VA space size
Change-Id: I7487eb74b8deebff849d662b55a6708566ccd9ef
Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r-- | src/svm/svm.c | 43 | ||||
-rw-r--r-- | src/svm/svm_common.h | 8 | ||||
-rw-r--r-- | src/svm/svmtool.c | 2 | ||||
-rw-r--r-- | src/vlibmemory/memory_api.c | 2 |
4 files changed, 43 insertions, 12 deletions
diff --git a/src/svm/svm.c b/src/svm/svm.c index c54f9730094..f187fbfcab2 100644 --- a/src/svm/svm.c +++ b/src/svm/svm.c @@ -58,6 +58,43 @@ svm_get_root_rp (void) #define MUTEX_DEBUG +u64 +svm_get_global_region_base_va () +{ +#if __aarch64__ + /* On AArch64 VA space can have different size, from 36 to 48 bits. + Here we are trying to detect VA bits by parsing /proc/self/maps + address ranges */ + int fd; + unformat_input_t input; + u64 start, end = 0; + u8 bits = 0; + + if ((fd = open ("/proc/self/maps", 0)) < 0) + clib_unix_error ("open '/proc/self/maps'"); + + unformat_init_clib_file (&input, fd); + while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) + { + unformat (&input, "%llx-%llx", &start, &end); + unformat_skip_line (&input); + } + + count_leading_zeros (bits, end); + bits = 64 - bits; + if (bits >= 36 && bits <= 48) + return ((1ul << bits) / 4) - (2 * SVM_GLOBAL_REGION_SIZE); + else + clib_unix_error ("unexpected va bits '%u'", bits); + + unformat_free (&input); + close (fd); +#endif + + /* default value */ + return 0x30000000; +} + static void region_lock (svm_region_t * rp, int tag) { @@ -804,7 +841,7 @@ svm_region_init (void) memset (a, 0, sizeof (*a)); a->root_path = 0; a->name = SVM_GLOBAL_REGION_NAME; - a->baseva = SVM_GLOBAL_REGION_BASEVA; + a->baseva = svm_get_global_region_base_va (); a->size = SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; a->uid = 0; @@ -821,7 +858,7 @@ svm_region_init_chroot (const char *root_path) memset (a, 0, sizeof (*a)); a->root_path = root_path; a->name = SVM_GLOBAL_REGION_NAME; - a->baseva = SVM_GLOBAL_REGION_BASEVA; + a->baseva = svm_get_global_region_base_va (); a->size = SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; a->uid = 0; @@ -838,7 +875,7 @@ svm_region_init_chroot_uid_gid (const char *root_path, int uid, int gid) memset (a, 0, sizeof (*a)); a->root_path = root_path; a->name = SVM_GLOBAL_REGION_NAME; - a->baseva = SVM_GLOBAL_REGION_BASEVA; + a->baseva = svm_get_global_region_base_va (); a->size = SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; a->uid = uid; diff --git a/src/svm/svm_common.h b/src/svm/svm_common.h index 58cd0e94f5c..c650165b4cf 100644 --- a/src/svm/svm_common.h +++ b/src/svm/svm_common.h @@ -85,13 +85,7 @@ typedef struct svm_map_region_args_ */ #define SVM_GLOBAL_REGION_SIZE (64<<20) #define SVM_GLOBAL_REGION_NAME "/global_vm" -#if defined (__aarch64__) -#define VA_BITS 48 -#define BASEVA ((1ul << VA_BITS) / 4) -#define SVM_GLOBAL_REGION_BASEVA (BASEVA - (2 * SVM_GLOBAL_REGION_SIZE)) -#else -#define SVM_GLOBAL_REGION_BASEVA 0x30000000 -#endif +u64 svm_get_global_region_base_va (); /* * Memory shared across individual router instances. diff --git a/src/svm/svmtool.c b/src/svm/svmtool.c index 01ae4221371..63577d97fd9 100644 --- a/src/svm/svmtool.c +++ b/src/svm/svmtool.c @@ -368,7 +368,7 @@ repair (char *chroot_path, int crash_root_region) a->root_path = chroot_path; a->name = SVM_GLOBAL_REGION_NAME; - a->baseva = SVM_GLOBAL_REGION_BASEVA; + a->baseva = svm_get_global_region_base_va (); a->size = SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c index d049a625015..752f50717b0 100644 --- a/src/vlibmemory/memory_api.c +++ b/src/vlibmemory/memory_api.c @@ -871,7 +871,7 @@ vlibmemory_init (vlib_main_t * vm) a->root_path = am->root_path; a->name = SVM_GLOBAL_REGION_NAME; a->baseva = (am->global_baseva != 0) ? - am->global_baseva : SVM_GLOBAL_REGION_BASEVA; + am->global_baseva : +svm_get_global_region_base_va (); a->size = (am->global_size != 0) ? am->global_size : SVM_GLOBAL_REGION_SIZE; a->flags = SVM_FLAGS_NODATA; a->uid = am->api_uid; |