move rt_sigaction to device dependent
fix call kill(getpid(), ) after sigaction aborted
This commit is contained in:
@ -25,6 +25,9 @@
|
|||||||
#include <kmalloc.h>
|
#include <kmalloc.h>
|
||||||
|
|
||||||
void terminate(int, int, ihk_mc_user_context_t *);
|
void terminate(int, int, ihk_mc_user_context_t *);
|
||||||
|
int copy_from_user(struct process *proc, void *dst, const void *src, size_t siz);
|
||||||
|
int copy_to_user(struct process *proc, void *dst, const void *src, size_t siz);
|
||||||
|
long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||||
|
|
||||||
//#define DEBUG_PRINT_SC
|
//#define DEBUG_PRINT_SC
|
||||||
|
|
||||||
@ -87,20 +90,55 @@ int obtain_clone_cpuid() {
|
|||||||
return cpuid;
|
return cpuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(rt_sigaction)
|
||||||
|
{
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
int sig = ihk_mc_syscall_arg0(ctx);
|
||||||
|
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
|
||||||
|
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
|
||||||
|
size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
|
||||||
|
struct k_sigaction new_sa, old_sa;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (sigsetsize != sizeof(sigset_t))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if(act)
|
||||||
|
if(copy_from_user(proc, &new_sa.sa, act, sizeof new_sa.sa)){
|
||||||
|
goto fault;
|
||||||
|
}
|
||||||
|
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
|
||||||
|
if(rc == 0 && oact)
|
||||||
|
if(copy_to_user(proc, oact, &old_sa.sa, sizeof old_sa.sa)){
|
||||||
|
goto fault;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
fault:
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigsp {
|
||||||
|
struct x86_regs regs;
|
||||||
|
unsigned long sigrc;
|
||||||
|
};
|
||||||
|
|
||||||
SYSCALL_DECLARE(rt_sigreturn)
|
SYSCALL_DECLARE(rt_sigreturn)
|
||||||
{
|
{
|
||||||
struct process *proc = cpu_local_var(current);
|
struct process *proc = cpu_local_var(current);
|
||||||
struct x86_cpu_local_variables *v = get_x86_this_cpu_local();
|
|
||||||
struct x86_regs *regs;
|
struct x86_regs *regs;
|
||||||
|
struct sigsp *sigsp;
|
||||||
|
long rc = -EFAULT;
|
||||||
|
|
||||||
regs = (struct x86_regs *)v->kernel_stack;
|
asm("movq %%gs:132, %0" : "=r" (regs));
|
||||||
--regs;
|
--regs;
|
||||||
|
|
||||||
memcpy(regs, proc->sigstack, 128);
|
|
||||||
|
|
||||||
proc->sigmask.__val[0] = proc->supmask.__val[0];
|
proc->sigmask.__val[0] = proc->supmask.__val[0];
|
||||||
|
sigsp = (struct sigsp *)regs->rsp;
|
||||||
return proc->sigrc;
|
if(copy_from_user(proc, regs, &sigsp->regs, sizeof(struct x86_regs)))
|
||||||
|
return rc;
|
||||||
|
copy_from_user(proc, &rc, &sigsp->sigrc, sizeof(long));
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct cpu_local_var *clv;
|
extern struct cpu_local_var *clv;
|
||||||
@ -124,9 +162,7 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
|||||||
|
|
||||||
irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
irqstate = ihk_mc_spinlock_lock(&proc->sighandler->lock);
|
||||||
if(regs == NULL){ /* call from syscall */
|
if(regs == NULL){ /* call from syscall */
|
||||||
struct x86_cpu_local_variables *v = get_x86_this_cpu_local();
|
asm("movq %%gs:132, %0" : "=r" (regs));
|
||||||
|
|
||||||
regs = (struct x86_regs *)v->kernel_stack;
|
|
||||||
--regs;
|
--regs;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -141,16 +177,26 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
|||||||
}
|
}
|
||||||
else if(k->sa.sa_handler){
|
else if(k->sa.sa_handler){
|
||||||
unsigned long *usp; /* user stack */
|
unsigned long *usp; /* user stack */
|
||||||
|
struct sigsp *sigsp;
|
||||||
|
|
||||||
usp = (void *)regs->rsp;
|
usp = (unsigned long *)regs->rsp;
|
||||||
memcpy(proc->sigstack, regs, 128);
|
sigsp = ((struct sigsp *)usp) - 1;
|
||||||
proc->sigrc = rc;
|
if(copy_to_user(proc, &sigsp->regs, regs, sizeof(struct x86_regs)) ||
|
||||||
|
copy_to_user(proc, &sigsp->sigrc, &rc, sizeof(long))){
|
||||||
|
kfree(pending);
|
||||||
|
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||||
|
terminate(0, sig, (ihk_mc_user_context_t *)regs->rsp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
usp = (unsigned long *)sigsp;
|
||||||
usp--;
|
usp--;
|
||||||
*usp = (unsigned long)k->sa.sa_restorer;
|
*usp = (unsigned long)k->sa.sa_restorer;
|
||||||
|
|
||||||
regs->rdi = (unsigned long)sig;
|
regs->rdi = (unsigned long)sig;
|
||||||
regs->rip = (unsigned long)k->sa.sa_handler;
|
regs->rip = (unsigned long)k->sa.sa_handler;
|
||||||
regs->rsp = (unsigned long)usp;
|
regs->rsp = (unsigned long)usp;
|
||||||
|
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
proc->sigmask.__val[0] |= pending->sigmask.__val[0];
|
proc->sigmask.__val[0] |= pending->sigmask.__val[0];
|
||||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||||
|
|||||||
@ -178,9 +178,6 @@ struct process {
|
|||||||
struct list_head sigpending;
|
struct list_head sigpending;
|
||||||
struct sig_shared *sigshared;
|
struct sig_shared *sigshared;
|
||||||
struct sig_handler *sighandler;
|
struct sig_handler *sighandler;
|
||||||
char sigstack[512]; // TODO: 1. move to user stack
|
|
||||||
// TODO: 2. backup FR and MMX regs
|
|
||||||
unsigned long sigrc; // return code of rt_sigreturn (x86_64: rax reg.)
|
|
||||||
|
|
||||||
struct rlimit rlimit_stack;
|
struct rlimit rlimit_stack;
|
||||||
pgio_func_t *pgio_fp;
|
pgio_func_t *pgio_fp;
|
||||||
|
|||||||
@ -105,7 +105,6 @@ static void send_syscall(struct syscall_request *req, int cpu, int pid)
|
|||||||
{
|
{
|
||||||
struct ikc_scd_packet packet;
|
struct ikc_scd_packet packet;
|
||||||
struct syscall_response *res;
|
struct syscall_response *res;
|
||||||
unsigned long fin;
|
|
||||||
struct syscall_params *scp;
|
struct syscall_params *scp;
|
||||||
struct ihk_ikc_channel_desc *syscall_channel;
|
struct ihk_ikc_channel_desc *syscall_channel;
|
||||||
|
|
||||||
@ -1289,34 +1288,6 @@ do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(rt_sigaction)
|
|
||||||
{
|
|
||||||
struct process *proc = cpu_local_var(current);
|
|
||||||
int sig = ihk_mc_syscall_arg0(ctx);
|
|
||||||
const struct sigaction *act = (const struct sigaction *)ihk_mc_syscall_arg1(ctx);
|
|
||||||
struct sigaction *oact = (struct sigaction *)ihk_mc_syscall_arg2(ctx);
|
|
||||||
size_t sigsetsize = ihk_mc_syscall_arg3(ctx);
|
|
||||||
struct k_sigaction new_sa, old_sa;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (sigsetsize != sizeof(sigset_t))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if(act)
|
|
||||||
if(copy_from_user(proc, &new_sa.sa, act, sizeof new_sa.sa)){
|
|
||||||
goto fault;
|
|
||||||
}
|
|
||||||
rc = do_sigaction(sig, act? &new_sa: NULL, oact? &old_sa: NULL);
|
|
||||||
if(rc == 0 && oact)
|
|
||||||
if(copy_to_user(proc, oact, &old_sa.sa, sizeof old_sa.sa)){
|
|
||||||
goto fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
fault:
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
SYSCALL_DECLARE(rt_sigprocmask)
|
SYSCALL_DECLARE(rt_sigprocmask)
|
||||||
{
|
{
|
||||||
int how = ihk_mc_syscall_arg0(ctx);
|
int how = ihk_mc_syscall_arg0(ctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user