use "struct x86_regs *" to access stack frames

The intention of this fix is to cope with a recent change of
PUSH_ALL_REGS.
This commit is contained in:
NAKAMURA Gou
2014-04-03 14:01:05 +09:00
parent c0c9192e1b
commit 55817e9e83

View File

@@ -17,6 +17,7 @@
#include <ihk/cpu.h> #include <ihk/cpu.h>
#include <ihk/debug.h> #include <ihk/debug.h>
#include <cls.h> #include <cls.h>
#include <cpulocal.h>
#include <syscall.h> #include <syscall.h>
#include <process.h> #include <process.h>
#include <string.h> #include <string.h>
@@ -89,10 +90,12 @@ int obtain_clone_cpuid() {
SYSCALL_DECLARE(rt_sigreturn) SYSCALL_DECLARE(rt_sigreturn)
{ {
struct process *proc = cpu_local_var(current); struct process *proc = cpu_local_var(current);
unsigned long *regs; struct x86_cpu_local_variables *v = get_x86_this_cpu_local();
struct x86_regs *regs;
regs = (struct x86_regs *)v->kernel_stack;
--regs;
asm volatile ("movq %%gs:132,%0" : "=r" (regs));
regs -= 16;
memcpy(regs, proc->sigstack, 128); memcpy(regs, proc->sigstack, 128);
proc->sigmask.__val[0] = proc->supmask.__val[0]; proc->sigmask.__val[0] = proc->supmask.__val[0];
@@ -108,7 +111,7 @@ extern int num_processors;
void 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)
{ {
unsigned long *regs = regs0; struct x86_regs *regs = regs0;
struct k_sigaction *k; struct k_sigaction *k;
int sig; int sig;
__sigset_t w; __sigset_t w;
@@ -117,15 +120,17 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1); for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1);
if(sig == SIGKILL || sig == SIGTERM) if(sig == SIGKILL || sig == SIGTERM)
terminate(0, sig, (ihk_mc_user_context_t *)regs[14]); terminate(0, sig, (ihk_mc_user_context_t *)regs->rsp);
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 */
asm volatile ("movq %%gs:132,%0" : "=r" (regs)); struct x86_cpu_local_variables *v = get_x86_this_cpu_local();
regs -= 16;
regs = (struct x86_regs *)v->kernel_stack;
--regs;
} }
else{ else{
rc = regs[9]; /* rax */ rc = regs->rax;
} }
k = proc->sighandler->action + sig - 1; k = proc->sighandler->action + sig - 1;
@@ -137,15 +142,15 @@ 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 */
usp = (void *)regs[14]; usp = (void *)regs->rsp;
memcpy(proc->sigstack, regs, 128); memcpy(proc->sigstack, regs, 128);
proc->sigrc = rc; proc->sigrc = rc;
usp--; usp--;
*usp = (unsigned long)k->sa.sa_restorer; *usp = (unsigned long)k->sa.sa_restorer;
regs[4] = (unsigned long)sig; regs->rdi = (unsigned long)sig;
regs[11] = (unsigned long)k->sa.sa_handler; regs->rip = (unsigned long)k->sa.sa_handler;
regs[14] = (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);
@@ -155,14 +160,14 @@ do_signal(unsigned long rc, void *regs0, struct process *proc, struct sig_pendin
ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate); ihk_mc_spinlock_unlock(&proc->sighandler->lock, irqstate);
if(sig == SIGCHLD || sig == SIGURG) if(sig == SIGCHLD || sig == SIGURG)
return; return;
terminate(0, sig, (ihk_mc_user_context_t *)regs[14]); terminate(0, sig, (ihk_mc_user_context_t *)regs->rsp);
} }
} }
void void
check_signal(unsigned long rc, void *regs0) check_signal(unsigned long rc, void *regs0)
{ {
unsigned long *regs = regs0; struct x86_regs *regs = regs0;
struct process *proc; struct process *proc;
struct sig_pending *pending; struct sig_pending *pending;
struct sig_pending *next; struct sig_pending *next;
@@ -177,7 +182,7 @@ check_signal(unsigned long rc, void *regs0)
if(proc == NULL || proc->pid == 0) if(proc == NULL || proc->pid == 0)
return; return;
if(regs != NULL && (regs[14] & 0x8000000000000000)) if(regs != NULL && (regs->rsp & 0x8000000000000000))
return; return;
for(;;){ for(;;){
@@ -314,15 +319,15 @@ do_kill(int pid, int tid, int sig)
void void
set_signal(int sig, void *regs0) set_signal(int sig, void *regs0)
{ {
unsigned long *regs = regs0; struct x86_regs *regs = regs0;
struct process *proc = cpu_local_var(current); struct process *proc = cpu_local_var(current);
if(proc == NULL || proc->pid == 0) if(proc == NULL || proc->pid == 0)
return; return;
if((__sigmask(sig) & proc->sigmask.__val[0]) || if((__sigmask(sig) & proc->sigmask.__val[0]) ||
(regs[14] & 0x8000000000000000)) (regs->rsp & 0x8000000000000000))
terminate(0, sig, (ihk_mc_user_context_t *)regs[14]); terminate(0, sig, (ihk_mc_user_context_t *)regs->rsp);
else else
do_kill(proc->pid, proc->tid, sig); do_kill(proc->pid, proc->tid, sig);
} }