syscall: add prlimit64
Change-Id: Iad882813d54b439c236c0df74dc81508190e6707
This commit is contained in:
@@ -85,7 +85,11 @@ enum __rlimit_resource
|
|||||||
__RLIMIT_RTPRIO = 14,
|
__RLIMIT_RTPRIO = 14,
|
||||||
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
|
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
|
||||||
|
|
||||||
__RLIMIT_NLIMITS = 15,
|
/* timeout for RT tasks in us */
|
||||||
|
__RLIMIT_RTTIME = 15,
|
||||||
|
#define RLIMIT_RTTIME __RLIMIT_RTTIME
|
||||||
|
|
||||||
|
__RLIMIT_NLIMITS = 16,
|
||||||
__RLIM_NLIMITS = __RLIMIT_NLIMITS
|
__RLIM_NLIMITS = __RLIMIT_NLIMITS
|
||||||
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
|
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
|
||||||
#define RLIM_NLIMITS __RLIM_NLIMITS
|
#define RLIM_NLIMITS __RLIM_NLIMITS
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ SYSCALL_HANDLED(241, perf_event_open)
|
|||||||
SYSCALL_DELEGATED(241, perf_event_open)
|
SYSCALL_DELEGATED(241, perf_event_open)
|
||||||
#endif // PERF_ENABLE
|
#endif // PERF_ENABLE
|
||||||
SYSCALL_HANDLED(260, wait4)
|
SYSCALL_HANDLED(260, wait4)
|
||||||
|
SYSCALL_HANDLED(261, prlimit64)
|
||||||
SYSCALL_HANDLED(270, process_vm_readv)
|
SYSCALL_HANDLED(270, process_vm_readv)
|
||||||
SYSCALL_HANDLED(271, process_vm_writev)
|
SYSCALL_HANDLED(271, process_vm_writev)
|
||||||
SYSCALL_HANDLED(281, execveat)
|
SYSCALL_HANDLED(281, execveat)
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ enum __rlimit_resource
|
|||||||
__RLIMIT_RTPRIO = 14,
|
__RLIMIT_RTPRIO = 14,
|
||||||
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
|
#define RLIMIT_RTPRIO __RLIMIT_RTPRIO
|
||||||
|
|
||||||
__RLIMIT_NLIMITS = 15,
|
/* timeout for RT tasks in us */
|
||||||
|
__RLIMIT_RTTIME = 15,
|
||||||
|
#define RLIMIT_RTTIME __RLIMIT_RTTIME
|
||||||
|
|
||||||
|
__RLIMIT_NLIMITS = 16,
|
||||||
__RLIM_NLIMITS = __RLIMIT_NLIMITS
|
__RLIM_NLIMITS = __RLIMIT_NLIMITS
|
||||||
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
|
#define RLIMIT_NLIMITS __RLIMIT_NLIMITS
|
||||||
#define RLIM_NLIMITS __RLIM_NLIMITS
|
#define RLIM_NLIMITS __RLIM_NLIMITS
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ SYSCALL_HANDLED(289, signalfd4)
|
|||||||
#ifdef ENABLE_PERF
|
#ifdef ENABLE_PERF
|
||||||
SYSCALL_HANDLED(298, perf_event_open)
|
SYSCALL_HANDLED(298, perf_event_open)
|
||||||
#endif
|
#endif
|
||||||
|
SYSCALL_HANDLED(302, prlimit64)
|
||||||
#ifdef DCFA_KMOD
|
#ifdef DCFA_KMOD
|
||||||
SYSCALL_HANDLED(303, mod_call)
|
SYSCALL_HANDLED(303, mod_call)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
183
kernel/syscall.c
183
kernel/syscall.c
@@ -6596,71 +6596,162 @@ static int rlimits[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
SYSCALL_DECLARE(setrlimit)
|
static int do_prlimit64(int pid, int resource, struct rlimit *_new_limit,
|
||||||
|
struct rlimit *old_limit)
|
||||||
{
|
{
|
||||||
int rc;
|
struct rlimit new_limit;
|
||||||
int resource = ihk_mc_syscall_arg0(ctx);
|
int resource_found;
|
||||||
struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
|
int i;
|
||||||
struct thread *thread = cpu_local_var(current);
|
int mcresource;
|
||||||
int i;
|
struct process *proc;
|
||||||
struct rlimit new_rlim;
|
struct resource_set *rset = cpu_local_var(resource_set);
|
||||||
int mcresource;
|
int hash;
|
||||||
|
struct process_hash *phash = rset->process_hash;
|
||||||
|
struct mcs_rwlock_node exist_lock;
|
||||||
|
struct mcs_rwlock_node update_lock;
|
||||||
|
unsigned long irqstate;
|
||||||
|
int found;
|
||||||
|
int ret;
|
||||||
|
ihk_mc_user_context_t ctx;
|
||||||
|
|
||||||
if (copy_from_user(&new_rlim, rlm, sizeof(*rlm))) {
|
if (resource < 0 || resource >= RLIMIT_NLIMITS) {
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
if (new_rlim.rlim_cur > new_rlim.rlim_max) {
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(resource){
|
if (_new_limit) {
|
||||||
case RLIMIT_FSIZE:
|
if (copy_from_user(&new_limit, _new_limit,
|
||||||
case RLIMIT_NOFILE:
|
sizeof(struct rlimit))) {
|
||||||
case RLIMIT_LOCKS:
|
return -EFAULT;
|
||||||
case RLIMIT_MSGQUEUE:
|
}
|
||||||
rc = syscall_generic_forwarding(__NR_setrlimit, ctx);
|
|
||||||
if(rc < 0)
|
|
||||||
return rc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2)
|
if (new_limit.rlim_cur > new_limit.rlim_max) {
|
||||||
if(rlimits[i] == resource){
|
return -EINVAL;
|
||||||
mcresource = rlimits[i + 1];
|
}
|
||||||
|
|
||||||
|
/* update Linux side value as well */
|
||||||
|
switch (resource) {
|
||||||
|
case RLIMIT_FSIZE:
|
||||||
|
case RLIMIT_NOFILE:
|
||||||
|
case RLIMIT_LOCKS:
|
||||||
|
case RLIMIT_MSGQUEUE:
|
||||||
|
ihk_mc_syscall_arg0(&ctx) = pid;
|
||||||
|
ihk_mc_syscall_arg1(&ctx) = resource;
|
||||||
|
ihk_mc_syscall_arg2(&ctx) =
|
||||||
|
(unsigned long)_new_limit;
|
||||||
|
ihk_mc_syscall_arg3(&ctx) =
|
||||||
|
(unsigned long)old_limit;
|
||||||
|
ret = syscall_generic_forwarding(__NR_prlimit64, &ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i >= sizeof(rlimits) / sizeof(int)){
|
|
||||||
return syscall_generic_forwarding(__NR_setrlimit, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(thread->proc->rlimit + mcresource, &new_rlim,
|
/* translate resource */
|
||||||
sizeof(new_rlim));
|
resource_found = 0;
|
||||||
|
for (i = 0; i < sizeof(rlimits) / sizeof(int); i += 2) {
|
||||||
|
if (rlimits[i] == resource) {
|
||||||
|
mcresource = rlimits[i + 1];
|
||||||
|
resource_found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
if (!resource_found) {
|
||||||
|
ihk_mc_syscall_arg0(&ctx) = pid;
|
||||||
|
ihk_mc_syscall_arg1(&ctx) = resource;
|
||||||
|
ihk_mc_syscall_arg2(&ctx) =
|
||||||
|
(unsigned long)_new_limit;
|
||||||
|
ihk_mc_syscall_arg3(&ctx) =
|
||||||
|
(unsigned long)old_limit;
|
||||||
|
return syscall_generic_forwarding(__NR_prlimit64, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find process */
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
struct thread *thread = cpu_local_var(current);
|
||||||
|
|
||||||
|
pid = thread->proc->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
irqstate = cpu_disable_interrupt_save();
|
||||||
|
hash = process_hash(pid);
|
||||||
|
mcs_rwlock_reader_lock_noirq(&phash->lock[hash], &exist_lock);
|
||||||
|
|
||||||
|
list_for_each_entry(proc, &phash->list[hash], hash_list) {
|
||||||
|
if (proc->pid == pid) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&phash->lock[hash], &exist_lock);
|
||||||
|
cpu_restore_interrupt(irqstate);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_new_limit) {
|
||||||
|
mcs_rwlock_writer_lock_noirq(&proc->update_lock, &update_lock);
|
||||||
|
} else {
|
||||||
|
mcs_rwlock_reader_lock_noirq(&proc->update_lock, &update_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_limit) {
|
||||||
|
if (copy_to_user(old_limit, proc->rlimit + mcresource,
|
||||||
|
sizeof(struct rlimit))) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_new_limit) {
|
||||||
|
memcpy(proc->rlimit + mcresource, &new_limit,
|
||||||
|
sizeof(struct rlimit));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
out:
|
||||||
|
if (_new_limit) {
|
||||||
|
mcs_rwlock_writer_unlock_noirq(&proc->update_lock,
|
||||||
|
&update_lock);
|
||||||
|
} else {
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&proc->update_lock,
|
||||||
|
&update_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
mcs_rwlock_reader_unlock_noirq(&phash->lock[hash], &exist_lock);
|
||||||
|
cpu_restore_interrupt(irqstate);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(setrlimit)
|
||||||
|
{
|
||||||
|
int resource = ihk_mc_syscall_arg0(ctx);
|
||||||
|
struct rlimit *new_limit = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
|
||||||
|
|
||||||
|
return do_prlimit64(0, resource, new_limit, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(getrlimit)
|
SYSCALL_DECLARE(getrlimit)
|
||||||
{
|
{
|
||||||
int resource = ihk_mc_syscall_arg0(ctx);
|
int resource = ihk_mc_syscall_arg0(ctx);
|
||||||
struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
|
struct rlimit *old_limit = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
|
||||||
struct thread *thread = cpu_local_var(current);
|
|
||||||
int i;
|
|
||||||
int mcresource;
|
|
||||||
|
|
||||||
for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2)
|
return do_prlimit64(0, resource, NULL, old_limit);
|
||||||
if(rlimits[i] == resource){
|
}
|
||||||
mcresource = rlimits[i + 1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(i >= sizeof(rlimits) / sizeof(int)){
|
|
||||||
return syscall_generic_forwarding(__NR_getrlimit, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: check limit
|
SYSCALL_DECLARE(prlimit64)
|
||||||
if(copy_to_user(rlm, thread->proc->rlimit + mcresource, sizeof(struct rlimit)))
|
{
|
||||||
return -EFAULT;
|
int pid = ihk_mc_syscall_arg0(ctx);
|
||||||
|
int resource = ihk_mc_syscall_arg1(ctx);
|
||||||
|
struct rlimit *new_limit = (struct rlimit *)ihk_mc_syscall_arg2(ctx);
|
||||||
|
struct rlimit *old_limit = (struct rlimit *)ihk_mc_syscall_arg3(ctx);
|
||||||
|
|
||||||
return 0;
|
return do_prlimit64(pid, resource, new_limit, old_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(getrusage)
|
SYSCALL_DECLARE(getrusage)
|
||||||
|
|||||||
Reference in New Issue
Block a user