fix general protection fault caused by SIGALARM
This commit is contained in:
@@ -98,6 +98,8 @@ SYSCALL_DECLARE(rt_sigreturn)
|
||||
}
|
||||
|
||||
extern struct cpu_local_var *clv;
|
||||
extern unsigned long do_kill(int pid, int sig);
|
||||
extern void interrupt_syscall();
|
||||
|
||||
void
|
||||
check_signal(unsigned long rc, unsigned long *regs)
|
||||
@@ -123,7 +125,6 @@ check_signal(unsigned long rc, unsigned long *regs)
|
||||
else{
|
||||
rc = regs[9]; /* rax */
|
||||
}
|
||||
|
||||
k = proc->sighandler->action + sig - 1;
|
||||
|
||||
if(k->sa.sa_handler == (void *)1){
|
||||
@@ -133,6 +134,13 @@ check_signal(unsigned long rc, unsigned long *regs)
|
||||
else if(k->sa.sa_handler){
|
||||
unsigned long *usp; /* user stack */
|
||||
|
||||
if(regs[14] & 0x8000000000000000){ // kernel addr
|
||||
proc->signal = sig;
|
||||
interrupt_syscall();
|
||||
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
|
||||
return;
|
||||
}
|
||||
|
||||
usp = (void *)regs[14];
|
||||
memcpy(proc->sigstack, regs, 128);
|
||||
proc->sigrc = rc;
|
||||
@@ -153,8 +161,6 @@ check_signal(unsigned long rc, unsigned long *regs)
|
||||
}
|
||||
}
|
||||
|
||||
extern unsigned long do_kill(int pid, int sig);
|
||||
|
||||
unsigned long
|
||||
do_kill(int pid, int sig)
|
||||
{
|
||||
@@ -187,4 +193,5 @@ set_signal(int sig, unsigned long *regs)
|
||||
if(proc == NULL || proc->pid == 0)
|
||||
return;
|
||||
proc->signal = sig;
|
||||
interrupt_syscall();
|
||||
}
|
||||
|
||||
@@ -116,6 +116,11 @@ static int fd;
|
||||
static char *altroot;
|
||||
static const char rlimit_stack_envname[] = "MCKERNEL_RLIMIT_STACK";
|
||||
|
||||
pid_t gettid(void)
|
||||
{
|
||||
return syscall(SYS_gettid);
|
||||
}
|
||||
|
||||
struct program_load_desc *load_elf(FILE *fp, char **interp_pathp)
|
||||
{
|
||||
Elf64_Ehdr hdr;
|
||||
@@ -483,6 +488,8 @@ struct thread_data_s {
|
||||
int ret;
|
||||
pthread_mutex_t *lock;
|
||||
} *thread_data;
|
||||
int ncpu;
|
||||
pid_t master_tid;
|
||||
|
||||
static void *main_loop_thread_func(void *arg)
|
||||
{
|
||||
@@ -498,6 +505,9 @@ sendsig(int sig)
|
||||
{
|
||||
unsigned long param;
|
||||
|
||||
if(gettid() != master_tid)
|
||||
return;
|
||||
|
||||
param = ((unsigned long)sig) << 32 | ((unsigned long)getpid());
|
||||
if (ioctl(fd, MCEXEC_UP_SEND_SIGNAL, param) != 0) {
|
||||
perror("send_signal");
|
||||
@@ -562,7 +572,6 @@ int main(int argc, char **argv)
|
||||
char **a;
|
||||
char *p;
|
||||
int i;
|
||||
int ncpu;
|
||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
FILE *interp = NULL;
|
||||
char *interp_path;
|
||||
@@ -766,6 +775,18 @@ int main(int argc, char **argv)
|
||||
__dprint("mccmd server initialized\n");
|
||||
#endif
|
||||
|
||||
master_tid = gettid();
|
||||
for (i = 1; i <= 64; i++)
|
||||
if (i != SIGCHLD && i != SIGCONT && i != SIGSTOP &&
|
||||
i != SIGTSTP && i != SIGTTIN && i != SIGTTOU){
|
||||
struct sigaction act;
|
||||
|
||||
sigaction(i, NULL, &act);
|
||||
act.sa_handler = sendsig;
|
||||
act.sa_flags &= ~(SA_RESTART);
|
||||
sigaction(i, &act, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i <= ncpu; ++i) {
|
||||
int ret;
|
||||
|
||||
@@ -787,11 +808,6 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i <= 64; i++)
|
||||
if (i != SIGCHLD && i != SIGCONT && i != SIGSTOP &&
|
||||
i != SIGTSTP && i != SIGTTIN && i != SIGTTOU)
|
||||
signal(i, sendsig);
|
||||
|
||||
for (i = 0; i <= ncpu; ++i) {
|
||||
pthread_join(thread_data[i].thread_id, NULL);
|
||||
}
|
||||
@@ -851,6 +867,21 @@ do_generic_syscall(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
kill_thread(unsigned long cpu)
|
||||
{
|
||||
if(cpu >= 0 && cpu < ncpu){
|
||||
pthread_kill(thread_data[cpu].thread_id, SIGINT);
|
||||
}
|
||||
else{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ncpu; ++i) {
|
||||
pthread_kill(thread_data[i].thread_id, SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_ERR(ret) if (ret == -1) ret = -errno
|
||||
|
||||
int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
@@ -860,10 +891,10 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
char *fn;
|
||||
int sig;
|
||||
int term;
|
||||
|
||||
|
||||
w.cpu = cpu;
|
||||
|
||||
while (ioctl(fd, MCEXEC_UP_WAIT_SYSCALL, (unsigned long)&w) == 0) {
|
||||
while (((ret = ioctl(fd, MCEXEC_UP_WAIT_SYSCALL, (unsigned long)&w)) == 0) || (ret == -1 && errno == EINTR)) {
|
||||
|
||||
/* Don't print when got a msg to stdout */
|
||||
if (!(w.sr.number == __NR_write && w.sr.args[0] == 1))
|
||||
@@ -909,6 +940,10 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
w.sr.args[0], sizeof(struct timeval));
|
||||
break;
|
||||
|
||||
case __NR_kill: // interrupt syscall
|
||||
kill_thread(w.sr.args[0]);
|
||||
do_syscall_return(fd, cpu, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
case __NR_exit:
|
||||
case __NR_exit_group:
|
||||
sig = 0;
|
||||
@@ -963,6 +998,8 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr, "syscall=%ld\n", w.sr.number);
|
||||
fflush(stderr);
|
||||
ret = do_generic_syscall(&w);
|
||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||
break;
|
||||
|
||||
@@ -108,7 +108,8 @@ static void send_syscall(struct syscall_request *req)
|
||||
struct ihk_ikc_channel_desc *syscall_channel;
|
||||
int cpu;
|
||||
|
||||
if(req->number == __NR_exit_group){
|
||||
if(req->number == __NR_exit_group ||
|
||||
req->number == __NR_kill){ // interrupt syscall
|
||||
extern int num_processors;
|
||||
|
||||
scp = &get_cpu_local_var(0)->scp2;
|
||||
@@ -160,7 +161,8 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
||||
ihk_mc_get_processor_id(),
|
||||
req->number);
|
||||
|
||||
if(req->number == __NR_exit_group){
|
||||
if(req->number == __NR_exit_group ||
|
||||
req->number == __NR_kill){ // interrupt syscall
|
||||
scp = &get_cpu_local_var(0)->scp2;
|
||||
}
|
||||
else{
|
||||
@@ -250,6 +252,22 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
|
||||
schedule();
|
||||
}
|
||||
|
||||
void
|
||||
interrupt_syscall()
|
||||
{
|
||||
ihk_mc_user_context_t ctx;
|
||||
long lerror;
|
||||
|
||||
ihk_mc_syscall_arg0(&ctx) = ihk_mc_get_processor_id();
|
||||
ihk_mc_syscall_arg1(&ctx) = 0;
|
||||
|
||||
lerror = syscall_generic_forwarding(__NR_kill, &ctx);
|
||||
if (lerror) {
|
||||
kprintf("clear_host_pte failed. %ld\n", lerror);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(exit_group)
|
||||
{
|
||||
#if 0
|
||||
|
||||
Reference in New Issue
Block a user