support profil
This commit is contained in:
@@ -161,12 +161,41 @@ fault:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sigsp {
|
struct sigsp {
|
||||||
struct x86_user_context regs;
|
unsigned long flags;
|
||||||
|
void *link;
|
||||||
|
stack_t sigstack;
|
||||||
|
unsigned long regs[23];
|
||||||
|
#define _r8 regs[0]
|
||||||
|
#define _r9 regs[1]
|
||||||
|
#define _r10 regs[2]
|
||||||
|
#define _r11 regs[3]
|
||||||
|
#define _r12 regs[4]
|
||||||
|
#define _r13 regs[5]
|
||||||
|
#define _r14 regs[6]
|
||||||
|
#define _r15 regs[7]
|
||||||
|
#define _rdi regs[8]
|
||||||
|
#define _rsi regs[9]
|
||||||
|
#define _rbp regs[10]
|
||||||
|
#define _rbx regs[11]
|
||||||
|
#define _rdx regs[12]
|
||||||
|
#define _rax regs[13]
|
||||||
|
#define _rcx regs[14]
|
||||||
|
#define _rsp regs[15]
|
||||||
|
#define _rip regs[16]
|
||||||
|
#define _rflags regs[17]
|
||||||
|
#define _csgsfs regs[18]
|
||||||
|
#define _error regs[19]
|
||||||
|
#define _trapno regs[20]
|
||||||
|
#define _oldmask regs[21]
|
||||||
|
#define _cr2 regs[22]
|
||||||
|
void *fpregs;
|
||||||
|
unsigned long reserve[8];
|
||||||
|
|
||||||
unsigned long sigrc;
|
unsigned long sigrc;
|
||||||
unsigned long sigmask;
|
unsigned long sigmask;
|
||||||
int ssflags;
|
|
||||||
int num;
|
int num;
|
||||||
int restart;
|
int restart;
|
||||||
|
unsigned long ss;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,16 +203,38 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
{
|
{
|
||||||
struct thread *thread = cpu_local_var(current);
|
struct thread *thread = cpu_local_var(current);
|
||||||
struct x86_user_context *regs;
|
struct x86_user_context *regs;
|
||||||
|
struct sigsp ksigsp;
|
||||||
struct sigsp *sigsp;
|
struct sigsp *sigsp;
|
||||||
|
|
||||||
asm("movq %%gs:132, %0" : "=r" (regs));
|
asm("movq %%gs:132, %0" : "=r" (regs));
|
||||||
--regs;
|
--regs;
|
||||||
|
|
||||||
sigsp = (struct sigsp *)regs->gpr.rsp;
|
sigsp = (struct sigsp *)regs->gpr.rsp;
|
||||||
if(copy_from_user(regs, &sigsp->regs, sizeof(struct x86_user_context)))
|
if(copy_from_user(&ksigsp, sigsp, sizeof ksigsp))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
thread->sigmask.__val[0] = sigsp->sigmask;
|
|
||||||
thread->sigstack.ss_flags = sigsp->ssflags;
|
regs->gpr.r15 = ksigsp._r15;
|
||||||
|
regs->gpr.r14 = ksigsp._r14;
|
||||||
|
regs->gpr.r13 = ksigsp._r13;
|
||||||
|
regs->gpr.r12 = ksigsp._r12;
|
||||||
|
regs->gpr.rbp = ksigsp._rbp;
|
||||||
|
regs->gpr.rbx = ksigsp._rbx;
|
||||||
|
regs->gpr.r11 = ksigsp._r11;
|
||||||
|
regs->gpr.r10 = ksigsp._r10;
|
||||||
|
regs->gpr.r9 = ksigsp._r9;
|
||||||
|
regs->gpr.r8 = ksigsp._r8;
|
||||||
|
regs->gpr.rax = ksigsp._rax;
|
||||||
|
regs->gpr.rcx = ksigsp._rcx;
|
||||||
|
regs->gpr.rdx = ksigsp._rdx;
|
||||||
|
regs->gpr.rsi = ksigsp._rsi;
|
||||||
|
regs->gpr.rdi = ksigsp._rdi;
|
||||||
|
regs->gpr.error = ksigsp._error;
|
||||||
|
regs->gpr.rip = ksigsp._rip;
|
||||||
|
regs->gpr.rflags = ksigsp._rflags;
|
||||||
|
regs->gpr.rsp = ksigsp._rsp;
|
||||||
|
thread->sigmask.__val[0] = ksigsp._oldmask;
|
||||||
|
|
||||||
|
memcpy(&thread->sigstack, &ksigsp.sigstack, sizeof(stack_t));
|
||||||
if(sigsp->restart){
|
if(sigsp->restart){
|
||||||
return syscall(sigsp->num, (ihk_mc_user_context_t *)regs);
|
return syscall(sigsp->num, (ihk_mc_user_context_t *)regs);
|
||||||
}
|
}
|
||||||
@@ -567,9 +618,8 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
}
|
}
|
||||||
else if(k->sa.sa_handler){
|
else if(k->sa.sa_handler){
|
||||||
unsigned long *usp; /* user stack */
|
unsigned long *usp; /* user stack */
|
||||||
|
struct sigsp ksigsp;
|
||||||
struct sigsp *sigsp;
|
struct sigsp *sigsp;
|
||||||
int ssflags = thread->sigstack.ss_flags;
|
|
||||||
unsigned long mask = (unsigned long)thread->sigmask.__val[0];
|
|
||||||
|
|
||||||
if((k->sa.sa_flags & SA_ONSTACK) &&
|
if((k->sa.sa_flags & SA_ONSTACK) &&
|
||||||
!(thread->sigstack.ss_flags & SS_DISABLE) &&
|
!(thread->sigstack.ss_flags & SS_DISABLE) &&
|
||||||
@@ -584,31 +634,56 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
}
|
}
|
||||||
sigsp = ((struct sigsp *)usp) - 1;
|
sigsp = ((struct sigsp *)usp) - 1;
|
||||||
sigsp = (struct sigsp *)((unsigned long)sigsp & 0xfffffffffffffff0UL);
|
sigsp = (struct sigsp *)((unsigned long)sigsp & 0xfffffffffffffff0UL);
|
||||||
if(write_process_vm(thread->vm, &sigsp->regs, regs, sizeof(struct x86_user_context)) ||
|
memset(&ksigsp, '\0', sizeof ksigsp);
|
||||||
write_process_vm(thread->vm, &sigsp->sigrc, &rc, sizeof(long))){
|
|
||||||
|
ksigsp._r15 = regs->gpr.r15;
|
||||||
|
ksigsp._r14 = regs->gpr.r14;
|
||||||
|
ksigsp._r13 = regs->gpr.r13;
|
||||||
|
ksigsp._r12 = regs->gpr.r12;
|
||||||
|
ksigsp._rbp = regs->gpr.rbp;
|
||||||
|
ksigsp._rbx = regs->gpr.rbx;
|
||||||
|
ksigsp._r11 = regs->gpr.r11;
|
||||||
|
ksigsp._r10 = regs->gpr.r10;
|
||||||
|
ksigsp._r9 = regs->gpr.r9;
|
||||||
|
ksigsp._r8 = regs->gpr.r8;
|
||||||
|
ksigsp._rax = regs->gpr.rax;
|
||||||
|
ksigsp._rcx = regs->gpr.rcx;
|
||||||
|
ksigsp._rdx = regs->gpr.rdx;
|
||||||
|
ksigsp._rsi = regs->gpr.rsi;
|
||||||
|
ksigsp._rdi = regs->gpr.rdi;
|
||||||
|
ksigsp._error = regs->gpr.error;
|
||||||
|
ksigsp._rip = regs->gpr.rip;
|
||||||
|
ksigsp._rflags = regs->gpr.rflags;
|
||||||
|
ksigsp._rsp = regs->gpr.rsp;
|
||||||
|
ksigsp._cr2 = (unsigned long)pending->info._sifields._sigfault.si_addr;
|
||||||
|
ksigsp._oldmask = thread->sigmask.__val[0];
|
||||||
|
|
||||||
|
memcpy(&ksigsp.sigstack, &thread->sigstack, sizeof(stack_t));
|
||||||
|
ksigsp.sigrc = rc;
|
||||||
|
ksigsp.num = num;
|
||||||
|
ksigsp.restart = isrestart(num, rc, sig, k->sa.sa_flags & SA_RESTART);
|
||||||
|
if(num != 0 && rc == -EINTR && sig == SIGCHLD)
|
||||||
|
ksigsp.restart = 1;
|
||||||
|
memcpy(&ksigsp.info, &pending->info, sizeof(siginfo_t));
|
||||||
|
|
||||||
|
if(copy_to_user(sigsp, &ksigsp, sizeof ksigsp)){
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
ihk_mc_spinlock_unlock(&thread->sigcommon->lock, irqstate);
|
||||||
kprintf("do_signal,write_process_vm failed\n");
|
kprintf("do_signal,write_process_vm failed\n");
|
||||||
terminate(0, sig);
|
terminate(0, sig);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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;
|
usp = (unsigned long *)sigsp;
|
||||||
usp--;
|
usp--;
|
||||||
*usp = (unsigned long)k->sa.sa_restorer;
|
*usp = (unsigned long)k->sa.sa_restorer;
|
||||||
|
|
||||||
regs->gpr.rdi = (unsigned long)sig;
|
regs->gpr.rdi = (unsigned long)sig;
|
||||||
if(k->sa.sa_flags & SA_SIGINFO){
|
regs->gpr.rsi = (unsigned long)&sigsp->info;
|
||||||
regs->gpr.rsi = (unsigned long)&sigsp->info;
|
regs->gpr.rdx = (unsigned long)sigsp;
|
||||||
regs->gpr.rdx = 0;
|
|
||||||
}
|
|
||||||
regs->gpr.rip = (unsigned long)k->sa.sa_handler;
|
regs->gpr.rip = (unsigned long)k->sa.sa_handler;
|
||||||
regs->gpr.rsp = (unsigned long)usp;
|
regs->gpr.rsp = (unsigned long)usp;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user