diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index ea619eda..55cfea0d 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -20,6 +20,54 @@ #define SCD_MSG_SYSCALL_ONESIDE 0x4 +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +/* Cloning flags. */ +# define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */ +# define CLONE_VM 0x00000100 /* Set if VM shared between processes. */ +# define CLONE_FS 0x00000200 /* Set if fs info shared between processes. */ +# define CLONE_FILES 0x00000400 /* Set if open files shared between processes. */ +# define CLONE_SIGHAND 0x00000800 /* Set if signal handlers shared. */ +# define CLONE_PTRACE 0x00002000 /* Set if tracing continues on the child. */ +# define CLONE_VFORK 0x00004000 /* Set if the parent wants the child to + wake it up on mm_release. */ +# define CLONE_PARENT 0x00008000 /* Set if we want to have the same + parent as the cloner. */ +# define CLONE_THREAD 0x00010000 /* Set to add to same thread group. */ +# define CLONE_NEWNS 0x00020000 /* Set to create new namespace. */ +# define CLONE_SYSVSEM 0x00040000 /* Set to shared SVID SEM_UNDO semantics. */ +# define CLONE_SETTLS 0x00080000 /* Set TLS info. */ +# define CLONE_PARENT_SETTID 0x00100000 /* Store TID in userlevel buffer + before MM copy. */ +# define CLONE_CHILD_CLEARTID 0x00200000 /* Register exit futex and memory + location to clear. */ +# define CLONE_DETACHED 0x00400000 /* Create clone detached. */ +# define CLONE_UNTRACED 0x00800000 /* Set if the tracing process can't + force CLONE_PTRACE on this clone. */ +# define CLONE_CHILD_SETTID 0x01000000 /* Store TID in userlevel buffer in + the child. */ +# define CLONE_NEWUTS 0x04000000 /* New utsname group. */ +# define CLONE_NEWIPC 0x08000000 /* New ipcs. */ +# define CLONE_NEWUSER 0x10000000 /* New user namespace. */ +# define CLONE_NEWPID 0x20000000 /* New pid namespace. */ +# define CLONE_NEWNET 0x40000000 /* New network namespace. */ +# define CLONE_IO 0x80000000 /* Clone I/O context. */ + +struct user_desc { + unsigned int entry_number; + unsigned int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; + unsigned int lm:1; +}; struct ikc_scd_packet { int msg; int ref; diff --git a/kernel/syscall.c b/kernel/syscall.c index 554316d0..aa71f599 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -10,6 +10,11 @@ #include #include #include +#include +#include + +/* Headers taken from kitten LWK */ +#include #define SYSCALL_BY_IKC @@ -253,6 +258,13 @@ SYSCALL_DECLARE(munmap) address + len); } +SYSCALL_DECLARE(mprotect) +{ + dkprintf("mprotect returns 0\n"); + return 0; +} + + SYSCALL_DECLARE(getpid) { return cpu_local_var(current)->pid; @@ -286,6 +298,50 @@ long sys_getxid(int n, aal_mc_user_context_t *ctx) return do_syscall(&request, ctx); } +long do_arch_prctl(unsigned long code, unsigned long address) +{ + int err = 0; + enum aal_asr_type type; + + switch (code) { + case ARCH_SET_FS: + case ARCH_GET_FS: + type = AAL_ASR_X86_FS; + break; + case ARCH_GET_GS: + type = AAL_ASR_X86_GS; + break; + case ARCH_SET_GS: + return -ENOTSUPP; + default: + return -EINVAL; + } + + switch (code) { + case ARCH_SET_FS: + case ARCH_SET_GS: + err = aal_mc_arch_set_special_register(type, address); + break; + case ARCH_GET_FS: + case ARCH_GET_GS: + err = aal_mc_arch_get_special_register(type, + (unsigned long*)address); + break; + default: + break; + } + + return err; +} + + +SYSCALL_DECLARE(arch_prctl) +{ + return do_arch_prctl(aal_mc_syscall_arg0(ctx), + aal_mc_syscall_arg1(ctx)); +} + +#if 0 long sys_arch_prctl(int n, aal_mc_user_context_t *ctx) { unsigned long code = aal_mc_syscall_arg0(ctx); @@ -327,6 +383,68 @@ SYSCALL_DECLARE(clone) dkprintf("Clone ret.\n"); return new->pid; } +#endif + +SYSCALL_DECLARE(clone) +{ + int i; + int cpuid = -1; + int clone_flags = aal_mc_syscall_arg0(ctx); + //unsigned long flags; /* spinlock */ + struct aal_mc_cpu_info *cpu_info = aal_mc_get_cpu_info(); + struct process *new; + + kputs(";sys_clone\n"); + + //flags = aal_mc_spinlock_lock(&cpu_status_lock); + for (i = 0; i < cpu_info->ncpus; i++) { + if(get_cpu_local_var(i)->status == CPU_STATUS_IDLE) + cpuid = i; + } + if(cpuid < 0) return -EAGAIN; + + new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx), + aal_mc_syscall_arg1(ctx)); + + /* TODO: allocate new pid */ + new->pid = 0xc107e; + + if (clone_flags & CLONE_SETTLS) { + dkprintf("clone_flags & CLONE_SETTLS\n"); + + new->vm->region.tlsblock_base + = (unsigned long)aal_mc_syscall_arg4(ctx); + } + else + new->vm->region.tlsblock_base = 0; + + if (clone_flags & CLONE_PARENT_SETTID) { + unsigned long pptid; + int *vptid; + if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, + aal_mc_syscall_arg2(ctx), &pptid)) + return -EFAULT; + + vptid = (int *)phys_to_virt(pptid); + *vptid = 1; + } + + new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) + ? aal_mc_syscall_arg3(ctx) + : NULL; + + + aal_mc_syscall_ret(new->uctx) = 0; + get_cpu_local_var(cpuid)->next = new; + get_cpu_local_var(cpuid)->status = CPU_STATUS_RUNNING; + //aal_mc_spinlock_unlock(&cpu_status_lock, flags); + aal_mc_interrupt_cpu(aal_mc_get_cpu_info()->hw_ids[cpuid], 0xd1); + + dkprintf("clone: kicking scheduler!\n"); + while (1) { cpu_halt(); } + + return new->pid; +} SYSCALL_DECLARE(writev) @@ -375,6 +493,7 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [5] = sys_fstat, [8] = sys_lseek, [9] = sys_mmap, + [10] = sys_mprotect, [11] = sys_munmap, [12] = sys_brk, [16] = sys_ioctl, @@ -394,6 +513,21 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = { [231] = sys_exit_group, }; +#if 0 + +aal_spinlock_t cpu_status_lock; + +static int clone_init(void) +{ + unsigned long flags; + + aal_mc_spinlock_init(&cpu_status_lock); + + return 0; +} + +#endif + long syscall(int num, aal_mc_user_context_t *ctx) { long l; @@ -451,3 +585,4 @@ void __host_update_process_range(struct process *process, } cpu_enable_interrupt(); } +