execve(): supporting syscall and mcexec modifications

This commit is contained in:
Balazs Gerofi bgerofi@riken.jp
2014-05-22 17:34:41 +09:00
parent badb450153
commit 514d75b685
4 changed files with 195 additions and 1 deletions

View File

@ -1199,6 +1199,93 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
break;
}
case __NR_execve: {
/* Execve phase */
switch (w.sr.args[0]) {
int ret = -1;
struct program_load_desc *desc;
struct remote_transfer trans;
/* Load descriptor phase */
case 1:
if (load_elf_desc((char *)w.sr.args[1], &desc) != 0) {
fprintf(stderr,
"execve(): error loading ELF for file %s\n",
(char *)w.sr.args[1]);
goto return_execve1;
}
__dprintf("execve(): load_elf_desc() for %s OK, num sections: %d\n",
w.sr.args[1], desc->num_sections);
/* Copy descriptor to co-kernel side */
trans.userp = (void*)desc;
trans.rphys = w.sr.args[2];
trans.size = sizeof(struct program_load_desc) +
sizeof(struct program_image_section) *
desc->num_sections;
trans.direction = MCEXEC_UP_TRANSFER_TO_REMOTE;
if (ioctl(fd, MCEXEC_UP_TRANSFER, &trans) != 0) {
fprintf(stderr,
"execve(): error transfering ELF for file %s\n",
(char *)w.sr.args[1]);
goto return_execve1;
}
__dprintf("execve(): load_elf_desc() for %s OK\n",
w.sr.args[1]);
/* We can't be sure next phase will succeed */
/* TODO: what shall we do with fp in desc?? */
free(desc);
ret = 0;
return_execve1:
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
break;
/* Copy program image phase */
case 2:
/* Alloc descriptor */
desc = malloc(w.sr.args[2]);
if (!desc) {
fprintf(stderr, "execve(): error allocating desc\n");
goto return_execve2;
}
/* Copy descriptor from co-kernel side */
trans.userp = (void*)desc;
trans.rphys = w.sr.args[1];
trans.size = w.sr.args[2];
trans.direction = MCEXEC_UP_TRANSFER_FROM_REMOTE;
if (ioctl(fd, MCEXEC_UP_TRANSFER, &trans) != 0) {
fprintf(stderr,
"execve(): error obtaining ELF descriptor\n");
goto return_execve1;
}
printf("execve(): transfer ELF desc OK\n");
transfer_image(fd, desc);
__dprintf("execve(): image transferred\n");
ret = 0;
return_execve2:
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
break;
default:
fprintf(stderr, "execve(): ERROR: invalid execve phase\n");
break;
}
break;
}
default:
ret = do_generic_syscall(&w);
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);

View File

@ -212,6 +212,7 @@ void hold_process(struct process *proc);
void release_process(struct process *proc);
void flush_process_memory(struct process *proc);
void free_process_memory(struct process *proc);
void free_process_memory_ranges(struct process *proc);
int populate_process_memory(struct process *proc, void *start, size_t len);
int add_process_memory_range(struct process *process,

View File

@ -1423,6 +1423,29 @@ void flush_process_memory(struct process *proc)
return;
}
void free_process_memory_ranges(struct process *proc)
{
int error;
struct vm_range *range, *next;
struct process_vm *vm = proc->vm;
if (vm == NULL) {
return;
}
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
list_for_each_entry_safe(range, next, &vm->vm_range_list, list) {
error = free_process_memory_range(vm, range);
if (error) {
ekprintf("free_process_memory(%p):"
"free range failed. %lx-%lx %d\n",
proc, range->start, range->end, error);
/* through */
}
}
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
}
void free_process_memory(struct process *proc)
{
struct vm_range *range, *next;

View File

@ -97,6 +97,13 @@ void do_signal(long rc, void *regs, struct process *proc, struct sig_pending *pe
int copy_from_user(struct process *, void *, const void *, size_t);
int copy_to_user(struct process *, void *, const void *, size_t);
int prepare_process_ranges_args_envs(struct process *proc,
struct program_load_desc *pn,
struct program_load_desc *p,
enum ihk_mc_pt_attribute attr,
char *args, int args_len,
char *envs, int envs_len);
#ifdef DCFA_KMOD
static void do_mod_exit(int status);
#endif
@ -1128,7 +1135,83 @@ SYSCALL_DECLARE(arch_prctl)
SYSCALL_DECLARE(execve)
{
return -EOPNOTSUPP;
long ret;
const char *filename = (const char *)ihk_mc_syscall_arg0(ctx);
char **argv = (char **)ihk_mc_syscall_arg1(ctx);
char **envp = (char **)ihk_mc_syscall_arg2(ctx);
char *argv_flat = NULL;
int argv_flat_len = 0;
char *envp_flat = NULL;
int envp_flat_len = 0;
struct syscall_request request IHK_DMA_ALIGN;
struct program_load_desc *desc;
desc = ihk_mc_alloc_pages(1, IHK_MC_AP_NOWAIT);
if (!desc) {
kprintf("execve(): ERROR: allocating program descriptor\n");
return -ENOMEM;
}
memset((void*)desc, 0, PAGE_SIZE);
/* Request host to open executable and load ELF section descriptions */
request.number = __NR_execve;
request.args[0] = 1; /* 1st phase - get ELF desc */
request.args[1] = (unsigned long)filename;
request.args[2] = virt_to_phys(desc);
ret = do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0);
if (ret != 0) {
kprintf("execve(): ERROR: host failed to load elf header\n");
return -EINVAL;
}
dkprintf("execve(): ELF desc received, num sections: %d\n",
desc->num_sections);
/* Flatten argv and envp into kernel-space buffers */
argv_flat_len = flatten_strings(-1, argv, &argv_flat);
if (argv_flat_len == 0) {
kprintf("ERROR: no argv for executable: %s?\n", filename);
return -EINVAL;
}
envp_flat_len = flatten_strings(-1, envp, &envp_flat);
if (envp_flat_len == 0) {
kprintf("ERROR: no envp for executable: %s?\n", filename);
return -EINVAL;
}
/* Unmap all memory areas of the process, userspace will be gone */
free_process_memory_ranges(cpu_local_var(current));
/* 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,
argv_flat, argv_flat_len, envp_flat, envp_flat_len) != 0) {
kprintf("execve(): PANIC: preparing ranges, args, envs, stack\n");
panic("");
}
/* Request host to transfer ELF image */
request.number = __NR_execve;
request.args[0] = 2; /* 2nd phase - transfer ELF image */
request.args[1] = virt_to_phys(desc);
request.args[2] = sizeof(struct program_load_desc) +
sizeof(struct program_image_section) * desc->num_sections;
ret = do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0);
if (ret != 0) {
kprintf("execve(): PANIC: host failed to load elf image\n");
panic("");
}
dkprintf("execve(): returning to new process\n");
return 0;
}
SYSCALL_DECLARE(clone)