From 162523b9ccc6f3370e203fdc480ea86bc7be5f49 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2012 03:08:53 -0500 Subject: [PATCH] --- yaml --- r: 356692 b: refs/heads/master c: 4a9d32d377e1facca204cc1c6856406be8b53fa3 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/m68k/Kconfig | 3 -- trunk/arch/m68k/include/asm/signal.h | 7 ++++ trunk/arch/m68k/kernel/signal.c | 59 +++++++++++++++++++++++++-- trunk/arch/microblaze/Kconfig | 1 + trunk/arch/microblaze/kernel/signal.c | 17 +------- 6 files changed, 67 insertions(+), 22 deletions(-) diff --git a/[refs] b/[refs] index d14da3d3c6d9..53d8ca2febc6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8be433ab55d5058327e82f124f1eb0b37e4540b1 +refs/heads/master: 4a9d32d377e1facca204cc1c6856406be8b53fa3 diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index a358bf63defe..6710084e072a 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -18,9 +18,6 @@ config M68K select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_REL select MODULES_USE_ELF_RELA - select GENERIC_SIGALTSTACK - select OLD_SIGSUSPEND3 - select OLD_SIGACTION config RWSEM_GENERIC_SPINLOCK bool diff --git a/trunk/arch/m68k/include/asm/signal.h b/trunk/arch/m68k/include/asm/signal.h index 214320b50384..c7b4fb1fa14d 100644 --- a/trunk/arch/m68k/include/asm/signal.h +++ b/trunk/arch/m68k/include/asm/signal.h @@ -16,6 +16,13 @@ typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + #define __ARCH_HAS_SA_RESTORER #include diff --git a/trunk/arch/m68k/kernel/signal.c b/trunk/arch/m68k/kernel/signal.c index 2a16df3d9312..9a396cda3147 100644 --- a/trunk/arch/m68k/kernel/signal.c +++ b/trunk/arch/m68k/kernel/signal.c @@ -224,6 +224,56 @@ static inline void push_cache(unsigned long vaddr) #endif /* CONFIG_MMU */ +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int +sys_sigsuspend(int unused0, int unused1, 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) +{ + return do_sigaltstack(uss, uoss, rdusp()); +} + + /* * Do a signal return; undo the signal stack. * @@ -715,9 +765,8 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, err |= __get_user(temp, &uc->uc_formatvec); err |= rt_restore_fpu_state(uc); - err |= restore_altstack(&uc->uc_stack); - if (err) + if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) goto badframe; if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) @@ -965,7 +1014,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, rdusp()); + err |= __put_user((void __user *)current->sas_ss_sp, + &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(rdusp()), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); err |= rt_setup_ucontext(&frame->uc, regs); err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index ba3b7c8c04b8..5e30d75c74ed 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -27,6 +27,7 @@ config MICROBLAZE select GENERIC_CLOCKEVENTS select MODULES_USE_ELF_RELA select CLONE_BACKWARDS + select GENERIC_SIGALTSTACK config SWAP def_bool n diff --git a/trunk/arch/microblaze/kernel/signal.c b/trunk/arch/microblaze/kernel/signal.c index ac3d0a0f4814..dfd61e2f1189 100644 --- a/trunk/arch/microblaze/kernel/signal.c +++ b/trunk/arch/microblaze/kernel/signal.c @@ -41,13 +41,6 @@ #include #include -asmlinkage long -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, - struct pt_regs *regs) -{ - return do_sigaltstack(uss, uoss, regs->r1); -} - /* * Do a signal return; undo the signal stack. */ @@ -109,9 +102,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) goto badframe; - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) + if (restore_altstack(&frame->uc.uc_stack)) goto badframe; return rval; @@ -194,11 +185,7 @@ 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 |= __put_user((void __user *)current->sas_ss_sp, - &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->r1), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= __save_altstack(&frame->uc.uc_stack, regs->r1); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));