Commit e5fa2d06 authored by Hiroshi Shimamoto's avatar Hiroshi Shimamoto Committed by Ingo Molnar

x86: signal: unify signal_{32|64}.c, prepare

Impact: cleanup

Add #ifdef directive for 32-bit only code.
Signed-off-by: default avatarHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent bfeb91a9
/* /*
* Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs
* *
* 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
* 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
* 2000-2002 x86-64 support by Andi Kleen
*/ */
#include <linux/sched.h> #include <linux/sched.h>
...@@ -481,6 +483,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -481,6 +483,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
} }
#endif /* CONFIG_X86_32 */ #endif /* CONFIG_X86_32 */
#ifdef CONFIG_X86_32
/* /*
* Atomically swap in the new signal mask, and wait for a signal. * Atomically swap in the new signal mask, and wait for a signal.
*/ */
...@@ -535,6 +538,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, ...@@ -535,6 +538,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
return ret; return ret;
} }
#endif /* CONFIG_X86_32 */
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
asmlinkage int sys_sigaltstack(unsigned long bx) asmlinkage int sys_sigaltstack(unsigned long bx)
...@@ -561,6 +565,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, ...@@ -561,6 +565,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
/* /*
* Do a signal return; undo the signal stack. * Do a signal return; undo the signal stack.
*/ */
#ifdef CONFIG_X86_32
asmlinkage unsigned long sys_sigreturn(unsigned long __unused) asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
{ {
struct sigframe __user *frame; struct sigframe __user *frame;
...@@ -603,6 +608,7 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused) ...@@ -603,6 +608,7 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
return 0; return 0;
} }
#endif /* CONFIG_X86_32 */
static long do_rt_sigreturn(struct pt_regs *regs) static long do_rt_sigreturn(struct pt_regs *regs)
{ {
......
...@@ -54,12 +54,24 @@ ...@@ -54,12 +54,24 @@
err |= __get_user(regs->x, &sc->x); \ err |= __get_user(regs->x, &sc->x); \
} }
#define COPY_SEG(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp; \
}
#define COPY_SEG_CPL3(seg) { \ #define COPY_SEG_CPL3(seg) { \
unsigned short tmp; \ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \ err |= __get_user(tmp, &sc->seg); \
regs->seg = tmp | 3; \ regs->seg = tmp | 3; \
} }
#define GET_SEG(seg) { \
unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg, tmp); \
}
static int static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
unsigned long *pax) unsigned long *pax)
...@@ -471,6 +483,63 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -471,6 +483,63 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
} }
#endif /* CONFIG_X86_32 */ #endif /* CONFIG_X86_32 */
#ifdef CONFIG_X86_32
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
mask &= _BLOCKABLE;
spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked;
siginitset(&current->blocked, mask);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
current->state = TASK_INTERRUPTIBLE;
schedule();
set_restore_sigmask();
return -ERESTARTNOHAND;
}
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))
return -EFAULT;
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
__get_user(mask, &act->sa_mask);
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))
return -EFAULT;
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
}
#endif /* CONFIG_X86_32 */
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
asmlinkage int sys_sigaltstack(unsigned long bx) asmlinkage int sys_sigaltstack(unsigned long bx)
{ {
...@@ -496,6 +565,51 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, ...@@ -496,6 +565,51 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
/* /*
* Do a signal return; undo the signal stack. * Do a signal return; undo the signal stack.
*/ */
#ifdef CONFIG_X86_32
asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
{
struct sigframe __user *frame;
struct pt_regs *regs;
unsigned long ax;
sigset_t set;
regs = (struct pt_regs *) &__unused;
frame = (struct sigframe __user *)(regs->sp - 8);
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1
&& __copy_from_user(&set.sig[1], &frame->extramask,
sizeof(frame->extramask))))
goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sighand->siglock);
current->blocked = set;
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
if (restore_sigcontext(regs, &frame->sc, &ax))
goto badframe;
return ax;
badframe:
if (show_unhandled_signals && printk_ratelimit()) {
printk("%s%s[%d] bad frame in sigreturn frame:"
"%p ip:%lx sp:%lx oeax:%lx",
task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
current->comm, task_pid_nr(current), frame, regs->ip,
regs->sp, regs->orig_ax);
print_vma_addr(" in ", regs->ip);
printk(KERN_CONT "\n");
}
force_sig(SIGSEGV, current);
return 0;
}
#endif /* CONFIG_X86_32 */
static long do_rt_sigreturn(struct pt_regs *regs) static long do_rt_sigreturn(struct pt_regs *regs)
{ {
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
...@@ -542,7 +656,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) ...@@ -542,7 +656,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
#endif /* CONFIG_X86_32 */ #endif /* CONFIG_X86_32 */
/* /*
* OK, we're invoking a handler * OK, we're invoking a handler:
*/ */
static int signr_convert(int sig) static int signr_convert(int sig)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment