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 struct cpu_local_var *clv;
|
||||||
|
extern unsigned long do_kill(int pid, int sig);
|
||||||
|
extern void interrupt_syscall();
|
||||||
|
|
||||||
void
|
void
|
||||||
check_signal(unsigned long rc, unsigned long *regs)
|
check_signal(unsigned long rc, unsigned long *regs)
|
||||||
@@ -123,7 +125,6 @@ check_signal(unsigned long rc, unsigned long *regs)
|
|||||||
else{
|
else{
|
||||||
rc = regs[9]; /* rax */
|
rc = regs[9]; /* rax */
|
||||||
}
|
}
|
||||||
|
|
||||||
k = proc->sighandler->action + sig - 1;
|
k = proc->sighandler->action + sig - 1;
|
||||||
|
|
||||||
if(k->sa.sa_handler == (void *)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){
|
else if(k->sa.sa_handler){
|
||||||
unsigned long *usp; /* user stack */
|
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];
|
usp = (void *)regs[14];
|
||||||
memcpy(proc->sigstack, regs, 128);
|
memcpy(proc->sigstack, regs, 128);
|
||||||
proc->sigrc = rc;
|
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
|
unsigned long
|
||||||
do_kill(int pid, int sig)
|
do_kill(int pid, int sig)
|
||||||
{
|
{
|
||||||
@@ -187,4 +193,5 @@ set_signal(int sig, unsigned long *regs)
|
|||||||
if(proc == NULL || proc->pid == 0)
|
if(proc == NULL || proc->pid == 0)
|
||||||
return;
|
return;
|
||||||
proc->signal = sig;
|
proc->signal = sig;
|
||||||
|
interrupt_syscall();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ static int fd;
|
|||||||
static char *altroot;
|
static char *altroot;
|
||||||
static const char rlimit_stack_envname[] = "MCKERNEL_RLIMIT_STACK";
|
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)
|
struct program_load_desc *load_elf(FILE *fp, char **interp_pathp)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr hdr;
|
Elf64_Ehdr hdr;
|
||||||
@@ -483,6 +488,8 @@ struct thread_data_s {
|
|||||||
int ret;
|
int ret;
|
||||||
pthread_mutex_t *lock;
|
pthread_mutex_t *lock;
|
||||||
} *thread_data;
|
} *thread_data;
|
||||||
|
int ncpu;
|
||||||
|
pid_t master_tid;
|
||||||
|
|
||||||
static void *main_loop_thread_func(void *arg)
|
static void *main_loop_thread_func(void *arg)
|
||||||
{
|
{
|
||||||
@@ -498,6 +505,9 @@ sendsig(int sig)
|
|||||||
{
|
{
|
||||||
unsigned long param;
|
unsigned long param;
|
||||||
|
|
||||||
|
if(gettid() != master_tid)
|
||||||
|
return;
|
||||||
|
|
||||||
param = ((unsigned long)sig) << 32 | ((unsigned long)getpid());
|
param = ((unsigned long)sig) << 32 | ((unsigned long)getpid());
|
||||||
if (ioctl(fd, MCEXEC_UP_SEND_SIGNAL, param) != 0) {
|
if (ioctl(fd, MCEXEC_UP_SEND_SIGNAL, param) != 0) {
|
||||||
perror("send_signal");
|
perror("send_signal");
|
||||||
@@ -562,7 +572,6 @@ int main(int argc, char **argv)
|
|||||||
char **a;
|
char **a;
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
int ncpu;
|
|
||||||
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
FILE *interp = NULL;
|
FILE *interp = NULL;
|
||||||
char *interp_path;
|
char *interp_path;
|
||||||
@@ -766,6 +775,18 @@ int main(int argc, char **argv)
|
|||||||
__dprint("mccmd server initialized\n");
|
__dprint("mccmd server initialized\n");
|
||||||
#endif
|
#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) {
|
for (i = 0; i <= ncpu; ++i) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -787,11 +808,6 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
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) {
|
for (i = 0; i <= ncpu; ++i) {
|
||||||
pthread_join(thread_data[i].thread_id, NULL);
|
pthread_join(thread_data[i].thread_id, NULL);
|
||||||
}
|
}
|
||||||
@@ -851,6 +867,21 @@ do_generic_syscall(
|
|||||||
return ret;
|
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
|
#define SET_ERR(ret) if (ret == -1) ret = -errno
|
||||||
|
|
||||||
int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
||||||
@@ -863,7 +894,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
|
|
||||||
w.cpu = cpu;
|
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 */
|
/* Don't print when got a msg to stdout */
|
||||||
if (!(w.sr.number == __NR_write && w.sr.args[0] == 1))
|
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));
|
w.sr.args[0], sizeof(struct timeval));
|
||||||
break;
|
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:
|
||||||
case __NR_exit_group:
|
case __NR_exit_group:
|
||||||
sig = 0;
|
sig = 0;
|
||||||
@@ -963,6 +998,8 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
fprintf(stderr, "syscall=%ld\n", w.sr.number);
|
||||||
|
fflush(stderr);
|
||||||
ret = do_generic_syscall(&w);
|
ret = do_generic_syscall(&w);
|
||||||
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
do_syscall_return(fd, cpu, ret, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
struct ihk_ikc_channel_desc *syscall_channel;
|
struct ihk_ikc_channel_desc *syscall_channel;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if(req->number == __NR_exit_group){
|
if(req->number == __NR_exit_group ||
|
||||||
|
req->number == __NR_kill){ // interrupt syscall
|
||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
|
|
||||||
scp = &get_cpu_local_var(0)->scp2;
|
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(),
|
ihk_mc_get_processor_id(),
|
||||||
req->number);
|
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;
|
scp = &get_cpu_local_var(0)->scp2;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -250,6 +252,22 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
|
|||||||
schedule();
|
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)
|
SYSCALL_DECLARE(exit_group)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
Reference in New Issue
Block a user