ARC: Fix signal frame management for SA_SIGINFO

Previously, when a signal was registered with SA_SIGINFO, parameters 2
and 3 of the signal handler were written to registers r1 and r2 before
the register set was saved. This led to corruption of these two
registers after returning from the signal handler (the wrong values were
restored).
With this patch, registers are now saved before any parameters are
passed, thus maintaining the processor state from before signal entry.

Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
Christian Ruppert 2013-10-02 11:13:38 +02:00 коммит произвёл Vineet Gupta
Родитель 55c2e26204
Коммит 10469350e3
1 изменённых файлов: 13 добавлений и 12 удалений

Просмотреть файл

@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn)
{
struct rt_sigframe __user *sf;
unsigned int magic;
int err;
struct pt_regs *regs = current_pt_regs();
/* Always make any pending restarted system calls return -EINTR */
@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
goto badframe;
err = restore_usr_regs(regs, sf);
err |= __get_user(magic, &sf->sigret_magic);
if (err)
if (__get_user(magic, &sf->sigret_magic))
goto badframe;
if (unlikely(is_do_ss_needed(magic)))
if (restore_altstack(&sf->uc.uc_stack))
goto badframe;
if (restore_usr_regs(regs, sf))
goto badframe;
/* Don't restart from sigreturn */
syscall_wont_restart(regs);
@ -190,6 +190,15 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
if (!sf)
return 1;
/*
* w/o SA_SIGINFO, struct ucontext is partially populated (only
* uc_mcontext/uc_sigmask) for kernel's normal user state preservation
* during signal handler execution. This works for SA_SIGINFO as well
* although the semantics are now overloaded (the same reg state can be
* inspected by userland: but are they allowed to fiddle with it ?
*/
err |= stash_usr_regs(sf, regs, set);
/*
* SA_SIGINFO requires 3 args to signal handler:
* #1: sig-no (common to any handler)
@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
magic = MAGIC_SIGALTSTK;
}
/*
* w/o SA_SIGINFO, struct ucontext is partially populated (only
* uc_mcontext/uc_sigmask) for kernel's normal user state preservation
* during signal handler execution. This works for SA_SIGINFO as well
* although the semantics are now overloaded (the same reg state can be
* inspected by userland: but are they allowed to fiddle with it ?
*/
err |= stash_usr_regs(sf, regs, set);
err |= __put_user(magic, &sf->sigret_magic);
if (err)
return err;