futex and rlimit
This commit is contained in:
252
kernel/syscall.c
252
kernel/syscall.c
@ -1,6 +1,7 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <cpulocal.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
#include <aal/ikc.h>
|
||||
@ -12,9 +13,12 @@
|
||||
#include <uio.h>
|
||||
#include <aal/lock.h>
|
||||
#include <ctype.h>
|
||||
#include <waitq.h>
|
||||
#include <rlimit.h>
|
||||
|
||||
/* Headers taken from kitten LWK */
|
||||
#include <lwk/stddef.h>
|
||||
#include <futex.h>
|
||||
|
||||
#define SYSCALL_BY_IKC
|
||||
|
||||
@ -26,6 +30,10 @@
|
||||
#define dkprintf(...)
|
||||
#endif
|
||||
|
||||
static aal_spinlock_t sysc_lock = { 0 };
|
||||
|
||||
static aal_atomic_t pid_cnt = AAL_ATOMIC_INIT(1024);
|
||||
|
||||
int memcpy_async(unsigned long dest, unsigned long src,
|
||||
unsigned long len, int wait, unsigned long *notify);
|
||||
|
||||
@ -58,6 +66,7 @@ static void send_syscall(struct syscall_request *req)
|
||||
packet.arg = cpu_local_var(scp).request_rpa;
|
||||
|
||||
aal_ikc_send(cpu_local_var(syscall_channel), &packet, 0);
|
||||
//aal_ikc_send(get_cpu_local_var(0)->syscall_channel, &packet, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -151,8 +160,59 @@ SYSCALL_DECLARE(open)
|
||||
SYSCALL_FOOTER;
|
||||
}
|
||||
|
||||
static DECLARE_WAITQ(my_waitq);
|
||||
|
||||
SYSCALL_DECLARE(ioctl)
|
||||
{
|
||||
|
||||
switch (aal_mc_syscall_arg0(ctx)) {
|
||||
|
||||
case 0: {
|
||||
struct waitq_entry my_wait;
|
||||
waitq_init_entry(&my_wait, cpu_local_var(current));
|
||||
|
||||
dkprintf("CPU[%d] pid[%d] going to sleep...\n",
|
||||
cpu_local_var(current)->cpu_id,
|
||||
cpu_local_var(current)->pid);
|
||||
|
||||
waitq_prepare_to_wait(&my_waitq, &my_wait, PS_INTERRUPTIBLE);
|
||||
schedule();
|
||||
|
||||
waitq_finish_wait(&my_waitq, &my_wait);
|
||||
|
||||
dkprintf("CPU[%d] pid[%d] woke up!\n",
|
||||
cpu_local_var(current)->cpu_id,
|
||||
cpu_local_var(current)->pid);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
|
||||
dkprintf("CPU[%d] pid[%d] waking up everyone..\n",
|
||||
cpu_local_var(current)->cpu_id,
|
||||
cpu_local_var(current)->pid);
|
||||
|
||||
waitq_wakeup(&my_waitq);
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
dkprintf("[%d] pid %d made an ioctl\n",
|
||||
cpu_local_var(current)->cpu_id,
|
||||
cpu_local_var(current)->pid);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
dkprintf("ioctl() unimplemented\n");
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
SYSCALL_HEADER;
|
||||
|
||||
/* Very ad-hoc for termios */
|
||||
@ -163,6 +223,7 @@ SYSCALL_DECLARE(ioctl)
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(read)
|
||||
@ -195,9 +256,14 @@ SYSCALL_DECLARE(pwrite)
|
||||
|
||||
SYSCALL_DECLARE(close)
|
||||
{
|
||||
kprintf("[%d] close() \n", aal_mc_get_processor_id());
|
||||
return -EBADF;
|
||||
|
||||
/*
|
||||
SYSCALL_HEADER;
|
||||
SYSCALL_ARGS_1(D);
|
||||
SYSCALL_FOOTER;
|
||||
*/
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(lseek)
|
||||
@ -322,6 +388,11 @@ long do_arch_prctl(unsigned long code, unsigned long address)
|
||||
|
||||
switch (code) {
|
||||
case ARCH_SET_FS:
|
||||
kprintf("[%d] arch_prctl: ARCH_SET_FS: 0x%lX\n",
|
||||
aal_mc_get_processor_id(), address);
|
||||
cpu_local_var(current)->thread.tlsblock_base = address;
|
||||
err = aal_mc_arch_set_special_register(type, address);
|
||||
break;
|
||||
case ARCH_SET_GS:
|
||||
err = aal_mc_arch_set_special_register(type, address);
|
||||
break;
|
||||
@ -390,63 +461,73 @@ SYSCALL_DECLARE(clone)
|
||||
|
||||
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;
|
||||
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");
|
||||
dkprintf("[%d] clone(): stack_pointr: 0x%lX\n",
|
||||
aal_mc_get_processor_id(),
|
||||
(unsigned long)aal_mc_syscall_arg1(ctx));
|
||||
|
||||
//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)
|
||||
if (get_cpu_local_var(i)->status == CPU_STATUS_IDLE) {
|
||||
cpuid = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cpuid < 0) return -EAGAIN;
|
||||
|
||||
if (cpuid < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx),
|
||||
aal_mc_syscall_arg1(ctx));
|
||||
|
||||
if (!new) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* TODO: allocate new pid */
|
||||
new->pid = 0xc107e;
|
||||
|
||||
if (clone_flags & CLONE_SETTLS) {
|
||||
dkprintf("clone_flags & CLONE_SETTLS\n");
|
||||
/* Allocate new pid */
|
||||
new->pid = aal_atomic_inc_return(&pid_cnt);
|
||||
|
||||
if (clone_flags & CLONE_PARENT_SETTID) {
|
||||
dkprintf("clone_flags & CLONE_PARENT_SETTID: 0x%lX\n",
|
||||
(unsigned long)aal_mc_syscall_arg2(ctx));
|
||||
|
||||
new->vm->region.tlsblock_base
|
||||
*(int*)aal_mc_syscall_arg2(ctx) = new->pid;
|
||||
}
|
||||
|
||||
if (clone_flags & CLONE_CHILD_CLEARTID) {
|
||||
dkprintf("clone_flags & CLONE_CHILD_CLEARTID: 0x%lX\n",
|
||||
(unsigned long)aal_mc_syscall_arg3(ctx));
|
||||
|
||||
new->thread.clear_child_tid = (int*)aal_mc_syscall_arg3(ctx);
|
||||
}
|
||||
|
||||
if (clone_flags & CLONE_SETTLS) {
|
||||
dkprintf("clone_flags & CLONE_SETTLS: 0x%lX\n",
|
||||
(unsigned long)aal_mc_syscall_arg4(ctx));
|
||||
|
||||
new->thread.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,
|
||||
(int*)aal_mc_syscall_arg2(ctx), &pptid))
|
||||
return -EFAULT;
|
||||
|
||||
vptid = (int *)phys_to_virt(pptid);
|
||||
*vptid = 1;
|
||||
else {
|
||||
new->thread.tlsblock_base = 0;
|
||||
}
|
||||
|
||||
new->thread.clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID)
|
||||
? (int*)aal_mc_syscall_arg3(ctx)
|
||||
: NULL;
|
||||
|
||||
|
||||
aal_mc_syscall_ret(new->uctx) = 0;
|
||||
|
||||
runq_add_proc(new, cpuid);
|
||||
|
||||
//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(); }
|
||||
aal_mc_interrupt_cpu(get_x86_cpu_local_variable(cpuid)->apic_id, 0xd1);
|
||||
|
||||
//while (1) { cpu_halt(); }
|
||||
|
||||
return new->pid;
|
||||
}
|
||||
@ -459,6 +540,7 @@ SYSCALL_DECLARE(set_tid_address)
|
||||
return cpu_local_var(current)->pid;
|
||||
}
|
||||
|
||||
|
||||
SYSCALL_DECLARE(set_robust_list)
|
||||
{
|
||||
return -ENOSYS;
|
||||
@ -501,6 +583,94 @@ SYSCALL_DECLARE(writev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(futex)
|
||||
{
|
||||
// TODO: timespec support!
|
||||
//struct timespec _utime;
|
||||
uint64_t timeout = 1000; // MAX_SCHEDULE_TIMEOUT;
|
||||
uint32_t val2 = 0;
|
||||
|
||||
uint32_t *uaddr = (uint32_t *)aal_mc_syscall_arg0(ctx);
|
||||
int op = (int)aal_mc_syscall_arg1(ctx);
|
||||
uint32_t val = (uint32_t)aal_mc_syscall_arg2(ctx);
|
||||
//struct timespec __user *utime = aal_mc_syscall_arg3(ctx);
|
||||
uint32_t *uaddr2 = (uint32_t *)aal_mc_syscall_arg4(ctx);
|
||||
uint32_t val3 = (uint32_t)aal_mc_syscall_arg5(ctx);
|
||||
|
||||
/* Mask off the FUTEX_PRIVATE_FLAG,
|
||||
* assume all futexes are address space private */
|
||||
op = (op & FUTEX_CMD_MASK);
|
||||
|
||||
#if 0
|
||||
if (utime && (op == FUTEX_WAIT)) {
|
||||
if (copy_from_user(&_utime, utime, sizeof(_utime)) != 0)
|
||||
return -EFAULT;
|
||||
if (!timespec_valid(&_utime))
|
||||
return -EINVAL;
|
||||
timeout = timespec_to_ns(_utime);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Requeue parameter in 'utime' if op == FUTEX_CMP_REQUEUE.
|
||||
* number of waiters to wake in 'utime' if op == FUTEX_WAKE_OP. */
|
||||
if (op == FUTEX_CMP_REQUEUE || op == FUTEX_WAKE_OP)
|
||||
val2 = (uint32_t) (unsigned long) aal_mc_syscall_arg3(ctx);
|
||||
|
||||
return futex(uaddr, op, val, timeout, uaddr2, val2, val3);
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(exit)
|
||||
{
|
||||
/* If there is a clear_child_tid address set, clear it and wake it.
|
||||
* This unblocks any pthread_join() waiters. */
|
||||
if (cpu_local_var(current)->thread.clear_child_tid) {
|
||||
|
||||
kprintf("exit clear_child!\n");
|
||||
|
||||
*cpu_local_var(current)->thread.clear_child_tid = 0;
|
||||
barrier();
|
||||
futex((uint32_t *)cpu_local_var(current)->thread.clear_child_tid,
|
||||
FUTEX_WAKE, 1, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
runq_del_proc(cpu_local_var(current), cpu_local_var(current)->cpu_id);
|
||||
free_process_memory(cpu_local_var(current));
|
||||
|
||||
cpu_local_var(current) = NULL;
|
||||
schedule();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(getrlimit)
|
||||
{
|
||||
int ret;
|
||||
int resource = aal_mc_syscall_arg0(ctx);
|
||||
struct rlimit *rlm = (struct rlimit *)aal_mc_syscall_arg1(ctx);
|
||||
|
||||
switch (resource) {
|
||||
|
||||
case RLIMIT_STACK:
|
||||
|
||||
dkprintf("[%d] getrlimit() RLIMIT_STACK\n", aal_mc_get_processor_id());
|
||||
rlm->rlim_cur = (1024*1024);
|
||||
rlm->rlim_max = (16384*1024);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(noop)
|
||||
{
|
||||
kprintf("noop() \n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
||||
[0] = sys_read,
|
||||
@ -513,13 +683,17 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
||||
[10] = sys_mprotect,
|
||||
[11] = sys_munmap,
|
||||
[12] = sys_brk,
|
||||
[14] = sys_noop,
|
||||
[16] = sys_ioctl,
|
||||
[17] = sys_pread,
|
||||
[18] = sys_pwrite,
|
||||
[20] = sys_writev,
|
||||
[28] = sys_noop,
|
||||
[39] = sys_getpid,
|
||||
[56] = sys_clone,
|
||||
[60] = sys_exit,
|
||||
[63] = sys_uname,
|
||||
[97] = sys_getrlimit,
|
||||
[102] = sys_getxid,
|
||||
[104] = sys_getxid,
|
||||
[107] = sys_getxid,
|
||||
@ -527,6 +701,7 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
||||
[110] = sys_getxid,
|
||||
[111] = sys_getxid,
|
||||
[158] = sys_arch_prctl,
|
||||
[202] = sys_futex,
|
||||
[218] = sys_set_tid_address,
|
||||
[231] = sys_exit_group,
|
||||
[273] = sys_set_robust_list,
|
||||
@ -563,7 +738,6 @@ long syscall(int num, aal_mc_user_context_t *ctx)
|
||||
if (syscall_table[num]) {
|
||||
l = syscall_table[num](num, ctx);
|
||||
dkprintf(" %lx\n", l);
|
||||
return l;
|
||||
} else {
|
||||
dkprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num,
|
||||
aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx),
|
||||
@ -571,8 +745,10 @@ long syscall(int num, aal_mc_user_context_t *ctx)
|
||||
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
|
||||
aal_mc_syscall_sp(ctx));
|
||||
//while(1);
|
||||
return -ENOSYS;
|
||||
l = -ENOSYS;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void __host_update_process_range(struct process *process,
|
||||
|
||||
Reference in New Issue
Block a user