Merge branch 'master' of postpeta.pccluster.org:mckernel
This commit is contained in:
@@ -69,13 +69,16 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
unsigned long flags;
|
||||
uintptr_t interp_obase = -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, PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
if((p = ihk_mc_map_virtual(phys, npages, attr)) == NULL){
|
||||
ihk_mc_unmap_memory(NULL, phys, sz);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -264,7 +267,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->args, p->args_len);
|
||||
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
attr)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||
@@ -285,7 +288,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
||||
args_envs_rp = ihk_mc_map_memory(NULL, (unsigned long)p->envs, p->envs_len);
|
||||
dkprintf("args_envs_rp: 0x%lX\n", args_envs_rp);
|
||||
if((args_envs_r = (char *)ihk_mc_map_virtual(args_envs_rp, args_envs_npages,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
attr)) == NULL){
|
||||
goto err;
|
||||
}
|
||||
dkprintf("args_envs_r: 0x%lX\n", args_envs_r);
|
||||
@@ -363,6 +366,9 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long
|
||||
{
|
||||
struct ikc_scd_init_param *param = (void *)pphys;
|
||||
struct syscall_params *lparam;
|
||||
enum ihk_mc_pt_attribute attr;
|
||||
|
||||
attr = PTATTR_NO_EXECUTE | PTATTR_WRITABLE | PTATTR_FOR_USER;
|
||||
|
||||
lparam = &cpu_local_var(scp);
|
||||
if(cpu_local_var(syscall_channel2) == c)
|
||||
@@ -372,7 +378,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long
|
||||
REQUEST_PAGE_COUNT * PAGE_SIZE);
|
||||
if((lparam->request_va = ihk_mc_map_virtual(lparam->request_pa,
|
||||
REQUEST_PAGE_COUNT,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
attr)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
@@ -383,7 +389,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long
|
||||
PAGE_SIZE);
|
||||
if((lparam->doorbell_va = ihk_mc_map_virtual(lparam->doorbell_pa,
|
||||
DOORBELL_PAGE_COUNT,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
attr)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
@@ -392,7 +398,7 @@ static void process_msg_init_acked(struct ihk_ikc_channel_desc *c, unsigned long
|
||||
lparam->post_pa = ihk_mc_map_memory(NULL, param->post_page,
|
||||
PAGE_SIZE);
|
||||
if((lparam->post_va = ihk_mc_map_virtual(lparam->post_pa, 1,
|
||||
PTATTR_WRITABLE | PTATTR_FOR_USER)) == NULL){
|
||||
attr)) == NULL){
|
||||
// TODO:
|
||||
panic("ENOMEM");
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ struct process_vm {
|
||||
|
||||
|
||||
struct process *create_process(unsigned long user_pc);
|
||||
struct process *clone_process(struct process *org,
|
||||
unsigned long pc, unsigned long sp);
|
||||
struct process *clone_process(struct process *org, unsigned long pc,
|
||||
unsigned long sp, int clone_flags);
|
||||
void destroy_process(struct process *proc);
|
||||
void hold_process(struct process *proc);
|
||||
void free_process(struct process *proc);
|
||||
|
||||
@@ -109,6 +109,7 @@ struct program_load_desc {
|
||||
int cpu;
|
||||
int pid;
|
||||
int err;
|
||||
int stack_prot;
|
||||
unsigned long entry;
|
||||
unsigned long user_start;
|
||||
unsigned long user_end;
|
||||
@@ -206,9 +207,9 @@ struct syscall_params {
|
||||
SYSCALL_ARG_##a2(2); SYSCALL_ARG_##a3(3); \
|
||||
SYSCALL_ARG_##a4(4); SYSCALL_ARG_##a5(5);
|
||||
|
||||
#define SYSCALL_FOOTER return do_syscall(&request, ctx, ihk_mc_get_processor_id())
|
||||
#define SYSCALL_FOOTER return do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0)
|
||||
|
||||
extern long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu);
|
||||
extern long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu, int pid);
|
||||
extern int obtain_clone_cpuid();
|
||||
extern long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx);
|
||||
|
||||
|
||||
@@ -164,8 +164,8 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
||||
.priv = NULL,
|
||||
};
|
||||
|
||||
void set_signal(int, unsigned long *);
|
||||
void check_signal(long, unsigned long *);
|
||||
void set_signal(int sig, void *regs);
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
|
||||
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
||||
{
|
||||
|
||||
222
kernel/process.c
222
kernel/process.c
@@ -47,6 +47,10 @@
|
||||
#define KERNEL_STACK_NR_PAGES 24
|
||||
|
||||
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);
|
||||
static int copy_user_ranges(struct process *proc, struct process *org);
|
||||
enum ihk_mc_pt_attribute vrflag_to_ptattr(unsigned long flag);
|
||||
|
||||
static int init_process_vm(struct process *owner, struct process_vm *vm)
|
||||
{
|
||||
@@ -105,6 +109,7 @@ struct process *create_process(unsigned long user_pc)
|
||||
proc->vm = (struct process_vm *)(proc + 1);
|
||||
|
||||
if(init_process_vm(proc, proc->vm) != 0){
|
||||
kfree(proc->sigshared);
|
||||
kfree(proc->sighandler);
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
return NULL;
|
||||
@@ -117,11 +122,12 @@ struct process *create_process(unsigned long user_pc)
|
||||
}
|
||||
|
||||
struct process *clone_process(struct process *org, unsigned long pc,
|
||||
unsigned long sp)
|
||||
unsigned long sp, int clone_flags)
|
||||
{
|
||||
struct process *proc;
|
||||
|
||||
if((proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES, IHK_MC_AP_NOWAIT)) == NULL){
|
||||
if ((proc = ihk_mc_alloc_pages(KERNEL_STACK_NR_PAGES,
|
||||
IHK_MC_AP_NOWAIT)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -136,24 +142,198 @@ struct process *clone_process(struct process *org, unsigned long pc,
|
||||
memcpy(proc->uctx, org->uctx, sizeof(*org->uctx));
|
||||
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_STACK_POINTER, sp);
|
||||
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER, pc);
|
||||
|
||||
ihk_atomic_inc(&org->vm->refcount);
|
||||
proc->vm = org->vm;
|
||||
|
||||
proc->rlimit_stack = org->rlimit_stack;
|
||||
|
||||
proc->sighandler = org->sighandler;
|
||||
ihk_atomic_inc(&org->sighandler->use);
|
||||
/* clone() */
|
||||
if (clone_flags & CLONE_VM) {
|
||||
ihk_atomic_inc(&org->vm->refcount);
|
||||
proc->vm = org->vm;
|
||||
|
||||
proc->sighandler = org->sighandler;
|
||||
ihk_atomic_inc(&org->sighandler->use);
|
||||
|
||||
proc->sigshared = org->sigshared;
|
||||
ihk_atomic_inc(&org->sigshared->use);
|
||||
proc->sigshared = org->sigshared;
|
||||
ihk_atomic_inc(&org->sigshared->use);
|
||||
|
||||
ihk_mc_spinlock_init(&proc->sigpendinglock);
|
||||
INIT_LIST_HEAD(&proc->sigpending);
|
||||
ihk_mc_spinlock_init(&proc->sigpendinglock);
|
||||
INIT_LIST_HEAD(&proc->sigpending);
|
||||
}
|
||||
/* fork() */
|
||||
else {
|
||||
dkprintf("fork(): sighandler\n");
|
||||
proc->sighandler = kmalloc(sizeof(struct sig_handler),
|
||||
IHK_MC_AP_NOWAIT);
|
||||
|
||||
if (!proc->sighandler) {
|
||||
goto err_free_proc;
|
||||
}
|
||||
|
||||
dkprintf("fork(): sigshared\n");
|
||||
proc->sigshared = kmalloc(sizeof(struct sig_shared), IHK_MC_AP_NOWAIT);
|
||||
|
||||
if (!proc->sigshared) {
|
||||
goto err_free_sighandler;
|
||||
}
|
||||
|
||||
memset(proc->sighandler, '\0', sizeof(struct sig_handler));
|
||||
ihk_atomic_set(&proc->sighandler->use, 1);
|
||||
ihk_mc_spinlock_init(&proc->sighandler->lock);
|
||||
ihk_atomic_set(&proc->sigshared->use, 1);
|
||||
ihk_mc_spinlock_init(&proc->sigshared->lock);
|
||||
INIT_LIST_HEAD(&proc->sigshared->sigpending);
|
||||
ihk_mc_spinlock_init(&proc->sigpendinglock);
|
||||
INIT_LIST_HEAD(&proc->sigpending);
|
||||
|
||||
proc->vm = (struct process_vm *)(proc + 1);
|
||||
|
||||
dkprintf("fork(): init_process_vm()\n");
|
||||
if (init_process_vm(proc, proc->vm) != 0) {
|
||||
goto err_free_sigshared;
|
||||
}
|
||||
|
||||
memcpy(&proc->vm->region, &org->vm->region, sizeof(struct vm_regions));
|
||||
|
||||
dkprintf("fork(): copy_user_ranges()\n");
|
||||
/* Copy user-space mappings.
|
||||
* TODO: do this with COW later? */
|
||||
if (copy_user_ranges(proc, org) != 0) {
|
||||
goto err_free_sigshared;
|
||||
}
|
||||
|
||||
dkprintf("fork(): copy_user_ranges() OK\n");
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_init(&proc->spin_sleep_lock);
|
||||
proc->spin_sleep = 0;
|
||||
|
||||
return proc;
|
||||
|
||||
err_free_sigshared:
|
||||
kfree(proc->sigshared);
|
||||
|
||||
err_free_sighandler:
|
||||
ihk_mc_free_pages(proc->sighandler, KERNEL_STACK_NR_PAGES);
|
||||
|
||||
err_free_proc:
|
||||
ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int copy_user_ranges(struct process *proc, struct process *org)
|
||||
{
|
||||
struct vm_range *src_range;
|
||||
struct vm_range *range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&org->vm->memory_range_lock);
|
||||
|
||||
/* Iterate original process' vm_range list and take a copy one-by-one */
|
||||
list_for_each_entry(src_range, &org->vm->vm_range_list, list) {
|
||||
void *ptepgaddr;
|
||||
size_t ptepgsize;
|
||||
int ptep2align;
|
||||
void *pg_vaddr;
|
||||
size_t pgsize;
|
||||
void *vaddr;
|
||||
int p2align;
|
||||
enum ihk_mc_pt_attribute attr;
|
||||
pte_t *ptep;
|
||||
|
||||
range = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||
if (!range) {
|
||||
goto err_rollback;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&range->list);
|
||||
range->start = src_range->start;
|
||||
range->end = src_range->end;
|
||||
range->flag = src_range->flag;
|
||||
range->memobj = src_range->memobj;
|
||||
range->objoff = src_range->objoff;
|
||||
if (range->memobj) {
|
||||
memobj_ref(range->memobj);
|
||||
}
|
||||
|
||||
/* Copy actual mappings */
|
||||
vaddr = (void *)range->start;
|
||||
while ((unsigned long)vaddr < range->end) {
|
||||
/* Get source PTE */
|
||||
ptep = ihk_mc_pt_lookup_pte(org->vm->page_table, vaddr,
|
||||
&ptepgaddr, &ptepgsize, &ptep2align);
|
||||
|
||||
if (!ptep || pte_is_null(ptep) || !pte_is_present(ptep)) {
|
||||
vaddr += PAGE_SIZE;
|
||||
continue;
|
||||
}
|
||||
|
||||
dkprintf("copy_user_ranges(): 0x%lx PTE found\n", vaddr);
|
||||
|
||||
/* Page size */
|
||||
if (arch_get_smaller_page_size(NULL, -1, &ptepgsize,
|
||||
&ptep2align)) {
|
||||
|
||||
kprintf("ERROR: copy_user_ranges() "
|
||||
"(%p,%lx-%lx %lx,%lx):"
|
||||
"get pgsize failed\n", org->vm,
|
||||
range->start, range->end,
|
||||
range->flag, vaddr);
|
||||
|
||||
goto err_free_range_rollback;
|
||||
}
|
||||
|
||||
pgsize = ptepgsize;
|
||||
p2align = ptep2align;
|
||||
dkprintf("copy_user_ranges(): page size: %d\n", pgsize);
|
||||
|
||||
/* Get physical page */
|
||||
pg_vaddr = ihk_mc_alloc_aligned_pages(1, p2align, IHK_MC_AP_NOWAIT);
|
||||
|
||||
if (!pg_vaddr) {
|
||||
kprintf("ERROR: copy_user_ranges() allocating new page\n");
|
||||
goto err_free_range_rollback;
|
||||
}
|
||||
dkprintf("copy_user_ranges(): phys page allocated\n", pgsize);
|
||||
|
||||
/* Copy content */
|
||||
memcpy(pg_vaddr, vaddr, pgsize);
|
||||
dkprintf("copy_user_ranges(): memcpy OK\n", pgsize);
|
||||
|
||||
/* Set up new PTE */
|
||||
attr = vrflag_to_ptattr(range->flag);
|
||||
if (ihk_mc_pt_set_range(proc->vm->page_table, vaddr,
|
||||
vaddr + pgsize, virt_to_phys(pg_vaddr), attr)) {
|
||||
kprintf("ERROR: copy_user_ranges() "
|
||||
"(%p,%lx-%lx %lx,%lx):"
|
||||
"set range failed.\n",
|
||||
org->vm, range->start, range->end,
|
||||
range->flag, vaddr);
|
||||
|
||||
goto err_free_range_rollback;
|
||||
}
|
||||
dkprintf("copy_user_ranges(): new PTE set\n", pgsize);
|
||||
|
||||
vaddr += pgsize;
|
||||
}
|
||||
|
||||
insert_vm_range_list(proc->vm, range);
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&org->vm->memory_range_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_range_rollback:
|
||||
kfree(range);
|
||||
|
||||
err_rollback:
|
||||
|
||||
/* TODO: implement rollback */
|
||||
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&org->vm->memory_range_lock);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int update_process_page_table(struct process *process,
|
||||
@@ -167,6 +347,7 @@ int update_process_page_table(struct process *process,
|
||||
|
||||
attr = flag | PTATTR_USER | PTATTR_FOR_USER;
|
||||
attr |= (range->flag & VR_PROT_WRITE)? PTATTR_WRITABLE: 0;
|
||||
attr |= (range->flag & VR_PROT_EXEC)? 0: PTATTR_NO_EXECUTE;
|
||||
|
||||
p = range->start;
|
||||
while (p < range->end) {
|
||||
@@ -509,6 +690,10 @@ enum ihk_mc_pt_attribute vrflag_to_ptattr(unsigned long flag)
|
||||
attr |= PTATTR_WRITABLE;
|
||||
}
|
||||
|
||||
if (!(flag & VR_PROT_EXEC)) {
|
||||
attr |= PTATTR_NO_EXECUTE;
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
@@ -549,10 +734,9 @@ int add_process_memory_range(struct process *process,
|
||||
range->start, range->end, range->end - range->start,
|
||||
range->flag);
|
||||
} else {
|
||||
dkprintf("range: 0x%lX - 0x%lX => 0x%lX - 0x%lX (%ld) [%lx]\n",
|
||||
range->start, range->end, range->phys, range->phys +
|
||||
range->end - range->start, range->end - range->start,
|
||||
range->flag);
|
||||
dkprintf("range: 0x%lX - 0x%lX (%ld) [%lx]\n",
|
||||
range->start, range->end, range->end - range->start,
|
||||
range->flag);
|
||||
}
|
||||
|
||||
if (flag & VR_REMOTE) {
|
||||
@@ -1018,7 +1202,9 @@ static int do_page_fault_process(struct process *proc, void *fault_addr0, uint64
|
||||
|
||||
if (((range->flag & VR_PROT_MASK) == VR_PROT_NONE)
|
||||
|| ((reason & PF_WRITE)
|
||||
&& !(range->flag & VR_PROT_WRITE))) {
|
||||
&& !(range->flag & VR_PROT_WRITE))
|
||||
|| ((reason & PF_INSTR)
|
||||
&& !(range->flag & VR_PROT_EXEC))) {
|
||||
error = -EFAULT;
|
||||
kprintf("[%d]do_page_fault_process(%p,%lx,%lx):"
|
||||
"access denied. %d\n",
|
||||
@@ -1146,8 +1332,8 @@ int init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
start = end - size;
|
||||
|
||||
vrflag = VR_STACK | VR_DEMAND_PAGING;
|
||||
vrflag |= VR_PROT_READ | VR_PROT_WRITE | VR_PROT_EXEC;
|
||||
vrflag |= VRFLAG_PROT_TO_MAXPROT(vrflag);
|
||||
vrflag |= PROT_TO_VR_FLAG(pn->stack_prot);
|
||||
vrflag |= VR_MAXPROT_READ | VR_MAXPROT_WRITE | VR_MAXPROT_EXEC;
|
||||
#define NOPHYS ((uintptr_t)-1)
|
||||
if ((rc = add_process_memory_range(process, start, end, NOPHYS,
|
||||
vrflag, NULL, 0)) != 0) {
|
||||
|
||||
@@ -92,8 +92,8 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
|
||||
#undef SYSCALL_DELEGATED
|
||||
};
|
||||
|
||||
void check_signal(long rc, unsigned long *regs);
|
||||
void do_signal(long rc, unsigned long *regs, struct process *proc, struct sig_pending *pending);
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
void do_signal(long rc, void *regs, struct process *proc, struct sig_pending *pending);
|
||||
int copy_from_user(struct process *, void *, const void *, size_t);
|
||||
int copy_to_user(struct process *, void *, const void *, size_t);
|
||||
|
||||
@@ -101,7 +101,7 @@ int copy_to_user(struct process *, void *, const void *, size_t);
|
||||
static void do_mod_exit(int status);
|
||||
#endif
|
||||
|
||||
static void send_syscall(struct syscall_request *req, int cpu)
|
||||
static void send_syscall(struct syscall_request *req, int cpu, int pid)
|
||||
{
|
||||
struct ikc_scd_packet packet;
|
||||
struct syscall_response *res;
|
||||
@@ -147,7 +147,7 @@ static void send_syscall(struct syscall_request *req, int cpu)
|
||||
#ifdef SYSCALL_BY_IKC
|
||||
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
|
||||
packet.ref = cpu;
|
||||
packet.pid = cpu_local_var(current)->pid;
|
||||
packet.pid = pid ? pid : cpu_local_var(current)->pid;
|
||||
packet.arg = scp->request_rpa;
|
||||
dkprintf("send syscall, nr: %d, pid: %d\n", req->number, packet.pid);
|
||||
ihk_ikc_send(syscall_channel, &packet, 0);
|
||||
@@ -155,7 +155,8 @@ static void send_syscall(struct syscall_request *req, int cpu)
|
||||
}
|
||||
|
||||
|
||||
long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu)
|
||||
long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx,
|
||||
int cpu, int pid)
|
||||
{
|
||||
struct syscall_response *res;
|
||||
struct syscall_request req2 IHK_DMA_ALIGN;
|
||||
@@ -175,7 +176,7 @@ long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu
|
||||
}
|
||||
res = scp->response_va;
|
||||
|
||||
send_syscall(req, cpu);
|
||||
send_syscall(req, cpu, pid);
|
||||
|
||||
dkprintf("SC(%d)[%3d] waiting for host.. \n",
|
||||
ihk_mc_get_processor_id(),
|
||||
@@ -202,7 +203,7 @@ long do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx, int cpu
|
||||
req2.args[0] = PAGER_RESUME_PAGE_FAULT;
|
||||
req2.args[1] = error;
|
||||
|
||||
send_syscall(&req2, cpu);
|
||||
send_syscall(&req2, cpu, pid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +238,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
|
||||
/* XXX: send SIGKILL to all threads in this process */
|
||||
|
||||
flush_process_memory(proc); /* temporary hack */
|
||||
do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||
do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0);
|
||||
|
||||
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
||||
proc->status = PS_ZOMBIE;
|
||||
@@ -282,7 +283,7 @@ SYSCALL_DECLARE(exit_group)
|
||||
|
||||
/* XXX: send SIGKILL to all threads in this process */
|
||||
|
||||
do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||
do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0);
|
||||
|
||||
#define IS_DETACHED_PROCESS(proc) (1) /* should be implemented in the future */
|
||||
proc->status = PS_ZOMBIE;
|
||||
@@ -306,6 +307,8 @@ static void clear_host_pte(uintptr_t addr, size_t len)
|
||||
|
||||
ihk_mc_syscall_arg0(&ctx) = addr;
|
||||
ihk_mc_syscall_arg1(&ctx) = len;
|
||||
/* NOTE: 3rd parameter denotes new rpgtable of host process (if not zero) */
|
||||
ihk_mc_syscall_arg2(&ctx) = 0;
|
||||
|
||||
lerror = syscall_generic_forwarding(__NR_munmap, &ctx);
|
||||
if (lerror) {
|
||||
@@ -961,30 +964,56 @@ SYSCALL_DECLARE(clone)
|
||||
ihk_mc_user_context_t ctx1;
|
||||
struct syscall_request request1 IHK_DMA_ALIGN;
|
||||
|
||||
if(clone_flags == 0x1200011){
|
||||
// fork()
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
dkprintf("[%d] clone(): stack_pointr: 0x%lX\n",
|
||||
ihk_mc_get_processor_id(),
|
||||
(unsigned long)ihk_mc_syscall_arg1(ctx));
|
||||
dkprintf("clone(): stack_pointr passed in: 0x%lX, stack pointer of caller: 0x%lx\n",
|
||||
(unsigned long)ihk_mc_syscall_arg1(ctx),
|
||||
(unsigned long)ihk_mc_syscall_sp(ctx));
|
||||
|
||||
cpuid = obtain_clone_cpuid();
|
||||
|
||||
new = clone_process(cpu_local_var(current), ihk_mc_syscall_pc(ctx),
|
||||
ihk_mc_syscall_arg1(ctx));
|
||||
ihk_mc_syscall_arg1(ctx) ? ihk_mc_syscall_arg1(ctx) :
|
||||
ihk_mc_syscall_sp(ctx),
|
||||
clone_flags);
|
||||
|
||||
if (!new) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// /* Allocate new pid */
|
||||
// new->pid = ihk_atomic_inc_return(&pid_cnt);
|
||||
if (clone_flags & CLONE_VM) {
|
||||
new->pid = cpu_local_var(current)->pid;
|
||||
}
|
||||
/* fork() a new process on the host */
|
||||
else {
|
||||
request1.number = __NR_fork;
|
||||
new->pid = do_syscall(&request1, &ctx1, ihk_mc_get_processor_id(), 0);
|
||||
|
||||
if (new->pid == -1) {
|
||||
kprintf("ERROR: forking host process\n");
|
||||
|
||||
/* TODO: clean-up new */
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
new->pid = cpu_local_var(current)->pid;
|
||||
dkprintf("fork(): new pid: %d\n", new->pid);
|
||||
/* clear user space PTEs and set new rpgtable so that consequent
|
||||
* page faults will look up the right mappings */
|
||||
request1.number = __NR_munmap;
|
||||
request1.args[0] = new->vm->region.user_start;
|
||||
request1.args[1] = new->vm->region.user_end -
|
||||
new->vm->region.user_start;
|
||||
/* 3rd parameter denotes new rpgtable of host process */
|
||||
request1.args[2] = virt_to_phys(new->vm->page_table);
|
||||
|
||||
dkprintf("fork(): requesting PTE clear and rpgtable (0x%lx) update\n",
|
||||
request1.args[2]);
|
||||
|
||||
if (do_syscall(&request1, &ctx1, ihk_mc_get_processor_id(), new->pid)) {
|
||||
kprintf("ERROR: clearing PTEs in host process\n");
|
||||
}
|
||||
}
|
||||
|
||||
request1.number = __NR_gettid;
|
||||
new->tid = do_syscall(&request1, &ctx1, cpuid);
|
||||
new->tid = do_syscall(&request1, &ctx1, cpuid, new->pid);
|
||||
|
||||
if (clone_flags & CLONE_PARENT_SETTID) {
|
||||
dkprintf("clone_flags & CLONE_PARENT_SETTID: 0x%lX\n",
|
||||
@@ -1000,6 +1029,20 @@ SYSCALL_DECLARE(clone)
|
||||
new->thread.clear_child_tid = (int*)ihk_mc_syscall_arg3(ctx);
|
||||
}
|
||||
|
||||
if (clone_flags & CLONE_CHILD_SETTID) {
|
||||
unsigned long phys;
|
||||
dkprintf("clone_flags & CLONE_CHILD_SETTID: 0x%lX\n",
|
||||
(unsigned long)ihk_mc_syscall_arg3(ctx));
|
||||
|
||||
if (ihk_mc_pt_virt_to_phys(new->vm->page_table,
|
||||
(void *)ihk_mc_syscall_arg3(ctx), &phys)) {
|
||||
kprintf("ERROR: looking up physical addr for child process\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*((int*)phys_to_virt(phys)) = new->tid;
|
||||
}
|
||||
|
||||
if (clone_flags & CLONE_SETTLS) {
|
||||
dkprintf("clone_flags & CLONE_SETTLS: 0x%lX\n",
|
||||
(unsigned long)ihk_mc_syscall_arg4(ctx));
|
||||
@@ -1023,7 +1066,7 @@ SYSCALL_DECLARE(clone)
|
||||
SYSCALL_DECLARE(set_tid_address)
|
||||
{
|
||||
cpu_local_var(current)->thread.clear_child_tid =
|
||||
(int*)ihk_mc_syscall_arg2(ctx);
|
||||
(int*)ihk_mc_syscall_arg0(ctx);
|
||||
|
||||
return cpu_local_var(current)->pid;
|
||||
}
|
||||
@@ -1485,7 +1528,7 @@ SYSCALL_DECLARE(futex)
|
||||
|
||||
request.args[0] = __phys;
|
||||
|
||||
int r = do_syscall(&request, ctx, ihk_mc_get_processor_id());
|
||||
int r = do_syscall(&request, ctx, ihk_mc_get_processor_id(), 0);
|
||||
|
||||
if (r < 0) {
|
||||
return -EFAULT;
|
||||
|
||||
Reference in New Issue
Block a user