From d2591c6d256b95187812b7addba9126adaa2bad3 Mon Sep 17 00:00:00 2001 From: Taku Shimosawa Date: Fri, 6 Jan 2012 17:06:42 +0900 Subject: [PATCH] temp --- kernel/ap.c | 2 +- kernel/copy.c | 1 + kernel/host.c | 29 ++++++++-------- kernel/include/cls.h | 1 + kernel/include/process.h | 16 ++++++--- kernel/init.c | 16 +++++++-- kernel/process.c | 69 +++++++++++++++++++++++++++++--------- kernel/syscall.c | 60 ++++++++++++++++++++++++--------- linux/mod_mcctrl/control.c | 56 +++++++++++++++++++++++-------- linux/mod_mcctrl/ikc.c | 36 ++++++++++++++++++-- linux/mod_mcctrl/mcctrl.h | 3 +- linux/mod_mcctrl/syscall.c | 28 +++++++++++++--- 12 files changed, 244 insertions(+), 73 deletions(-) diff --git a/kernel/ap.c b/kernel/ap.c index cf9dce13..1da79aa1 100644 --- a/kernel/ap.c +++ b/kernel/ap.c @@ -24,7 +24,7 @@ static void ap_wait(void) kprintf("ap started.\n"); kmalloc_init(); sched_init(); - init_host_syscall_channel(); +/* init_host_syscall_channel(); */ schedule(); } diff --git a/kernel/copy.c b/kernel/copy.c index 8affde29..ebc47d96 100644 --- a/kernel/copy.c +++ b/kernel/copy.c @@ -28,5 +28,6 @@ int memcpy_async(unsigned long dest, unsigned long src, barrier(); } } + return 0; } diff --git a/kernel/host.c b/kernel/host.c index 6d959e5e..5c7864f7 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -53,26 +53,27 @@ static void process_msg_prepare_process(unsigned long rphys) /* TODO: Maybe we need flag */ if (i == 0) { - proc->region.text_start = s; - proc->region.text_end = e; + proc->vm->region.text_start = s; + proc->vm->region.text_end = e; } else if (i == 1) { - proc->region.data_start = s; - proc->region.data_end = e; + proc->vm->region.data_start = s; + proc->vm->region.data_end = e; } else { - proc->region.data_start = - (s < proc->region.data_start ? - s : proc->region.data_start); - proc->region.data_end = - (e > proc->region.data_end ? - e : proc->region.data_end); + proc->vm->region.data_start = + (s < proc->vm->region.data_start ? + s : proc->vm->region.data_start); + proc->vm->region.data_end = + (e > proc->vm->region.data_end ? + e : proc->vm->region.data_end); } } - proc->region.brk_start = proc->region.brk_end = proc->region.data_end; - proc->region.map_start = proc->region.map_end = + proc->vm->region.brk_start = proc->vm->region.brk_end = + proc->vm->region.data_end; + proc->vm->region.map_start = proc->vm->region.map_end = (USER_END / 3) & LARGE_PAGE_MASK; /* Map system call stuffs */ - addr = proc->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT; + addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT; e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT; add_process_memory_range(proc, addr, e, cpu_local_var(scp).doorbell_pa, @@ -92,7 +93,7 @@ static void process_msg_prepare_process(unsigned long rphys) init_process_stack(proc); kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid, - proc->page_table); + proc->vm->page_table); aal_mc_free(pn); diff --git a/kernel/include/cls.h b/kernel/include/cls.h index e3c279fd..2057150a 100644 --- a/kernel/include/cls.h +++ b/kernel/include/cls.h @@ -17,6 +17,7 @@ struct cpu_local_var { struct malloc_header free_list; struct process idle; + struct process_vm idle_vm; struct process *current; struct process *next; diff --git a/kernel/include/process.h b/kernel/include/process.h index e223edcd..727a03ca 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #define VR_STACK 0x1 @@ -28,20 +29,27 @@ struct vm_regions { unsigned long stack_start, stack_end; }; +struct process_vm { + aal_atomic_t refcount; + + struct page_table *page_table; + struct list_head vm_range_list; + struct vm_regions region; +}; + struct process { int pid; int status; - struct page_table *page_table; - struct list_head vm_range_list; - - struct vm_regions region; + struct process_vm *vm; aal_mc_kernel_context_t ctx; aal_mc_user_context_t *uctx; }; struct process *create_process(unsigned long user_pc); +struct process *clone_process(struct process *org, + unsigned long pc, unsigned long sp); void destroy_process(struct process *proc); void free_process_memory(struct process *proc); diff --git a/kernel/init.c b/kernel/init.c index ec7a8f0d..68fe3c10 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -38,7 +38,13 @@ static void dma_test(void) { struct aal_dma_request req; unsigned long fin = 0; + int i; + for (i = 0; i < 8; i++) { + data[i] = 8 - i; + } + + kprintf("DMA Test Started.\n"); memset(&req, 0, sizeof(req)); req.src_phys = virt_to_phys(data); req.dest_phys = virt_to_phys(data + 256); @@ -46,11 +52,17 @@ static void dma_test(void) req.notify = (void *)virt_to_phys(&fin); req.priv = (void *)0x2984; - aal_mc_dma_request(0, &req); + kprintf("VtoP : %p, %lx\n", data, virt_to_phys(data)); + if (aal_mc_dma_request(0, &req) != 0) { + kprintf("Failed to request DMA!\n"); + } + + kprintf("DMA Test Wait.\n"); while (!fin) { barrier(); } + kprintf("DMA Test End.\n"); } extern char *aal_mc_get_kernel_args(void); @@ -127,7 +139,7 @@ static void post_init(void) cpu_pause(); } - init_host_syscall_channel(); +/* init_host_syscall_channel(); */ ap_start(); } diff --git a/kernel/process.c b/kernel/process.c index 4694064c..46c41c12 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -6,6 +6,13 @@ #include #include +void init_process_vm(struct process_vm *vm) +{ + aal_atomic_set(&vm->refcount, 1); + INIT_LIST_HEAD(&vm->vm_range_list); + vm->page_table = aal_mc_pt_create(); +} + struct process *create_process(unsigned long user_pc) { struct process *proc; @@ -17,8 +24,33 @@ struct process *create_process(unsigned long user_pc) aal_mc_init_user_process(&proc->ctx, &proc->uctx, ((char *)proc) + PAGE_SIZE, user_pc, 0); - INIT_LIST_HEAD(&proc->vm_range_list); - proc->page_table = aal_mc_pt_create(); + proc->vm = (struct process_vm *)(proc + 1); + + init_process_vm(proc->vm); + + return proc; +} + +struct process *clone_process(struct process *org, unsigned long pc, + unsigned long sp) +{ + struct process *proc; + + proc = aal_mc_alloc_pages(1, 0); + + memset(proc, 0, sizeof(struct process)); + + aal_mc_init_user_process(&proc->ctx, &proc->uctx, + ((char *)proc) + PAGE_SIZE, pc, sp); + + memcpy(proc->uctx, org->uctx, sizeof(*org->uctx)); + aal_mc_modify_user_context(proc->uctx, AAL_UCR_STACK_POINTER, + sp); + aal_mc_modify_user_context(proc->uctx, AAL_UCR_PROGRAM_COUNTER, + pc); + + aal_atomic_inc(&org->vm->refcount); + proc->vm = org->vm; return proc; } @@ -33,7 +65,7 @@ void update_process_page_table(struct process *process, struct vm_range *range, p = range->start; while (p < range->end) { - aal_mc_pt_set_page(process->page_table, (void *)p, + aal_mc_pt_set_page(process->vm->page_table, (void *)p, pa, PTATTR_WRITABLE | PTATTR_USER | flag); pa += PAGE_SIZE; @@ -73,7 +105,7 @@ int add_process_memory_range(struct process *process, __host_update_process_range(process, range); } - list_add_tail(&range->list, &process->vm_range_list); + list_add_tail(&range->list, &process->vm->vm_range_list); return 0; } @@ -90,22 +122,20 @@ void init_process_stack(struct process *process) virt_to_phys(stack), VR_STACK); /* TODO: fill with actual value of argc, argv, envp */ - kprintf("%lx, %p\n", virt_to_phys(stack), p); - p[-1] = 0; /* AT_NULL */ p[-2] = 0; p[-3] = USER_END - sizeof(unsigned long) * 2; p[-4] = 0; /* env: "" */ p[-5] = 0x41; /* argv(0): "a" */ - p[-6] = USER_END - sizeof(unsigned long) * 4; /* envp: END - 8 */ + p[-6] = 0; /* envp: NULL */ p[-7] = 0; /* argv[1] = NULL */ p[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */ p[-9] = 1; /* argc */ aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER, - USER_END - sizeof(unsigned long) * 8); - process->region.stack_end = USER_END; - process->region.stack_start = USER_END - PAGE_SIZE; + USER_END - sizeof(unsigned long) * 9); + process->vm->region.stack_end = USER_END; + process->vm->region.stack_start = USER_END - PAGE_SIZE; } @@ -148,7 +178,7 @@ int remove_process_region(struct process *proc, /* We defer freeing to the time of exit */ while (start < end) { - aal_mc_pt_clear_page(proc->page_table, (void *)start); + aal_mc_pt_clear_page(proc->vm->page_table, (void *)start); start += PAGE_SIZE; } @@ -160,7 +190,11 @@ void free_process_memory(struct process *proc) { struct vm_range *range, *next; - list_for_each_entry_safe(range, next, &proc->vm_range_list, + if (!aal_atomic_dec_and_test(&proc->vm->refcount)) { + return; + } + + list_for_each_entry_safe(range, next, &proc->vm->vm_range_list, list) { if (!(range->flag & VR_REMOTE) && !(range->flag & VR_IO_NOCACHE) && @@ -195,6 +229,9 @@ void sched_init(void) struct process *idle_process = &cpu_local_var(idle); memset(idle_process, 0, sizeof(struct process)); + memset(&cpu_local_var(idle_vm), 0, sizeof(struct process_vm)); + + idle_process->vm = &cpu_local_var(idle_vm); aal_mc_init_context(&idle_process->ctx, NULL, idle); @@ -220,9 +257,11 @@ void schedule(void) cpu_enable_interrupt(); if (switch_ctx) { - kprintf("schedule: %p (%p) => %p (%p) \n", prev, - prev ? prev->page_table : NULL, next, next->page_table); - aal_mc_load_page_table(next->page_table); + kprintf("[%d] schedule: %d => %d \n", + aal_mc_get_processor_id(), + prev ? prev->pid : 0, next ? next->pid : 0); + + aal_mc_load_page_table(next->vm->page_table); if (prev) { aal_mc_switch_context(&prev->ctx, &next->ctx); diff --git a/kernel/syscall.c b/kernel/syscall.c index 15b96978..ce6b317e 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -18,12 +18,10 @@ static void send_syscall(struct syscall_request *req) struct ikc_scd_packet packet; struct syscall_response *res = cpu_local_var(scp).response_va; unsigned long fin; + int w; res->status = 0; - - kprintf("CPU : %lx\n", aal_mc_get_processor_id()); - kprintf("Target is %lx\n", cpu_local_var(scp).request_pa); - kprintf("SC req: %ld %ld %ld\n", req->valid, req->number, req->args[0]); + req->valid = 0; memcpy_async(cpu_local_var(scp).request_pa, virt_to_phys(req), sizeof(*req), 0, &fin); @@ -31,10 +29,12 @@ static void send_syscall(struct syscall_request *req) memcpy_async_wait(&cpu_local_var(scp).post_fin); cpu_local_var(scp).post_va->v[0] = cpu_local_var(scp).post_idx; + w = aal_mc_get_processor_id() + 1; + memcpy_async_wait(&fin); cpu_local_var(scp).request_va->valid = 1; - *(unsigned int *)cpu_local_var(scp).doorbell_va = 1; + *(unsigned int *)cpu_local_var(scp).doorbell_va = w; #ifdef SYSCALL_BY_IKC packet.msg = SCD_MSG_SYSCALL_ONESIDE; @@ -61,7 +61,7 @@ static int do_syscall(struct syscall_request *req) long sys_brk(int n, aal_mc_user_context_t *ctx) { unsigned long address = aal_mc_syscall_arg0(ctx); - struct vm_regions *region = &cpu_local_var(current)->region; + struct vm_regions *region = &cpu_local_var(current)->vm->region; region->brk_end = extend_process_region(cpu_local_var(current), @@ -73,13 +73,12 @@ long sys_brk(int n, aal_mc_user_context_t *ctx) #define SYSCALL_DECLARE(name) long sys_##name(int n, aal_mc_user_context_t *ctx) #define SYSCALL_HEADER struct syscall_request request; \ - request.valid = 0; \ request.number = n #define SYSCALL_ARG_D(n) request.args[n] = aal_mc_syscall_arg##n(ctx) #define SYSCALL_ARG_MO(n) \ do { \ unsigned long __phys; \ - if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \ + if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, \ (void *)aal_mc_syscall_arg##n(ctx),\ &__phys)) { \ return -EFAULT; \ @@ -89,7 +88,7 @@ long sys_brk(int n, aal_mc_user_context_t *ctx) #define SYSCALL_ARG_MI(n) \ do { \ unsigned long __phys; \ - if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \ + if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, \ (void *)aal_mc_syscall_arg##n(ctx),\ &__phys)) { \ return -EFAULT; \ @@ -201,7 +200,7 @@ SYSCALL_DECLARE(exit_group) SYSCALL_DECLARE(mmap) { unsigned long address, ret; - struct vm_regions *region = &cpu_local_var(current)->region; + struct vm_regions *region = &cpu_local_var(current)->vm->region; /* anonymous */ if (aal_mc_syscall_arg3(ctx) & 0x22) { @@ -240,12 +239,12 @@ SYSCALL_DECLARE(getpid) return cpu_local_var(current)->pid; } -long sys_uname(int n, aal_mc_user_context_t *ctx) +SYSCALL_DECLARE(uname) { - struct syscall_request request; + SYSCALL_HEADER; unsigned long phys; - if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, + if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, (void *)aal_mc_syscall_arg0(ctx), &phys)) { return -EFAULT; } @@ -253,7 +252,7 @@ long sys_uname(int n, aal_mc_user_context_t *ctx) request.number = n; request.args[0] = phys; - return do_syscall(&request), stop(); + return do_syscall(&request); } long sys_getxid(int n, aal_mc_user_context_t *ctx) @@ -284,6 +283,29 @@ long sys_arch_prctl(int n, aal_mc_user_context_t *ctx) return -EINVAL; } +SYSCALL_DECLARE(clone) +{ + /* Clone a new thread */ + struct process *new; + struct syscall_request request; + + new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx), + aal_mc_syscall_arg1(ctx)); + /* XXX Assign new pid! */ + new->pid = cpu_local_var(current)->pid; + kprintf("Cloned: %p \n", new); + + aal_mc_syscall_ret(new->uctx) = 0; + + /* Hope it is scheduled after... :) */ + request.number = n; + request.args[0] = (unsigned long)new; + /* Sync */ + do_syscall(&request); + kprintf("Clone ret.\n"); + return new->pid; +} + static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [0] = sys_read, [1] = sys_write, @@ -298,6 +320,7 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [17] = sys_pread, [18] = sys_pwrite, [39] = sys_getpid, + [56] = sys_clone, [63] = sys_uname, [102] = sys_getxid, [104] = sys_getxid, @@ -309,22 +332,29 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [231] = sys_exit_group, }; +#define DEBUG_PRINT_SC + long syscall(int num, aal_mc_user_context_t *ctx) { long l; cpu_enable_interrupt(); - kprintf("SC(%d)[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", +#ifdef DEBUG_PRINT_SC + kprintf("SC(%d)[%3d](%lx, %lx) @ %lx | %lx = ", aal_mc_get_processor_id(), num, aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx), aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx), aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx), aal_mc_syscall_sp(ctx)); +#endif if (syscall_table[num]) { l = syscall_table[num](num, ctx); +#ifdef DEBUG_PRINT_SC + kprintf(" %lx\n", l); +#endif return l; } else { kprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num, diff --git a/linux/mod_mcctrl/control.c b/linux/mod_mcctrl/control.c index 63504f98..e83cec4d 100644 --- a/linux/mod_mcctrl/control.c +++ b/linux/mod_mcctrl/control.c @@ -102,6 +102,8 @@ int mcexec_load_image(aal_os_t os, struct program_transfer *__user upt) return 0; } +extern unsigned long last_thread_exec; + static long mcexec_start_image(aal_os_t os, struct program_load_desc * __user udesc) { @@ -117,6 +119,8 @@ static long mcexec_start_image(aal_os_t os, c = channels + desc.cpu; mcctrl_ikc_set_recv_cpu(desc.cpu); + + last_thread_exec = desc.cpu; isp.msg = SCD_MSG_SCHEDULE_PROCESS; isp.ref = desc.cpu; @@ -139,11 +143,14 @@ int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg) int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, struct syscall_request *sc); +static int remaining_job, base_cpu, job_pos; +extern int num_channels; + int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req) { struct syscall_wait_desc swd; struct mcctrl_channel *c; - unsigned long s, w; + unsigned long s, w, d; if (copy_from_user(&swd, req, sizeof(swd.cpu))) { return -EFAULT; @@ -157,20 +164,38 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req) #else while (1) { rdtscll(s); - while (!(*c->param.doorbell_va)) { - mb(); - cpu_relax(); - rdtscll(w); - if (w > s + 1024 * 1024 * 1024 * 1) { - return -EINTR; + if (!remaining_job) { + while (!(*c->param.doorbell_va)) { + mb(); + cpu_relax(); + rdtscll(w); + if (w > s + 1024UL * 1024 * 1024 * 10) { + return -EINTR; + } } + d = (*c->param.doorbell_va) - 1; + *c->param.doorbell_va = 0; + + if (d < 0 || d >= num_channels) { + d = 0; + } + base_cpu = d; + job_pos = 0; + remaining_job = 1; + } else { + job_pos++; } - *c->param.doorbell_va = 0; - printk("(%p) %ld SC %ld: %lx\n", - c->param.request_va, - c->param.request_va->valid, - c->param.request_va->number, - c->param.request_va->args[0]); + + for (; job_pos < num_channels; job_pos++) { + if (base_cpu + job_pos >= num_channels) { + c = channels + + (base_cpu + job_pos - num_channels); + } else { + c = channels + base_cpu + job_pos; + } + if (c->param.request_va && + c->param.request_va->valid) { + c->param.request_va->valid = 0; /* ack */ if (__do_in_kernel_syscall(os, c, c->param.request_va)) { #endif if (copy_to_user(&req->sr, c->param.request_va, @@ -178,8 +203,11 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req) return -EFAULT; } #ifndef DO_USER_MODE - break; + return 0; } + } + } + remaining_job = 0; } #endif return 0; diff --git a/linux/mod_mcctrl/ikc.c b/linux/mod_mcctrl/ikc.c index 2029c6be..2971151c 100644 --- a/linux/mod_mcctrl/ikc.c +++ b/linux/mod_mcctrl/ikc.c @@ -7,7 +7,7 @@ #include #include -static int num_channels; +int num_channels; struct mcctrl_channel *channels; @@ -45,6 +45,21 @@ int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp) return aal_ikc_send(channels[cpu].c, pisp, 0); } +int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg) +{ + struct ikc_scd_packet packet; + + if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) { + return -EINVAL; + } + + packet.msg = msg; + packet.ref = ref; + packet.arg = arg; + + return aal_ikc_send(channels[cpu].c, &packet, 0); +} + int mcctrl_ikc_set_recv_cpu(int cpu) { aal_ikc_channel_set_cpu(channels[cpu].c, @@ -54,6 +69,15 @@ int mcctrl_ikc_set_recv_cpu(int cpu) return 0; } +int mcctrl_ikc_is_valid_thread(int cpu) +{ + if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) { + return 0; + } else { + return 1; + } +} + unsigned long *mcctrl_doorbell_va; unsigned long mcctrl_doorbell_pa; @@ -68,6 +92,8 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys) return; } + printk("IKC init: %d\n", cpu); + phys = aal_device_map_memory(aal_os_to_dev(os), rphys, sizeof(struct ikc_scd_init_param)); rpm = ioremap_wc(phys, sizeof(struct ikc_scd_init_param)); @@ -79,6 +105,7 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys) pmc->param.post_va = (void *)__get_free_page(GFP_KERNEL); pmc->param.post_pa = virt_to_phys(pmc->param.post_va); memset(pmc->param.doorbell_va, 0, PAGE_SIZE); + memset(pmc->param.request_va, 0, PAGE_SIZE); memset(pmc->param.post_va, 0, PAGE_SIZE); pmc->param.response_rpa = rpm->response_page; @@ -86,8 +113,8 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys) = aal_device_map_memory(aal_os_to_dev(os), pmc->param.response_rpa, PAGE_SIZE); - pmc->param.response_va = ioremap_wc(pmc->param.response_pa, - PAGE_SIZE); + pmc->param.response_va = ioremap_cache(pmc->param.response_pa, + PAGE_SIZE); pmc->dma_buf = (void *)__get_free_pages(GFP_KERNEL, DMA_PIN_SHIFT - PAGE_SHIFT); @@ -103,6 +130,9 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys) printk("Request: %lx, Response: %lx, Doorbell: %lx\n", pmc->param.request_pa, pmc->param.response_rpa, pmc->param.doorbell_pa); + printk("Request: %p, Response: %p, Doorbell: %p\n", + pmc->param.request_va, pmc->param.response_va, + pmc->param.doorbell_va); aal_ikc_send(pmc->c, &packet, 0); diff --git a/linux/mod_mcctrl/mcctrl.h b/linux/mod_mcctrl/mcctrl.h index dbc7eb89..26fc9426 100644 --- a/linux/mod_mcctrl/mcctrl.h +++ b/linux/mod_mcctrl/mcctrl.h @@ -61,5 +61,6 @@ struct mcctrl_channel { }; int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp); - +int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg); +int mcctrl_ikc_is_valid_thread(int cpu); #endif diff --git a/linux/mod_mcctrl/syscall.c b/linux/mod_mcctrl/syscall.c index d7e6bddf..dabdec12 100644 --- a/linux/mod_mcctrl/syscall.c +++ b/linux/mod_mcctrl/syscall.c @@ -76,6 +76,10 @@ static unsigned long translate_remote_va(struct mcctrl_channel *c, return -EFAULT; } +unsigned long last_thread_exec = 0; + +extern struct mcctrl_channel *channels; + int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, struct syscall_request *sc) { @@ -84,7 +88,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, unsigned long pa; switch (sc->number) { - case 0: + case 0: /* read */ case 1024: if (sc->number & 1024) { sc->args[1] = translate_remote_va(c, sc->args[1]); @@ -108,7 +112,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, __return_syscall(c, ret); return 0; - case 1: + case 1: /* write */ case 1025: if (sc->number & 1024) { sc->args[1] = translate_remote_va(c, sc->args[1]); @@ -131,7 +135,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, __return_syscall(c, ret); return 0; - case 2: + case 2: /* open */ case 1026: if (sc->number & 1024) { sc->args[0] = translate_remote_va(c, sc->args[0]); @@ -155,11 +159,27 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c, __return_syscall(c, ret); return 0; - case 3: + case 3: /* Close */ ret = sys_close(sc->args[0]); __return_syscall(c, ret); return 0; + case 56: /* Clone */ + last_thread_exec++; + if (mcctrl_ikc_is_valid_thread(last_thread_exec)) { + printk("Clone notification: %lx\n", sc->args[0]); + if (channels[last_thread_exec].param.post_va) { + memcpy(channels[last_thread_exec].param.post_va, + c->param.post_va, PAGE_SIZE); + } + mcctrl_ikc_send_msg(last_thread_exec, + SCD_MSG_SCHEDULE_PROCESS, + last_thread_exec, sc->args[0]); + } + + __return_syscall(c, 0); + return 0; + default: if (sc->number & 1024) { __return_syscall(c, -EFAULT);