diff --git a/devicemodel/core/hugetlb.c b/devicemodel/core/hugetlb.c index 409218ff9..c111e4f4c 100644 --- a/devicemodel/core/hugetlb.c +++ b/devicemodel/core/hugetlb.c @@ -40,6 +40,8 @@ #include "vmmapi.h" +extern char *vmname; + #define HUGETLB_LV1 0 #define HUGETLB_LV2 1 #define HUGETLB_LV_MAX 2 @@ -139,7 +141,7 @@ static int open_hugetlbfs(struct vmctx *ctx, int level) path = hugetlb_priv[level].node_path; memset(path, '\0', MAX_PATH_LEN); - strncpy(path, hugetlb_priv[level].mount_path, MAX_PATH_LEN); + snprintf(path, MAX_PATH_LEN, "%s%s/", hugetlb_priv[level].mount_path, ctx->name); len = strnlen(path, MAX_PATH_LEN); /* UUID will use 32 bytes */ @@ -336,9 +338,29 @@ static size_t adj_biosmem_param(struct hugetlb_info *htlb, return htlb->biosmem; } +static int rm_hugetlb_dirs(int level) +{ + char path[MAX_PATH_LEN]={0}; + + if (level >= HUGETLB_LV_MAX) { + perror("exceed max hugetlb level"); + return -EINVAL; + } + + snprintf(path,MAX_PATH_LEN, "%s%s/",hugetlb_priv[level].mount_path,vmname); + + if (access(path, F_OK) == 0) { + if (rmdir(path) < 0) { + perror("rmdir failed"); + return -1; + } + } + return 0; +} + static int create_hugetlb_dirs(int level) { - char tmp_path[MAX_PATH_LEN], *path; + char path[MAX_PATH_LEN]={0}; int i; size_t len; @@ -347,30 +369,19 @@ static int create_hugetlb_dirs(int level) return -EINVAL; } - path = hugetlb_priv[level].mount_path; + snprintf(path,MAX_PATH_LEN, "%s%s/",hugetlb_priv[level].mount_path,vmname); + len = strnlen(path, MAX_PATH_LEN); - if (len == MAX_PATH_LEN || len == 0) { - perror("invalid path len"); - return -EINVAL; - } - - memset(tmp_path, '\0', MAX_PATH_LEN); - strncpy(tmp_path, path, MAX_PATH_LEN); - - if ((tmp_path[len - 1] != '/') && (len < MAX_PATH_LEN - 1)) - tmp_path[len] = '/'; - - len = strnlen(tmp_path, MAX_PATH_LEN); for (i = 1; i < len; i++) { - if (tmp_path[i] == '/') { - tmp_path[i] = 0; - if (access(tmp_path, F_OK) != 0) { - if (mkdir(tmp_path, 0755) < 0) { + if (path[i] == '/') { + path[i] = 0; + if (access(path, F_OK) != 0) { + if (mkdir(path, 0755) < 0) { perror("mkdir failed"); return -1; } } - tmp_path[i] = '/'; + path[i] = '/'; } } @@ -380,6 +391,7 @@ static int create_hugetlb_dirs(int level) static int mount_hugetlbfs(int level) { int ret; + char path[MAX_PATH_LEN]; if (level >= HUGETLB_LV_MAX) { perror("exceed max hugetlb level"); @@ -389,8 +401,10 @@ static int mount_hugetlbfs(int level) if (hugetlb_priv[level].mounted) return 0; + snprintf(path, MAX_PATH_LEN, "%s%s", hugetlb_priv[level].mount_path,vmname); + /* only support x86 as HUGETLB level-1 2M page, level-2 1G page*/ - ret = mount("none", hugetlb_priv[level].mount_path, "hugetlbfs", + ret = mount("none", path, "hugetlbfs", 0, hugetlb_priv[level].mount_opt); if (ret == 0) hugetlb_priv[level].mounted = true; @@ -400,13 +414,18 @@ static int mount_hugetlbfs(int level) static void umount_hugetlbfs(int level) { + char path[MAX_PATH_LEN]; + if (level >= HUGETLB_LV_MAX) { perror("exceed max hugetlb level"); return; } + snprintf(path, MAX_PATH_LEN, "%s%s", hugetlb_priv[level].mount_path,vmname); + + if (hugetlb_priv[level].mounted) { - umount(hugetlb_priv[level].mount_path); + umount(path); hugetlb_priv[level].mounted = false; } } @@ -589,7 +608,8 @@ static bool hugetlb_reserve_pages(void) return true; } -bool check_hugetlb_support(void) + +bool init_hugetlb(void) { int level; @@ -615,6 +635,15 @@ bool check_hugetlb_support(void) return true; } +void uninit_hugetlb(void) +{ + int level; + for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) { + umount_hugetlbfs(level); + rm_hugetlb_dirs(level); + } +} + int hugetlb_setup_memory(struct vmctx *ctx) { int level; @@ -626,15 +655,6 @@ int hugetlb_setup_memory(struct vmctx *ctx) goto err; } - /* for first time DM start UOS, hugetlbfs is already mounted by - * check_hugetlb_support; but for reboot, here need re-mount - * it as it already be umount by hugetlb_unsetup_memory - * TODO: actually, correct reboot process should not change memory - * layout, the setup_memory should be removed from reboot process - */ - for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) - mount_hugetlbfs(level); - /* open hugetlbfs and get pagesize for two level */ for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) { if (open_hugetlbfs(ctx, level) < 0) { @@ -781,7 +801,6 @@ err: } for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) { close_hugetlbfs(level); - umount_hugetlbfs(level); } return -ENOMEM; } @@ -798,6 +817,5 @@ void hugetlb_unsetup_memory(struct vmctx *ctx) for (level = HUGETLB_LV1; level < hugetlb_lv_max; level++) { close_hugetlbfs(level); - umount_hugetlbfs(level); } } diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index bd9532f2a..eb37e4406 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -770,7 +770,7 @@ static char optstr[] = "hAWYvE:k:r:B:p:c:s:m:l:U:G:i:"; int main(int argc, char *argv[]) { - int c, error, err; + int c, error, ret=1; int max_vcpus, mptgen; struct vmctx *ctx; size_t memsize; @@ -949,23 +949,23 @@ main(int argc, char *argv[]) if (argc != 1) usage(1); - if (!check_hugetlb_support()) { - pr_err("check_hugetlb_support failed\n"); - exit(1); - } - vmname = argv[0]; if (strnlen(vmname, MAX_VMNAME_LEN) >= MAX_VMNAME_LEN) { pr_err("vmname size exceed %u\n", MAX_VMNAME_LEN); exit(1); } + if (!init_hugetlb()) { + pr_err("init_hugetlb failed\n"); + exit(1); + } + for (;;) { pr_notice("vm_create: %s\n", vmname); ctx = vm_create(vmname, (unsigned long)vhm_req_buf); if (!ctx) { pr_err("vm_create failed"); - exit(1); + goto create_fail; } if (guest_ncpus < 1) { @@ -981,14 +981,14 @@ main(int argc, char *argv[]) } pr_notice("vm_setup_memory: size=0x%lx\n", memsize); - err = vm_setup_memory(ctx, memsize); - if (err) { + error = vm_setup_memory(ctx, memsize); + if (error) { pr_err("Unable to setup memory (%d)\n", errno); goto fail; } - err = mevent_init(); - if (err) { + error = mevent_init(); + if (error) { pr_err("Unable to initialize mevent (%d)\n", errno); goto mevent_fail; } @@ -1050,8 +1050,10 @@ main(int argc, char *argv[]) vm_pause(ctx); delete_cpu(ctx, BSP); - if (vm_get_suspend_mode() != VM_SUSPEND_FULL_RESET) + if (vm_get_suspend_mode() != VM_SUSPEND_FULL_RESET){ + ret = 0; break; + } vm_deinit_vdevs(ctx); mevent_deinit(); @@ -1070,5 +1072,7 @@ mevent_fail: vm_unsetup_memory(ctx); fail: vm_destroy(ctx); - exit(0); +create_fail: + uninit_hugetlb(); + exit(ret); } diff --git a/devicemodel/include/vmmapi.h b/devicemodel/include/vmmapi.h index 77f8dc8c4..f6c4598fd 100644 --- a/devicemodel/include/vmmapi.h +++ b/devicemodel/include/vmmapi.h @@ -108,7 +108,8 @@ int vm_map_memseg_vma(struct vmctx *ctx, size_t len, vm_paddr_t gpa, uint64_t vma, int prot); int vm_setup_memory(struct vmctx *ctx, size_t len); void vm_unsetup_memory(struct vmctx *ctx); -bool check_hugetlb_support(void); +bool init_hugetlb(void); +void uninit_hugetlb(void); int hugetlb_setup_memory(struct vmctx *ctx); void hugetlb_unsetup_memory(struct vmctx *ctx); void *vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len);