diff options
Diffstat (limited to 'src/svm')
-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 |
3 files changed, 42 insertions, 11 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; |