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 /src/svm/svm.c | |
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>
Diffstat (limited to 'src/svm/svm.c')
-rw-r--r-- | src/svm/svm.c | 43 |
1 files changed, 40 insertions, 3 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; |