support SA_RESTART flag and restart syscall
This commit is contained in:
@ -604,7 +604,7 @@ void setup_x86_ap(void (*next_func)(void))
|
||||
|
||||
void arch_show_interrupt_context(const void *reg);
|
||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
void check_signal(unsigned long, void *, int);
|
||||
extern void tlb_flush_handler(int vector);
|
||||
|
||||
void handle_interrupt(int vector, struct x86_user_context *regs)
|
||||
@ -678,7 +678,7 @@ void handle_interrupt(int vector, struct x86_user_context *regs)
|
||||
}
|
||||
}
|
||||
|
||||
check_signal(0, regs);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
|
||||
@ -691,7 +691,7 @@ void gpe_handler(struct x86_user_context *regs)
|
||||
panic("gpe_handler");
|
||||
}
|
||||
set_signal(SIGSEGV, regs, NULL);
|
||||
check_signal(0, regs);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
// panic("GPF");
|
||||
}
|
||||
@ -719,7 +719,7 @@ void debug_handler(struct x86_user_context *regs)
|
||||
memset(&info, '\0', sizeof info);
|
||||
info.si_code = si_code;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
check_signal(0, regs);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
|
||||
@ -736,7 +736,7 @@ void int3_handler(struct x86_user_context *regs)
|
||||
memset(&info, '\0', sizeof info);
|
||||
info.si_code = TRAP_BRKPT;
|
||||
set_signal(SIGTRAP, regs, &info);
|
||||
check_signal(0, regs);
|
||||
check_signal(0, regs, 0);
|
||||
check_need_resched();
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ SYSCALL_DELEGATED(2, open)
|
||||
SYSCALL_HANDLED(3, close)
|
||||
SYSCALL_DELEGATED(4, stat)
|
||||
SYSCALL_DELEGATED(5, fstat)
|
||||
SYSCALL_DELEGATED(7, poll)
|
||||
SYSCALL_DELEGATED(8, lseek)
|
||||
SYSCALL_HANDLED(9, mmap)
|
||||
SYSCALL_HANDLED(10, mprotect)
|
||||
@ -39,6 +40,7 @@ SYSCALL_DELEGATED(17, pread64)
|
||||
SYSCALL_DELEGATED(18, pwrite64)
|
||||
SYSCALL_DELEGATED(20, writev)
|
||||
SYSCALL_DELEGATED(21, access)
|
||||
SYSCALL_DELEGATED(23, select)
|
||||
SYSCALL_HANDLED(24, sched_yield)
|
||||
SYSCALL_HANDLED(25, mremap)
|
||||
SYSCALL_HANDLED(26, msync)
|
||||
@ -48,6 +50,7 @@ SYSCALL_HANDLED(29, shmget)
|
||||
SYSCALL_HANDLED(30, shmat)
|
||||
SYSCALL_HANDLED(31, shmctl)
|
||||
SYSCALL_HANDLED(34, pause)
|
||||
SYSCALL_DELEGATED(35, nanosleep)
|
||||
SYSCALL_HANDLED(39, getpid)
|
||||
SYSCALL_HANDLED(56, clone)
|
||||
SYSCALL_DELEGATED(57, fork)
|
||||
@ -57,7 +60,10 @@ SYSCALL_HANDLED(60, exit)
|
||||
SYSCALL_HANDLED(61, wait4)
|
||||
SYSCALL_HANDLED(62, kill)
|
||||
SYSCALL_DELEGATED(63, uname)
|
||||
SYSCALL_DELEGATED(65, semop)
|
||||
SYSCALL_HANDLED(67, shmdt)
|
||||
SYSCALL_DELEGATED(69, msgsnd)
|
||||
SYSCALL_DELEGATED(70, msgrcv)
|
||||
SYSCALL_DELEGATED(72, fcntl)
|
||||
SYSCALL_DELEGATED(79, getcwd)
|
||||
SYSCALL_DELEGATED(89, readlink)
|
||||
@ -104,18 +110,25 @@ SYSCALL_DELEGATED(201, time)
|
||||
SYSCALL_HANDLED(202, futex)
|
||||
SYSCALL_HANDLED(203, sched_setaffinity)
|
||||
SYSCALL_HANDLED(204, sched_getaffinity)
|
||||
SYSCALL_DELEGATED(208, io_getevents)
|
||||
SYSCALL_HANDLED(216, remap_file_pages)
|
||||
SYSCALL_DELEGATED(217, getdents64)
|
||||
SYSCALL_HANDLED(218, set_tid_address)
|
||||
SYSCALL_DELEGATED(220, semtimedop)
|
||||
SYSCALL_DELEGATED(230, clock_nanosleep)
|
||||
SYSCALL_HANDLED(231, exit_group)
|
||||
SYSCALL_DELEGATED(232, epoll_wait)
|
||||
SYSCALL_HANDLED(234, tgkill)
|
||||
SYSCALL_HANDLED(237, mbind)
|
||||
SYSCALL_HANDLED(238, set_mempolicy)
|
||||
SYSCALL_HANDLED(239, get_mempolicy)
|
||||
SYSCALL_HANDLED(247, waitid)
|
||||
SYSCALL_HANDLED(256, migrate_pages)
|
||||
SYSCALL_DELEGATED(270, pselect6)
|
||||
SYSCALL_DELEGATED(271, ppoll)
|
||||
SYSCALL_HANDLED(273, set_robust_list)
|
||||
SYSCALL_HANDLED(279, move_pages)
|
||||
SYSCALL_DELEGATED(281, epoll_pwait)
|
||||
SYSCALL_HANDLED(282, signalfd)
|
||||
SYSCALL_HANDLED(289, signalfd4)
|
||||
#ifdef DCFA_KMOD
|
||||
|
||||
@ -30,6 +30,7 @@ int copy_from_user(void *dst, const void *src, size_t siz);
|
||||
int copy_to_user(void *dst, const void *src, size_t siz);
|
||||
int write_process_vm(struct process_vm *vm, void *dst, const void *src, size_t siz);
|
||||
long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||
long syscall(int num, ihk_mc_user_context_t *ctx);
|
||||
extern void save_fp_regs(struct process *proc);
|
||||
|
||||
//#define DEBUG_PRINT_SC
|
||||
@ -152,6 +153,8 @@ struct sigsp {
|
||||
unsigned long sigrc;
|
||||
unsigned long sigmask;
|
||||
int ssflags;
|
||||
int num;
|
||||
int restart;
|
||||
siginfo_t info;
|
||||
};
|
||||
|
||||
@ -160,18 +163,19 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
struct process *proc = cpu_local_var(current);
|
||||
struct x86_user_context *regs;
|
||||
struct sigsp *sigsp;
|
||||
long rc = -EFAULT;
|
||||
|
||||
asm("movq %%gs:132, %0" : "=r" (regs));
|
||||
--regs;
|
||||
|
||||
sigsp = (struct sigsp *)regs->gpr.rsp;
|
||||
if(copy_from_user(regs, &sigsp->regs, sizeof(struct x86_user_context)))
|
||||
return -EFAULT;
|
||||
proc->sigmask.__val[0] = sigsp->sigmask;
|
||||
proc->sigstack.ss_flags = sigsp->ssflags;
|
||||
if(copy_from_user(regs, &sigsp->regs, sizeof(struct x86_user_context)))
|
||||
return rc;
|
||||
copy_from_user(&rc, &sigsp->sigrc, sizeof(long));
|
||||
return rc;
|
||||
if(sigsp->restart){
|
||||
return syscall(sigsp->num, (ihk_mc_user_context_t *)regs);
|
||||
}
|
||||
return sigsp->sigrc;
|
||||
}
|
||||
|
||||
extern struct cpu_local_var *clv;
|
||||
@ -495,9 +499,41 @@ void ptrace_report_signal(struct process *proc, int sig)
|
||||
schedule();
|
||||
dkprintf("ptrace_report_signal,wake up\n");
|
||||
}
|
||||
static int
|
||||
isrestart(int num, unsigned long rc, int sig, int restart)
|
||||
{
|
||||
if(num == 0 || rc != -EINTR)
|
||||
return 0;
|
||||
switch(num){
|
||||
case __NR_pause:
|
||||
case __NR_rt_sigsuspend:
|
||||
case __NR_rt_sigtimedwait:
|
||||
// case __NR_rt_sigwaitinfo:
|
||||
case __NR_epoll_wait:
|
||||
case __NR_epoll_pwait:
|
||||
case __NR_poll:
|
||||
case __NR_ppoll:
|
||||
case __NR_select:
|
||||
case __NR_pselect6:
|
||||
case __NR_msgrcv:
|
||||
case __NR_msgsnd:
|
||||
case __NR_semop:
|
||||
case __NR_semtimedop:
|
||||
case __NR_clock_nanosleep:
|
||||
case __NR_nanosleep:
|
||||
// case __NR_usleep:
|
||||
case __NR_io_getevents:
|
||||
return 0;
|
||||
}
|
||||
if(sig == SIGCHLD)
|
||||
return 1;
|
||||
if(restart)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pending *pending)
|
||||
do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pending *pending, int num)
|
||||
{
|
||||
struct x86_user_context *regs = regs0;
|
||||
struct k_sigaction *k;
|
||||
@ -564,6 +600,10 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
|
||||
}
|
||||
sigsp->sigmask = mask;
|
||||
sigsp->ssflags = ssflags;
|
||||
sigsp->num = num;
|
||||
sigsp->restart = isrestart(num, rc, sig, k->sa.sa_flags & SA_RESTART);
|
||||
if(num != 0 && rc == -EINTR && sig == SIGCHLD)
|
||||
sigsp->restart = 1;
|
||||
memcpy(&sigsp->info, &pending->info, sizeof(siginfo_t));
|
||||
|
||||
usp = (unsigned long *)sigsp;
|
||||
@ -697,6 +737,9 @@ getsigpending(struct process *proc, int delflag){
|
||||
struct sig_pending *pending;
|
||||
__sigset_t w;
|
||||
int irqstate;
|
||||
__sigset_t x;
|
||||
int sig;
|
||||
struct k_sigaction *k;
|
||||
|
||||
w = proc->sigmask.__val[0];
|
||||
|
||||
@ -705,11 +748,18 @@ getsigpending(struct process *proc, int delflag){
|
||||
for(;;){
|
||||
irqstate = ihk_mc_spinlock_lock(lock);
|
||||
list_for_each_entry_safe(pending, next, head, list){
|
||||
if(!(pending->sigmask.__val[0] & w)){
|
||||
if(delflag)
|
||||
list_del(&pending->list);
|
||||
ihk_mc_spinlock_unlock(lock, irqstate);
|
||||
return pending;
|
||||
for(x = pending->sigmask.__val[0], sig = 0; x; sig++, x >>= 1);
|
||||
k = proc->sighandler->action + sig - 1;
|
||||
if(delflag ||
|
||||
(sig != SIGCHLD && sig != SIGURG) ||
|
||||
(k->sa.sa_handler != (void *)1 &&
|
||||
k->sa.sa_handler != NULL)){
|
||||
if(!(pending->sigmask.__val[0] & w)){
|
||||
if(delflag)
|
||||
list_del(&pending->list);
|
||||
ihk_mc_spinlock_unlock(lock, irqstate);
|
||||
return pending;
|
||||
}
|
||||
}
|
||||
}
|
||||
ihk_mc_spinlock_unlock(lock, irqstate);
|
||||
@ -730,7 +780,7 @@ hassigpending(struct process *proc)
|
||||
}
|
||||
|
||||
void
|
||||
check_signal(unsigned long rc, void *regs0)
|
||||
check_signal(unsigned long rc, void *regs0, int num)
|
||||
{
|
||||
struct x86_user_context *regs = regs0;
|
||||
struct process *proc;
|
||||
@ -770,7 +820,7 @@ check_signal(unsigned long rc, void *regs0)
|
||||
return;
|
||||
}
|
||||
|
||||
do_signal(rc, regs, proc, pending);
|
||||
do_signal(rc, regs, proc, pending, num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -171,7 +171,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
||||
};
|
||||
|
||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
void check_signal(unsigned long, void *, int);
|
||||
int gencore(struct process *, void *, struct coretable **, int *);
|
||||
void freecore(struct coretable **);
|
||||
|
||||
@ -416,7 +416,7 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
||||
info._sifields._sigfault.si_addr = fault_addr;
|
||||
set_signal(SIGSEGV, regs, &info);
|
||||
}
|
||||
check_signal(0, regs);
|
||||
check_signal(0, regs, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ static char *syscall_name[] MCKERNEL_UNUSED = {
|
||||
#undef SYSCALL_DELEGATED
|
||||
};
|
||||
|
||||
void check_signal(unsigned long rc, void *regs);
|
||||
void check_signal(unsigned long, void *, int);
|
||||
void do_signal(long rc, void *regs, struct process *proc, struct sig_pending *pending);
|
||||
extern unsigned long do_kill(int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
||||
extern struct sigpending *hassigpending(struct process *proc);
|
||||
@ -6059,7 +6059,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
l = syscall_generic_forwarding(num, ctx);
|
||||
}
|
||||
|
||||
check_signal(l, NULL);
|
||||
check_signal(l, NULL, num);
|
||||
check_need_resched();
|
||||
|
||||
if (cpu_local_var(current)->ftn->ptrace) {
|
||||
|
||||
Reference in New Issue
Block a user