diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index 4d1ca6a1..ef14d8df 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -73,6 +73,7 @@ SYSCALL_HANDLED(131, sigaltstack) SYSCALL_HANDLED(149, mlock) SYSCALL_HANDLED(150, munlock) SYSCALL_HANDLED(158, arch_prctl) +SYSCALL_HANDLED(160, setrlimit) SYSCALL_HANDLED(186, gettid) SYSCALL_DELEGATED(201, time) SYSCALL_HANDLED(202, futex) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index fcc1aaa2..a3181d8c 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -70,6 +70,7 @@ struct program_image_section { }; #define SHELL_PATH_MAX_LEN 1024 +#define MCK_RLIM_MAX 20 struct program_load_desc { int num_sections; @@ -93,8 +94,7 @@ struct program_load_desc { unsigned long args_len; char *envs; unsigned long envs_len; - unsigned long rlimit_stack_cur; - unsigned long rlimit_stack_max; + struct rlimit rlimit[MCK_RLIM_MAX]; unsigned long interp_align; char shell_path[SHELL_PATH_MAX_LEN]; struct program_image_section sections[0]; diff --git a/executer/kernel/procfs.c b/executer/kernel/procfs.c index 50c9e0fc..c2652bb5 100644 --- a/executer/kernel/procfs.c +++ b/executer/kernel/procfs.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "mcctrl.h" //#define PROCFS_DEBUG diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index fa840b3c..9400286c 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -40,7 +40,6 @@ #include #include #include -#include "../include/uprotocol.h" #include #include @@ -57,6 +56,7 @@ #include #include #include +#include "../include/uprotocol.h" //#define DEBUG @@ -945,7 +945,75 @@ void init_worker_threads(int fd, int mcosid) } pthread_barrier_wait(&init_ready); -} +} + +#define MCK_RLIMIT_AS 0 +#define MCK_RLIMIT_CORE 1 +#define MCK_RLIMIT_CPU 2 +#define MCK_RLIMIT_DATA 3 +#define MCK_RLIMIT_FSIZE 4 +#define MCK_RLIMIT_LOCKS 5 +#define MCK_RLIMIT_MEMLOCK 6 +#define MCK_RLIMIT_MSGQUEUE 7 +#define MCK_RLIMIT_NICE 8 +#define MCK_RLIMIT_NOFILE 9 +#define MCK_RLIMIT_NPROC 10 +#define MCK_RLIMIT_RSS 11 +#define MCK_RLIMIT_RTPRIO 12 +#define MCK_RLIMIT_RTTIME 13 +#define MCK_RLIMIT_SIGPENDING 14 +#define MCK_RLIMIT_STACK 15 + +static int rlimits[] = { +#ifdef RLIMIT_AS + RLIMIT_AS, MCK_RLIMIT_AS, +#endif +#ifdef RLIMIT_CORE + RLIMIT_CORE, MCK_RLIMIT_CORE, +#endif +#ifdef RLIMIT_CPU + RLIMIT_CPU, MCK_RLIMIT_CPU, +#endif +#ifdef RLIMIT_DATA + RLIMIT_DATA, MCK_RLIMIT_DATA, +#endif +#ifdef RLIMIT_FSIZE + RLIMIT_FSIZE, MCK_RLIMIT_FSIZE, +#endif +#ifdef RLIMIT_LOCKS + RLIMIT_LOCKS, MCK_RLIMIT_LOCKS, +#endif +#ifdef RLIMIT_MEMLOCK + RLIMIT_MEMLOCK, MCK_RLIMIT_MEMLOCK, +#endif +#ifdef RLIMIT_MSGQUEUE + RLIMIT_MSGQUEUE,MCK_RLIMIT_MSGQUEUE, +#endif +#ifdef RLIMIT_NICE + RLIMIT_NICE, MCK_RLIMIT_NICE, +#endif +#ifdef RLIMIT_NOFILE + RLIMIT_NOFILE, MCK_RLIMIT_NOFILE, +#endif +#ifdef RLIMIT_NPROC + RLIMIT_NPROC, MCK_RLIMIT_NPROC, +#endif +#ifdef RLIMIT_RSS + RLIMIT_RSS, MCK_RLIMIT_RSS, +#endif +#ifdef RLIMIT_RTPRIO + RLIMIT_RTPRIO, MCK_RLIMIT_RTPRIO, +#endif +#ifdef RLIMIT_RTTIME + RLIMIT_RTTIME, MCK_RLIMIT_RTTIME, +#endif +#ifdef RLIMIT_SIGPENDING + RLIMIT_SIGPENDING,MCK_RLIMIT_SIGPENDING, +#endif +#ifdef RLIMIT_STACK + RLIMIT_STACK, MCK_RLIMIT_STACK, +#endif +}; char dev[64]; @@ -1071,7 +1139,9 @@ int main(int argc, char **argv) if (shell) { argv[optind] = path; } - + + for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2) + getrlimit(rlimits[i], &desc->rlimit[rlimits[i + 1]]); desc->envs_len = envs_len; desc->envs = envs; //print_flat(envs); @@ -1106,8 +1176,8 @@ int main(int argc, char **argv) rlim_stack.rlim_cur = lcur; rlim_stack.rlim_max = lmax; } - desc->rlimit_stack_cur = rlim_stack.rlim_cur; - desc->rlimit_stack_max = rlim_stack.rlim_max; + desc->rlimit[MCK_RLIMIT_STACK].rlim_cur = rlim_stack.rlim_cur; + desc->rlimit[MCK_RLIMIT_STACK].rlim_max = rlim_stack.rlim_max; ncpu = ioctl(fd, MCEXEC_UP_GET_CPU, 0); if(ncpu == -1){ diff --git a/kernel/host.c b/kernel/host.c index 46e8bc6f..493398b6 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -368,8 +368,7 @@ static int process_msg_prepare_process(unsigned long rphys) 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; + memcpy(proc->rlimit, pn->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX); /* TODO: Clear it at the proper timing */ cpu_local_var(scp).post_idx = 0; diff --git a/kernel/include/process.h b/kernel/include/process.h index 772e829a..609d3a8a 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -21,6 +21,7 @@ #include #include #include +#include #define VR_NONE 0x0 #define VR_STACK 0x1 @@ -145,7 +146,6 @@ #include #include -#include struct user_fpregs_struct { @@ -343,7 +343,7 @@ struct process { struct sig_shared *sigshared; struct sig_handler *sighandler; - struct rlimit rlimit_stack; + struct rlimit rlimit[MCK_RLIM_MAX]; pgio_func_t *pgio_fp; void *pgio_arg; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index b9976d0a..a62b30c5 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -15,6 +15,7 @@ #include #include +#include #define NUM_SYSCALLS 255 @@ -112,6 +113,24 @@ struct program_image_section { }; #define SHELL_PATH_MAX_LEN 1024 +#define MCK_RLIM_MAX 20 + +#define MCK_RLIMIT_AS 0 +#define MCK_RLIMIT_CORE 1 +#define MCK_RLIMIT_CPU 2 +#define MCK_RLIMIT_DATA 3 +#define MCK_RLIMIT_FSIZE 4 +#define MCK_RLIMIT_LOCKS 5 +#define MCK_RLIMIT_MEMLOCK 6 +#define MCK_RLIMIT_MSGQUEUE 7 +#define MCK_RLIMIT_NICE 8 +#define MCK_RLIMIT_NOFILE 9 +#define MCK_RLIMIT_NPROC 10 +#define MCK_RLIMIT_RSS 11 +#define MCK_RLIMIT_RTPRIO 12 +#define MCK_RLIMIT_RTTIME 13 +#define MCK_RLIMIT_SIGPENDING 14 +#define MCK_RLIMIT_STACK 15 struct program_load_desc { int num_sections; @@ -135,8 +154,7 @@ struct program_load_desc { unsigned long args_len; char *envs; unsigned long envs_len; - unsigned long rlimit_stack_cur; - unsigned long rlimit_stack_max; + struct rlimit rlimit[MCK_RLIM_MAX]; unsigned long interp_align; char shell_path[SHELL_PATH_MAX_LEN]; struct program_image_section sections[0]; diff --git a/kernel/process.c b/kernel/process.c index 18065c02..6a8ebb8e 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -235,7 +235,7 @@ struct process *clone_process(struct process *org, unsigned long pc, ihk_mc_modify_user_context(proc->uctx, IHK_UCR_STACK_POINTER, sp); ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER, pc); - proc->rlimit_stack = org->rlimit_stack; + memcpy(proc->rlimit, org->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX); proc->sigmask = org->sigmask; proc->ftn = kmalloc(sizeof(struct fork_tree_node), IHK_MC_AP_NOWAIT); @@ -1453,7 +1453,7 @@ int init_process_stack(struct process *process, struct program_load_desc *pn, /* create stack range */ minsz = PAGE_SIZE; - size = process->rlimit_stack.rlim_cur & PAGE_MASK; + size = process->rlimit[MCK_RLIMIT_STACK].rlim_cur & PAGE_MASK; if (size > (USER_END / 2)) { size = USER_END / 2; } diff --git a/kernel/syscall.c b/kernel/syscall.c index 539ee334..52d6fc47 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2455,43 +2455,110 @@ SYSCALL_DECLARE(exit) return 0; } -SYSCALL_DECLARE(getrlimit) +static int rlimits[] = { +#ifdef RLIMIT_AS + RLIMIT_AS, MCK_RLIMIT_AS, +#endif +#ifdef RLIMIT_CORE + RLIMIT_CORE, MCK_RLIMIT_CORE, +#endif +#ifdef RLIMIT_CPU + RLIMIT_CPU, MCK_RLIMIT_CPU, +#endif +#ifdef RLIMIT_DATA + RLIMIT_DATA, MCK_RLIMIT_DATA, +#endif +#ifdef RLIMIT_FSIZE + RLIMIT_FSIZE, MCK_RLIMIT_FSIZE, +#endif +#ifdef RLIMIT_LOCKS + RLIMIT_LOCKS, MCK_RLIMIT_LOCKS, +#endif +#ifdef RLIMIT_MEMLOCK + RLIMIT_MEMLOCK, MCK_RLIMIT_MEMLOCK, +#endif +#ifdef RLIMIT_MSGQUEUE + RLIMIT_MSGQUEUE,MCK_RLIMIT_MSGQUEUE, +#endif +#ifdef RLIMIT_NICE + RLIMIT_NICE, MCK_RLIMIT_NICE, +#endif +#ifdef RLIMIT_NOFILE + RLIMIT_NOFILE, MCK_RLIMIT_NOFILE, +#endif +#ifdef RLIMIT_NPROC + RLIMIT_NPROC, MCK_RLIMIT_NPROC, +#endif +#ifdef RLIMIT_RSS + RLIMIT_RSS, MCK_RLIMIT_RSS, +#endif +#ifdef RLIMIT_RTPRIO + RLIMIT_RTPRIO, MCK_RLIMIT_RTPRIO, +#endif +#ifdef RLIMIT_RTTIME + RLIMIT_RTTIME, MCK_RLIMIT_RTTIME, +#endif +#ifdef RLIMIT_SIGPENDING + RLIMIT_SIGPENDING,MCK_RLIMIT_SIGPENDING, +#endif +#ifdef RLIMIT_STACK + RLIMIT_STACK, MCK_RLIMIT_STACK, +#endif +}; + +SYSCALL_DECLARE(setrlimit) { - int ret; + int rc; int resource = ihk_mc_syscall_arg0(ctx); struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx); struct process *proc = cpu_local_var(current); + int i; + int mcresource; - switch (resource) { - - case RLIMIT_STACK: - dkprintf("[%d] getrlimit() RLIMIT_STACK\n", ihk_mc_get_processor_id()); - if(copy_to_user(proc, &rlm->rlim_cur, &proc->rlimit_stack.rlim_cur, sizeof rlm->rlim_cur)) - return -EFAULT; - if(copy_to_user(proc, &rlm->rlim_max, &proc->rlimit_stack.rlim_max, sizeof rlm->rlim_max)) - return -EFAULT; - ret = 0; + switch(resource){ + case RLIMIT_FSIZE: + case RLIMIT_NOFILE: + rc = syscall_generic_forwarding(__NR_setrlimit, ctx); + if(rc < 0) + return rc; break; - - case RLIMIT_FSIZE: - case RLIMIT_LOCKS: - case RLIMIT_NOFILE: - /* just forward */ - ret = syscall_generic_forwarding(n, ctx); - - /* return one less than the actual value to make sure mcexec can open - * its temporary synchronization pipe when a new process is forked */ - if (resource == RLIMIT_NOFILE) { - ret -= 1; - } - break; - - default: - - return -ENOSYS; } - return ret; + for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2) + if(rlimits[i] == resource){ + mcresource = rlimits[i + 1]; + break; + } + if(i >= sizeof(rlimits) / sizeof(int)) + return -EINVAL; + + if(copy_from_user(proc, proc->rlimit + mcresource, rlm, sizeof(struct rlimit))) + return -EFAULT; + + return 0; +} + +SYSCALL_DECLARE(getrlimit) +{ + int resource = ihk_mc_syscall_arg0(ctx); + struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx); + struct process *proc = cpu_local_var(current); + int i; + int mcresource; + + for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2) + if(rlimits[i] == resource){ + mcresource = rlimits[i + 1]; + break; + } + if(i >= sizeof(rlimits) / sizeof(int)) + return -EINVAL; + +// TODO: check limit + if(copy_to_user(proc, rlm, proc->rlimit + mcresource, sizeof(struct rlimit))) + return -EFAULT; + + return 0; } extern int ptrace_traceme(void);