Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356746
b: refs/heads/master
c: 99b06fe
h: refs/heads/master
v: v3
  • Loading branch information
Al Viro committed Feb 3, 2013
1 parent f2c5e85 commit 894ca05
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 94 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0679a858c5439bf4bc05fd211d3690f82fefa5b6
refs/heads/master: 99b06feb0f7c99f171cb962d0e6a17f81625abd3
3 changes: 0 additions & 3 deletions trunk/arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ config SUPERH
select GENERIC_STRNLEN_USER
select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER
select MODULES_USE_ELF_RELA
select GENERIC_SIGALTSTACK
select OLD_SIGSUSPEND
select OLD_SIGACTION
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
Expand Down
6 changes: 6 additions & 0 deletions trunk/arch/sh/include/asm/syscalls_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

struct pt_regs;

asmlinkage int sys_sigsuspend(old_sigset_t mask);
asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact);
asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/sh/include/uapi/asm/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@

#include <asm-generic/signal.h>

#ifndef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
#endif

#endif /* __ASM_SH_SIGNAL_H */
63 changes: 61 additions & 2 deletions trunk/arch/sh/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,60 @@ struct fdpic_func_descriptor {
*/
#define UNWINDGUARD 64

/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int
sys_sigsuspend(old_sigset_t mask)
{
sigset_t blocked;
siginitset(&blocked, mask);
return sigsuspend(&blocked);
}

asmlinkage int
sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;

if (act) {
old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
__get_user(mask, &act->sa_mask))
return -EFAULT;
siginitset(&new_ka.sa.sa_mask, mask);
}

ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
__put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
}

return ret;
}

asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);

return do_sigaltstack(uss, uoss, regs->regs[15]);
}


/*
* Do a signal return; undo the signal stack.
*/
Expand Down Expand Up @@ -203,7 +257,8 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
goto badframe;

if (restore_altstack(&frame->uc.uc_stack))
if (do_sigaltstack(&frame->uc.uc_stack, NULL,
regs->regs[15]) == -EFAULT)
goto badframe;

return r0;
Expand Down Expand Up @@ -368,7 +423,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(NULL, &frame->uc.uc_link);
err |= __save_altstack(&frame->uc.uc_stack, regs->regs[15]);
err |= __put_user((void *)current->sas_ss_sp,
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[15]),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
Expand Down
62 changes: 60 additions & 2 deletions trunk/arch/sh/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,58 @@ static void do_signal(struct pt_regs *regs)
restore_saved_sigmask();
}

/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int
sys_sigsuspend(old_sigset_t mask)
{
sigset_t blocked;
siginitset(&blocked, mask);
return sigsuspend(&blocked);
}

asmlinkage int
sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;

if (act) {
old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
__get_user(mask, &act->sa_mask))
return -EFAULT;
siginitset(&new_ka.sa.sa_mask, mask);
}

ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);

if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
__put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
}

return ret;
}

asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r4, unsigned long r5, unsigned long r6,
unsigned long r7,
struct pt_regs * regs)
{
return do_sigaltstack(uss, uoss, REF_REG_SP);
}

/*
* Do a signal return; undo the signal stack.
*/
Expand Down Expand Up @@ -312,7 +364,9 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
goto badframe;
regs->pc -= 4;

if (restore_altstack(&frame->uc.uc_stack))
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT)
goto badframe;

return (int) ret;
Expand Down Expand Up @@ -506,7 +560,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
err |= __save_altstack(&frame->uc.uc_stack, regs->regs[REG_SP]);
err |= __put_user((void *)current->sas_ss_sp,
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[REG_SP]),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ config SPARC
select GENERIC_STRNLEN_USER
select MODULES_USE_ELF_RELA
select ODD_RT_SIGACTION
select GENERIC_SIGALTSTACK

config SPARC32
def_bool !64BIT
Expand Down
6 changes: 0 additions & 6 deletions trunk/arch/sparc/include/asm/compat_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ struct __old_sigaction32 {
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
};

typedef struct sigaltstack32 {
u32 ss_sp;
int ss_flags;
compat_size_t ss_size;
} stack_t32;
#endif

#endif /* !(_COMPAT_SIGNAL_H) */
8 changes: 0 additions & 8 deletions trunk/arch/sparc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -819,14 +819,6 @@ sys_sparc_pipe:
call sparc_pipe
mov %l5, %o7

.align 4
.globl sys_sigaltstack
sys_sigaltstack:
mov %o7, %l5
mov %fp, %o2
call do_sigaltstack
mov %l5, %o7

.align 4
.globl sys_sigstack
sys_sigstack:
Expand Down
48 changes: 4 additions & 44 deletions trunk/arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct rt_signal_frame32 {
compat_sigset_t mask;
/* __siginfo_fpu_t * */ u32 fpu_save;
unsigned int insns[2];
stack_t32 stack;
compat_stack_t stack;
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus;
Expand Down Expand Up @@ -230,13 +230,11 @@ void do_sigreturn32(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{
struct rt_signal_frame32 __user *sf;
unsigned int psr, pc, npc, u_ss_sp;
unsigned int psr, pc, npc;
compat_uptr_t fpu_save;
compat_uptr_t rwin_save;
mm_segment_t old_fs;
sigset_t set;
compat_sigset_t seta;
stack_t st;
int err, i;

/* Always make any pending restarted system calls return -EINTR */
Expand Down Expand Up @@ -295,20 +293,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
if (!err && fpu_save)
err |= restore_fpu_state(regs, compat_ptr(fpu_save));
err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
st.ss_sp = compat_ptr(u_ss_sp);
err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
err |= __get_user(st.ss_size, &sf->stack.ss_size);
err |= compat_restore_altstack(&sf->stack);
if (err)
goto segv;

/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs);

err |= __get_user(rwin_save, &sf->rwin_save);
if (!err && rwin_save) {
if (restore_rwin_state(compat_ptr(rwin_save)))
Expand Down Expand Up @@ -642,9 +630,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err |= copy_siginfo_to_user32(&sf->info, info);

/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);

switch (_NSIG_WORDS) {
case 4: seta.sig[7] = (oldset->sig[3] >> 32);
Expand Down Expand Up @@ -856,29 +842,3 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
out:
return ret;
}

asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
{
stack_t uss, uoss;
u32 u_ss_sp = 0;
int ret;
mm_segment_t old_fs;
stack_t32 __user *uss32 = compat_ptr(ussa);
stack_t32 __user *uoss32 = compat_ptr(uossa);

if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
__get_user(uss.ss_flags, &uss32->ss_flags) ||
__get_user(uss.ss_size, &uss32->ss_size)))
return -EFAULT;
uss.ss_sp = compat_ptr(u_ss_sp);
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
uossa ? (stack_t __user *) &uoss : NULL, sp);
set_fs(old_fs);
if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
__put_user(uoss.ss_flags, &uoss32->ss_flags) ||
__put_user(uoss.ss_size, &uoss32->ss_size)))
return -EFAULT;
return ret;
}
17 changes: 2 additions & 15 deletions trunk/arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
unsigned int psr, pc, npc;
__siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
mm_segment_t old_fs;
sigset_t set;
stack_t st;
int err;

synchronize_user_stack();
Expand Down Expand Up @@ -171,23 +169,14 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
if (!err && fpu_save)
err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));

err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
err |= restore_altstack(&sf->stack);

if (err)
goto segv;

regs->pc = pc;
regs->npc = npc;

/* It is more difficult to avoid calling this function than to
* call it and ignore errors.
*/
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs);

err |= __get_user(rwin_save, &sf->rwin_save);
if (!err && rwin_save) {
if (restore_rwin_state(rwin_save))
Expand Down Expand Up @@ -391,9 +380,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));

/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);

if (!wsaved) {
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
Expand Down
7 changes: 3 additions & 4 deletions trunk/arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ void do_rt_sigreturn(struct pt_regs *regs)
err |= restore_fpu_state(regs, fpu_save);

err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
err |= restore_altstack(&sf->stack);
if (err)
goto segv;

err |= __get_user(rwin_save, &sf->rwin_save);
Expand Down Expand Up @@ -403,9 +404,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
}

/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);

err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));

Expand Down
Loading

0 comments on commit 894ca05

Please sign in to comment.