refactor process_msg_prepare_process() in preparation for execve()
This commit is contained in:
149
kernel/host.c
149
kernel/host.c
@@ -50,71 +50,38 @@ void check_mapping_for_proc(struct process *proc, unsigned long addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Communication with host
|
* Prepares the process ranges based on the ELF header described
|
||||||
|
* in program_load_desc and updates physical address in "p" so that
|
||||||
|
* host can copy program image.
|
||||||
|
* It also prepares args, envs and the process stack.
|
||||||
|
*
|
||||||
|
* NOTE: if args, args_len, envs, envs_len are zero,
|
||||||
|
* the function constructs them based on the descriptor
|
||||||
*/
|
*/
|
||||||
static int process_msg_prepare_process(unsigned long rphys)
|
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)
|
||||||
{
|
{
|
||||||
unsigned long phys, sz, s, e, up;
|
|
||||||
struct program_load_desc *p, *pn;
|
|
||||||
int i, npages, n;
|
|
||||||
struct process *proc;
|
|
||||||
unsigned long addr;
|
|
||||||
char *args_envs, *args_envs_r;
|
char *args_envs, *args_envs_r;
|
||||||
unsigned long args_envs_p, args_envs_rp;
|
unsigned long args_envs_p, args_envs_rp;
|
||||||
|
unsigned long s, e, up;
|
||||||
char **argv;
|
char **argv;
|
||||||
int argc, envc, args_envs_npages;
|
int i, n, argc, envc, args_envs_npages;
|
||||||
char **env;
|
char **env;
|
||||||
int range_npages;
|
int range_npages;
|
||||||
void *up_v;
|
void *up_v;
|
||||||
|
unsigned long addr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
uintptr_t interp_obase = -1;
|
uintptr_t interp_obase = -1;
|
||||||
uintptr_t interp_nbase = -1;
|
uintptr_t interp_nbase = -1;
|
||||||
enum ihk_mc_pt_attribute attr;
|
|
||||||
|
|
||||||
attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER;
|
|
||||||
|
|
||||||
sz = sizeof(struct program_load_desc)
|
|
||||||
+ sizeof(struct program_image_section) * 16;
|
|
||||||
npages = ((rphys + sz - 1) >> PAGE_SHIFT) - (rphys >> PAGE_SHIFT) + 1;
|
|
||||||
|
|
||||||
phys = ihk_mc_map_memory(NULL, rphys, sz);
|
|
||||||
if((p = ihk_mc_map_virtual(phys, npages, attr)) == NULL){
|
|
||||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = p->num_sections;
|
n = p->num_sections;
|
||||||
dkprintf("# of sections: %d\n", n);
|
|
||||||
|
|
||||||
if((pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
|
||||||
+ sizeof(struct program_image_section) * n, IHK_MC_AP_NOWAIT)) == NULL){
|
|
||||||
ihk_mc_unmap_virtual(p, npages, 0);
|
|
||||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memcpy_long(pn, p, sizeof(struct program_load_desc)
|
|
||||||
+ sizeof(struct program_image_section) * n);
|
|
||||||
|
|
||||||
if((proc = create_process(p->entry)) == NULL){
|
|
||||||
ihk_mc_free(pn);
|
|
||||||
ihk_mc_unmap_virtual(p, npages, 1);
|
|
||||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
proc->pid = pn->pid;
|
|
||||||
proc->tid = pn->pid;
|
|
||||||
proc->ftn->pid = pn->pid;
|
|
||||||
proc->vm->region.user_start = pn->user_start;
|
|
||||||
proc->vm->region.user_end = pn->user_end;
|
|
||||||
proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
|
|
||||||
proc->vm->region.map_end = proc->vm->region.map_start;
|
|
||||||
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
|
||||||
proc->rlimit_stack.rlim_max = pn->rlimit_stack_max;
|
|
||||||
|
|
||||||
/* TODO: Clear it at the proper timing */
|
|
||||||
cpu_local_var(scp).post_idx = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) {
|
if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) {
|
||||||
interp_obase = pn->sections[i].vaddr;
|
interp_obase = pn->sections[i].vaddr;
|
||||||
interp_obase -= (interp_obase % pn->interp_align);
|
interp_obase -= (interp_obase % pn->interp_align);
|
||||||
@@ -122,6 +89,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
interp_nbase = (interp_nbase + pn->interp_align - 1)
|
interp_nbase = (interp_nbase + pn->interp_align - 1)
|
||||||
& ~(pn->interp_align - 1);
|
& ~(pn->interp_align - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pn->sections[i].interp) {
|
if (pn->sections[i].interp) {
|
||||||
pn->sections[i].vaddr -= interp_obase;
|
pn->sections[i].vaddr -= interp_obase;
|
||||||
pn->sections[i].vaddr += interp_nbase;
|
pn->sections[i].vaddr += interp_nbase;
|
||||||
@@ -135,9 +103,11 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
flags |= PROT_TO_VR_FLAG(pn->sections[i].prot);
|
flags |= PROT_TO_VR_FLAG(pn->sections[i].prot);
|
||||||
flags |= VRFLAG_PROT_TO_MAXPROT(flags);
|
flags |= VRFLAG_PROT_TO_MAXPROT(flags);
|
||||||
|
|
||||||
if((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
if ((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT))
|
||||||
|
== NULL) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
up = virt_to_phys(up_v);
|
up = virt_to_phys(up_v);
|
||||||
if (add_process_memory_range(proc, s, e, up, flags, NULL, 0) != 0) {
|
if (add_process_memory_range(proc, s, e, up, flags, NULL, 0) != 0) {
|
||||||
ihk_mc_free_pages(up_v, range_npages);
|
ihk_mc_free_pages(up_v, range_npages);
|
||||||
@@ -178,10 +148,12 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
else if (i == 0) {
|
else if (i == 0) {
|
||||||
proc->vm->region.text_start = s;
|
proc->vm->region.text_start = s;
|
||||||
proc->vm->region.text_end = e;
|
proc->vm->region.text_end = e;
|
||||||
} else if (i == 1) {
|
}
|
||||||
|
else if (i == 1) {
|
||||||
proc->vm->region.data_start = s;
|
proc->vm->region.data_start = s;
|
||||||
proc->vm->region.data_end = e;
|
proc->vm->region.data_end = e;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
proc->vm->region.data_start =
|
proc->vm->region.data_start =
|
||||||
(s < proc->vm->region.data_start ?
|
(s < proc->vm->region.data_start ?
|
||||||
s : proc->vm->region.data_start);
|
s : proc->vm->region.data_start);
|
||||||
@@ -195,7 +167,8 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
pn->entry -= interp_obase;
|
pn->entry -= interp_obase;
|
||||||
pn->entry += interp_nbase;
|
pn->entry += interp_nbase;
|
||||||
p->entry = pn->entry;
|
p->entry = pn->entry;
|
||||||
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER, pn->entry);
|
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER,
|
||||||
|
pn->entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@@ -331,10 +304,78 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
|
|
||||||
p->rprocess = (unsigned long)proc;
|
p->rprocess = (unsigned long)proc;
|
||||||
p->rpgtable = virt_to_phys(proc->vm->page_table);
|
p->rpgtable = virt_to_phys(proc->vm->page_table);
|
||||||
|
|
||||||
if (init_process_stack(proc, pn, argc, argv, envc, env) != 0) {
|
if (init_process_stack(proc, pn, argc, argv, envc, env) != 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
/* TODO: cleanup allocated ranges */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Communication with host
|
||||||
|
*/
|
||||||
|
static int process_msg_prepare_process(unsigned long rphys)
|
||||||
|
{
|
||||||
|
unsigned long phys, sz;
|
||||||
|
struct program_load_desc *p, *pn;
|
||||||
|
int npages, n;
|
||||||
|
struct process *proc;
|
||||||
|
enum ihk_mc_pt_attribute attr;
|
||||||
|
|
||||||
|
attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER;
|
||||||
|
|
||||||
|
sz = sizeof(struct program_load_desc)
|
||||||
|
+ sizeof(struct program_image_section) * 16;
|
||||||
|
npages = ((rphys + sz - 1) >> PAGE_SHIFT) - (rphys >> PAGE_SHIFT) + 1;
|
||||||
|
|
||||||
|
phys = ihk_mc_map_memory(NULL, rphys, sz);
|
||||||
|
if((p = ihk_mc_map_virtual(phys, npages, attr)) == NULL){
|
||||||
|
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = p->num_sections;
|
||||||
|
dkprintf("# of sections: %d\n", n);
|
||||||
|
|
||||||
|
if((pn = ihk_mc_allocate(sizeof(struct program_load_desc)
|
||||||
|
+ sizeof(struct program_image_section) * n, IHK_MC_AP_NOWAIT)) == NULL){
|
||||||
|
ihk_mc_unmap_virtual(p, npages, 0);
|
||||||
|
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy_long(pn, p, sizeof(struct program_load_desc)
|
||||||
|
+ sizeof(struct program_image_section) * n);
|
||||||
|
|
||||||
|
if((proc = create_process(p->entry)) == NULL){
|
||||||
|
ihk_mc_free(pn);
|
||||||
|
ihk_mc_unmap_virtual(p, npages, 1);
|
||||||
|
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
proc->pid = pn->pid;
|
||||||
|
proc->tid = pn->pid;
|
||||||
|
proc->ftn->pid = pn->pid;
|
||||||
|
proc->vm->region.user_start = pn->user_start;
|
||||||
|
proc->vm->region.user_end = pn->user_end;
|
||||||
|
proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
|
||||||
|
proc->vm->region.map_end = proc->vm->region.map_start;
|
||||||
|
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
||||||
|
proc->rlimit_stack.rlim_max = pn->rlimit_stack_max;
|
||||||
|
|
||||||
|
/* TODO: Clear it at the proper timing */
|
||||||
|
cpu_local_var(scp).post_idx = 0;
|
||||||
|
|
||||||
|
if (prepare_process_ranges_args_envs(proc, pn, p, attr,
|
||||||
|
NULL, 0, NULL, 0) != 0) {
|
||||||
|
kprintf("error: preparing process ranges, args, envs, stack\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||||
proc->vm->page_table);
|
proc->vm->page_table);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user