From c83e80ad9126429f7feada70237c41d9a79ae7b6 Mon Sep 17 00:00:00 2001 From: "Balazs Gerofi bgerofi@riken.jp" Date: Mon, 28 Jul 2014 15:34:58 +0900 Subject: [PATCH] execve(): clear host user-space PTEs before context switching --- executer/user/mcexec.c | 53 ++++++++++++++++++++++++++++++++++------ kernel/include/process.h | 3 +++ kernel/process.c | 3 --- kernel/syscall.c | 24 +++++++++++++++++- 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 04d57a34..0e24d0fa 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1217,18 +1217,57 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) int ret = -1; struct program_load_desc *desc; struct remote_transfer trans; - + FILE *fp; + int status; + char path[2048]; + char *filename; + /* Load descriptor phase */ case 1: - if (load_elf_desc((char *)w.sr.args[1], &desc) != 0) { + + filename = (char *)w.sr.args[1]; + + /* Is filename without path? */ + if (0 && strncmp(filename, "/", 1) + //&& strncmp(filename, ".", 1) + ) { + + char *PATH = getenv("PATH"); + fprintf(stderr, "PATH: %s\n", PATH); + + /* Open command for reading. */ + sprintf(path, "/usr/bin/which %s", filename); + fp = popen(path, "r"); + if (fp == NULL) { + fprintf(stderr, "execve(): failed to run which\n" ); + goto return_execve1; + } + + /* Read the output a line at a time - output it. */ + if (fgets(path, sizeof(path)-1, fp) == NULL) { + fprintf(stderr, "execve(): failed to read which\n" ); + pclose(fp); + goto return_execve1; + } + + /* close */ + pclose(fp); + } + else { + sprintf(path, "%s", filename); + } + + __dprintf("execve: filename: %s\n", filename); + __dprintf("execve: LD_LIBRARY_PATH: %s\n", getenv("LD_LIBRARY_PATH") ? getenv("LD_LIBRARY_PATH") : "(empty)"); + + if (load_elf_desc(path, &desc) != 0) { fprintf(stderr, - "execve(): error loading ELF for file %s\n", - (char *)w.sr.args[1]); + "execve(): error loading ELF for file %s\n", path); goto return_execve1; } __dprintf("execve(): load_elf_desc() for %s OK, num sections: %d\n", - w.sr.args[1], desc->num_sections); + path, desc->num_sections); /* Copy descriptor to co-kernel side */ trans.userp = (void*)desc; @@ -1246,7 +1285,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) } __dprintf("execve(): load_elf_desc() for %s OK\n", - w.sr.args[1]); + path); /* We can't be sure next phase will succeed */ /* TODO: what shall we do with fp in desc?? */ @@ -1279,7 +1318,7 @@ return_execve1: goto return_execve1; } - printf("execve(): transfer ELF desc OK\n"); + __dprintf("execve(): transfer ELF desc OK\n"); transfer_image(fd, desc); __dprintf("execve(): image transferred\n"); diff --git a/kernel/include/process.h b/kernel/include/process.h index adf74ecf..066b5e96 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -84,6 +84,9 @@ //#define USE_LARGE_PAGES #endif +#define USER_STACK_NR_PAGES 8192 +#define KERNEL_STACK_NR_PAGES 25 + #include #include #include diff --git a/kernel/process.c b/kernel/process.c index aacd0856..13f820fb 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -43,9 +43,6 @@ #endif -#define USER_STACK_NR_PAGES 8192 -#define KERNEL_STACK_NR_PAGES 25 - extern long do_arch_prctl(unsigned long code, unsigned long address); static void insert_vm_range_list(struct process_vm *vm, struct vm_range *newrange); diff --git a/kernel/syscall.c b/kernel/syscall.c index 67280657..aa453800 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1228,6 +1228,11 @@ SYSCALL_DECLARE(execve) /* Unmap all memory areas of the process, userspace will be gone */ free_process_memory_ranges(cpu_local_var(current)); + ihk_mc_init_user_process(&cpu_local_var(current)->ctx, + &cpu_local_var(current)->uctx, + ((char *)cpu_local_var(current)) + + KERNEL_STACK_NR_PAGES * PAGE_SIZE, desc->entry, 0); + /* Create virtual memory ranges and update args/envs */ if (prepare_process_ranges_args_envs(cpu_local_var(current), desc, desc, PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER, @@ -1235,6 +1240,18 @@ SYSCALL_DECLARE(execve) kprintf("execve(): PANIC: preparing ranges, args, envs, stack\n"); panic(""); } + + /* Clear host user space PTEs */ + request.number = __NR_munmap; + request.args[0] = cpu_local_var(current)->vm->region.user_start; + request.args[1] = cpu_local_var(current)->vm->region.user_end - + cpu_local_var(current)->vm->region.user_start; + dkprintf("execve(): requesting host PTE clear\n"); + + if (do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0)) { + kprintf("execve(): ERROR: clearing PTEs in host process\n"); + panic(""); + } /* Request host to transfer ELF image */ request.number = __NR_execve; @@ -1250,8 +1267,13 @@ SYSCALL_DECLARE(execve) panic(""); } - dkprintf("execve(): returning to new process\n"); + /* Switch to new execution context */ + dkprintf("execve(): switching to new process\n"); + + ihk_mc_switch_context(NULL, &cpu_local_var(current)->ctx, + cpu_local_var(current)); + /* Never reach here */ return 0; }