x86: signal: move {setup|restore}_sigcontext()
PATCH 1/3 x86: signal: move {setup|restore}_sigcontext()
From: Hiroshi Shimamoto <[email protected]>
Impact: cleanup
Move {setup|restore}_sigcontext() declaration onto head of file.
--- arch/x86/kernel/signal_32.c | 271 ++++++++++++++++++++++--------------------- arch/x86/kernel/signal_64.c | 148 ++++++++++++------------ 2 files changed, 210 insertions(+), 209 deletions(-)
arch/x86/kernel/signal_32.c +136 -135
@@ -70,6 +70,142 @@ static const struct { 0 }; +#define COPY (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) { \ + unsigned short tmp; \ + err |= __get_user(tmp, &sc->seg); \ + regs->seg = tmp | 3; \ +} + +#define GET_SEG (seg) { \ + unsigned short tmp; \ + err |= __get_user(tmp, &sc->seg); \ + loadsegment(seg, tmp); \ +} + +static int +restore_sigcontext (struct pt_regs *regs,struct sigcontext __user *sc, +unsigned long *pax) +{ +void __user *buf; +unsigned int tmpflags; +unsigned int err =0 ; + +/* Always make any pending restarted system calls return -EINTR */ +current_thread_info ()->restart_block.fn = do_no_restart_syscall; + +#ifdef CONFIG_X86_32 +GET_SEG (gs); +COPY_SEG (fs); +COPY_SEG (es); +COPY_SEG (ds); +#endif /* CONFIG_X86_32 */ + +COPY (di);COPY (si);COPY (bp);COPY (sp);COPY (bx); +COPY (dx);COPY (cx);COPY (ip); + +#ifdef CONFIG_X86_64 +COPY (r8); +COPY (r9); +COPY (r10); +COPY (r11); +COPY (r12); +COPY (r13); +COPY (r14); +COPY (r15); +#endif /* CONFIG_X86_64 */ + +#ifdef CONFIG_X86_32 +COPY_SEG_CPL3 (cs); +COPY_SEG_CPL3 (ss); +#else /* !CONFIG_X86_32 */ +/* Kernel saves and restores only the CS segment register on signals, +* which is the bare minimum needed to allow mixed 32/64-bit code. +* App's signal handler can save/restore other segments if needed. */ +COPY_SEG_CPL3 (cs); +#endif /* CONFIG_X86_32 */ + + err |=__get_user (tmpflags, &sc->flags); + regs->flags = (regs->flags & ~FIX_EFLAGS ) | (tmpflags &FIX_EFLAGS ); + regs->orig_ax =-1 ;/* disable syscall checks */ + + err |=__get_user (buf, &sc->fpstate); + err |=restore_i387_xstate (buf); + + err |=__get_user (*pax, &sc->ax); +return err; +} + +static int +setup_sigcontext (struct sigcontext __user *sc,void __user *fpstate, +struct pt_regs *regs,unsigned long mask) +{ +int err =0 ; + +#ifdef CONFIG_X86_32 + { +unsigned int tmp; + +savesegment (gs, tmp); + err |=__put_user (tmp, (unsigned int __user *)&sc->gs); + } + err |=__put_user (regs->fs, (unsigned int __user *)&sc->fs); + err |=__put_user (regs->es, (unsigned int __user *)&sc->es); + err |=__put_user (regs->ds, (unsigned int __user *)&sc->ds); +#endif /* CONFIG_X86_32 */ + + err |=__put_user (regs->di, &sc->di); + err |=__put_user (regs->si, &sc->si); + err |=__put_user (regs->bp, &sc->bp); + err |=__put_user (regs->sp, &sc->sp); + err |=__put_user (regs->bx, &sc->bx); + err |=__put_user (regs->dx, &sc->dx); + err |=__put_user (regs->cx, &sc->cx); + err |=__put_user (regs->ax, &sc->ax); +#ifdef CONFIG_X86_64 + err |=__put_user (regs->r8, &sc->r8); + err |=__put_user (regs->r9, &sc->r9); + err |=__put_user (regs->r10, &sc->r10); + err |=__put_user (regs->r11, &sc->r11); + err |=__put_user (regs->r12, &sc->r12); + err |=__put_user (regs->r13, &sc->r13); + err |=__put_user (regs->r14, &sc->r14); + err |=__put_user (regs->r15, &sc->r15); +#endif /* CONFIG_X86_64 */ + + err |=__put_user (current->thread.trap_no, &sc->trapno); + err |=__put_user (current->thread.error_code, &sc->err); + err |=__put_user (regs->ip, &sc->ip); +#ifdef CONFIG_X86_32 + err |=__put_user (regs->cs, (unsigned int __user *)&sc->cs); + err |=__put_user (regs->flags, &sc->flags); + err |=__put_user (regs->sp, &sc->sp_at_signal); + err |=__put_user (regs->ss, (unsigned int __user *)&sc->ss); +#else /* !CONFIG_X86_32 */ + err |=__put_user (regs->flags, &sc->flags); + err |=__put_user (regs->cs, &sc->cs); + err |=__put_user (0 , &sc->gs); + err |=__put_user (0 , &sc->fs); +#endif /* CONFIG_X86_32 */ + + err |=__put_user (fpstate, &sc->fpstate); + +/* non-iBCS2 extensions.. */ + err |=__put_user (mask, &sc->oldmask); + err |=__put_user (current->thread.cr2, &sc->cr2); + +return err; +} +/* * Atomically swap in the new signal mask, and wait for a signal. */
@@ -147,84 +283,9 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, }#endif /* CONFIG_X86_32 */ -#define COPY (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) { \ - unsigned short tmp; \ - err |= __get_user(tmp, &sc->seg); \ - regs->seg = tmp | 3; \ -} - -#define GET_SEG (seg) { \ - unsigned short tmp; \ - err |= __get_user(tmp, &sc->seg); \ - loadsegment(seg, tmp); \ -} -/* * Do a signal return; undo the signal stack. */ -static int -restore_sigcontext (struct pt_regs *regs,struct sigcontext __user *sc, -unsigned long *pax) -{ -void __user *buf; -unsigned int tmpflags; -unsigned int err =0 ; - -/* Always make any pending restarted system calls return -EINTR */ -current_thread_info ()->restart_block.fn = do_no_restart_syscall; - -#ifdef CONFIG_X86_32 -GET_SEG (gs); -COPY_SEG (fs); -COPY_SEG (es); -COPY_SEG (ds); -#endif /* CONFIG_X86_32 */ - -COPY (di);COPY (si);COPY (bp);COPY (sp);COPY (bx); -COPY (dx);COPY (cx);COPY (ip); - -#ifdef CONFIG_X86_64 -COPY (r8); -COPY (r9); -COPY (r10); -COPY (r11); -COPY (r12); -COPY (r13); -COPY (r14); -COPY (r15); -#endif /* CONFIG_X86_64 */ - -#ifdef CONFIG_X86_32 -COPY_SEG_CPL3 (cs); -COPY_SEG_CPL3 (ss); -#else /* !CONFIG_X86_32 */ -/* Kernel saves and restores only the CS segment register on signals, -* which is the bare minimum needed to allow mixed 32/64-bit code. -* App's signal handler can save/restore other segments if needed. */ -COPY_SEG_CPL3 (cs); -#endif /* CONFIG_X86_32 */ - - err |=__get_user (tmpflags, &sc->flags); - regs->flags = (regs->flags & ~FIX_EFLAGS ) | (tmpflags &FIX_EFLAGS ); - regs->orig_ax =-1 ;/* disable syscall checks */ - - err |=__get_user (buf, &sc->fpstate); - err |=restore_i387_xstate (buf); - - err |=__get_user (*pax, &sc->ax); -return err; -} -asmlinkage unsigned long sys_sigreturn (unsigned long __unused) {struct sigframe __user *frame;
@@ -316,66 +377,6 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)/* * Set up a signal frame. */ -static int -setup_sigcontext (struct sigcontext __user *sc,void __user *fpstate, -struct pt_regs *regs,unsigned long mask) -{ -int err =0 ; - -#ifdef CONFIG_X86_32 - { -unsigned int tmp; - -savesegment (gs, tmp); - err |=__put_user (tmp, (unsigned int __user *)&sc->gs); - } - err |=__put_user (regs->fs, (unsigned int __user *)&sc->fs); - err |=__put_user (regs->es, (unsigned int __user *)&sc->es); - err |=__put_user (regs->ds, (unsigned int __user *)&sc->ds); -#endif /* CONFIG_X86_32 */ - - err |=__put_user (regs->di, &sc->di); - err |=__put_user (regs->si, &sc->si); - err |=__put_user (regs->bp, &sc->bp); - err |=__put_user (regs->sp, &sc->sp); - err |=__put_user (regs->bx, &sc->bx); - err |=__put_user (regs->dx, &sc->dx); - err |=__put_user (regs->cx, &sc->cx); - err |=__put_user (regs->ax, &sc->ax); -#ifdef CONFIG_X86_64 - err |=__put_user (regs->r8, &sc->r8); - err |=__put_user (regs->r9, &sc->r9); - err |=__put_user (regs->r10, &sc->r10); - err |=__put_user (regs->r11, &sc->r11); - err |=__put_user (regs->r12, &sc->r12); - err |=__put_user (regs->r13, &sc->r13); - err |=__put_user (regs->r14, &sc->r14); - err |=__put_user (regs->r15, &sc->r15); -#endif /* CONFIG_X86_64 */ - - err |=__put_user (current->thread.trap_no, &sc->trapno); - err |=__put_user (current->thread.error_code, &sc->err); - err |=__put_user (regs->ip, &sc->ip); -#ifdef CONFIG_X86_32 - err |=__put_user (regs->cs, (unsigned int __user *)&sc->cs); - err |=__put_user (regs->flags, &sc->flags); - err |=__put_user (regs->sp, &sc->sp_at_signal); - err |=__put_user (regs->ss, (unsigned int __user *)&sc->ss); -#else /* !CONFIG_X86_32 */ - err |=__put_user (regs->flags, &sc->flags); - err |=__put_user (regs->cs, &sc->cs); - err |=__put_user (0 , &sc->gs); - err |=__put_user (0 , &sc->fs); -#endif /* CONFIG_X86_32 */ - - err |=__put_user (fpstate, &sc->fpstate); - -/* non-iBCS2 extensions.. */ - err |=__put_user (mask, &sc->oldmask); - err |=__put_user (current->thread.cr2, &sc->cr2); - -return err; -}/* * Determine which stack to use..
arch/x86/kernel/signal_64.c +74 -74
175 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH 2/3 x86: signal: cosmetic unification of __setup_sigframe() and __setup_rt_sigframe()
From: Hiroshi Shimamoto <[email protected]>
Subject: [PATCH]
Impact: cleanup
Add #ifdef directive to unify __setup_sigframe() and __setup_rt_sigframe(). Move them after {setup|restore}_sigcontext() declaration.
--- arch/x86/kernel/signal_32.c | 469 ++++++++++++++++++++++++++----------------- arch/x86/kernel/signal_64.c | 309 +++++++++++++++++++++++----- 2 files changed, 536 insertions(+), 242 deletions(-)
arch/x86/kernel/signal_32.c +280 -189
@@ -48,28 +48,6 @@# define FIX_EFLAGS __FIX_EFLAGS#endif -static const struct { -u16 poplmovl; -u32 val; -u16 int80; -} __attribute__((packed)) retcode = { -0xb858 ,/* popl %eax; movl $..., %eax */ - __NR_sigreturn, -0x80cd ,/* int $0x80 */ -}; - -static const struct { -u8 movl; -u32 val; -u16 int80; -u8 pad; -} __attribute__((packed)) rt_retcode = { -0xb8 ,/* movl $..., %eax */ - __NR_rt_sigreturn, -0x80cd ,/* int $0x80 */ -0 -}; -#define COPY (x) { \ err |= __get_user(regs->x, &sc->x); \ }
@@ -207,176 +185,30 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, }/* -* Atomically swap in the new signal mask, and wait for a signal. +* Set up a signal frame. */ -asmlinkage int -sys_sigsuspend (int history0,int history1,old_sigset_t mask) -{ - mask &= _BLOCKABLE; -spin_lock_irq (¤t->sighand->siglock); - current->saved_sigmask = current->blocked; -siginitset (¤t->blocked, mask); -recalc_sigpending (); -spin_unlock_irq (¤t->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; -} -#ifdef CONFIG_X86_32 -asmlinkage int sys_sigaltstack(unsigned long bx) -{ -/* -* This is needed to make gcc realize it doesn't own the -* "struct pt_regs" -*/ -struct pt_regs *regs = (struct pt_regs *)&bx; -const stack_t __user *uss = (const stack_t __user *)bx; -stack_t __user *uoss = (stack_t __user *)regs->cx; - -return do_sigaltstack (uss, uoss, regs->sp); -} -#else /* !CONFIG_X86_32 */ -asmlinkage long -sys_sigaltstack (const stack_t __user *uss,stack_t __user *uoss, -struct pt_regs *regs) -{ -return do_sigaltstack (uss, uoss, regs->sp); -} -#endif /* CONFIG_X86_32 */ - -/* -* Do a signal return; undo the signal stack. -*/ -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 (¤t->sighand->siglock); - current->blocked = set; -recalc_sigpending (); -spin_unlock_irq (¤t->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 ; -} - -static long do_rt_sigreturn (struct pt_regs *regs) -{ -struct rt_sigframe __user *frame; -unsigned long ax; -sigset_t set; - - frame = (struct rt_sigframe __user *)(regs->sp -sizeof (long )); -if (!access_ok (VERIFY_READ , frame,sizeof (*frame))) - goto badframe; -if (__copy_from_user (&set, &frame->uc.uc_sigmask,sizeof (set))) - goto badframe; - -sigdelsetmask (&set, ~_BLOCKABLE); -spin_lock_irq (¤t->sighand->siglock); - current->blocked = set; -recalc_sigpending (); -spin_unlock_irq (¤t->sighand->siglock); - -if (restore_sigcontext (regs, &frame->uc.uc_mcontext, &ax)) - goto badframe; - -if (do_sigaltstack (&frame->uc.uc_stack,NULL , regs->sp) == -EFAULT ) - goto badframe; - -return ax; - -badframe: -signal_fault (regs, frame,"rt_sigreturn" ); -return 0 ; -} - -#ifdef CONFIG_X86_32 -asmlinkage int sys_rt_sigreturn(unsigned long __unused) -{ -struct pt_regs *regs = (struct pt_regs *)&__unused; - -return do_rt_sigreturn (regs); -} -#else /* !CONFIG_X86_32 */ -asmlinkage long sys_rt_sigreturn (struct pt_regs *regs) -{ -return do_rt_sigreturn (regs); -} -#endif /* CONFIG_X86_32 */ +static const struct { +u16 poplmovl; +u32 val; +u16 int80; +} __attribute__((packed)) retcode = { +0xb858 ,/* popl %eax; movl $..., %eax */ + __NR_sigreturn, +0x80cd ,/* int $0x80 */ +}; -/* -* Set up a signal frame. -*/ +static const struct { +u8 movl; +u32 val; +u16 int80; +u8 pad; +} __attribute__((packed)) rt_retcode = { +0xb8 ,/* movl $..., %eax */ + __NR_rt_sigreturn, +0x80cd ,/* int $0x80 */ +0 +};/* * Determine which stack to use..
@@ -557,6 +389,265 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,return 0 ; } +#else /* !CONFIG_X86_32 */ +/* +* Determine which stack to use.. +*/ +static void __user * +get_stack (struct k_sigaction *ka,unsigned long sp,unsigned long size) +{ +/* Default to using normal stack - redzone*/ + sp -=128 ; + +/* This is the X/Open sanctioned signal stack switching. */ +if (ka->sa.sa_flags &SA_ONSTACK ) { +if (sas_ss_flags (sp) ==0 ) + sp = current->sas_ss_sp + current->sas_ss_size; + } + +return (void __user *)round_down (sp - size,64 ); +} + +static int __setup_rt_frame (int sig,struct k_sigaction *ka,siginfo_t *info, +sigset_t *set,struct pt_regs *regs) +{ +struct rt_sigframe __user *frame; +void __user *fp =NULL ; +int err =0 ; +struct task_struct *me = current; + +if (used_math ()) { + fp =get_stack (ka, regs->sp, sig_xstate_size); + frame = (void __user *)round_down ( + (unsigned long )fp -sizeof (struct rt_sigframe ),16 ) -8 ; + +if (save_i387_xstate (fp) <0 ) +return -EFAULT ; + }else + frame =get_stack (ka, regs->sp,sizeof (struct rt_sigframe )) -8 ; + +if (!access_ok (VERIFY_WRITE , frame,sizeof (*frame))) +return -EFAULT ; + +if (ka->sa.sa_flags &SA_SIGINFO ) { +if (copy_siginfo_to_user (&frame->info, info)) +return -EFAULT ; + } + +/* Create the ucontext. */ +if (cpu_has_xsave) + err |=__put_user (UC_FP_XSTATE , &frame->uc.uc_flags); +else + err |=__put_user (0 , &frame->uc.uc_flags); + err |=__put_user (0 , &frame->uc.uc_link); + err |=__put_user (me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |=__put_user (sas_ss_flags (regs->sp), + &frame->uc.uc_stack.ss_flags); + err |=__put_user (me->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |=setup_sigcontext (&frame->uc.uc_mcontext, fp, regs, set->sig[0 ]); + err |=__copy_to_user (&frame->uc.uc_sigmask, set,sizeof (*set)); + +/* Set up to return from userspace. If provided, use a stub +already in userspace. */ +/* x86-64 should always use SA_RESTORER. */ +if (ka->sa.sa_flags &SA_RESTORER ) { + err |=__put_user (ka->sa.sa_restorer, &frame->pretcode); + }else { +/* could use a vstub here */ +return -EFAULT ; + } + +if (err) +return -EFAULT ; + +/* Set up registers for signal handler */ + regs->di = sig; +/* In case the signal handler was declared without prototypes */ + regs->ax =0 ; + +/* This also works for non SA_SIGINFO handlers because they expect the +next argument after the signal number on the stack. */ + regs->si = (unsigned long )&frame->info; + regs->dx = (unsigned long )&frame->uc; + regs->ip = (unsigned long ) ka->sa.sa_handler; + + regs->sp = (unsigned long )frame; + +/* Set up the CS register to run signal handlers in 64-bit mode, +even if the handler happens to be interrupting 32-bit code. */ + regs->cs = __USER_CS; + +return 0 ; +} +#endif /* 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 (¤t->sighand->siglock); + current->saved_sigmask = current->blocked; +siginitset (¤t->blocked, mask); +recalc_sigpending (); +spin_unlock_irq (¤t->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; +} + +#ifdef CONFIG_X86_32 +asmlinkage int sys_sigaltstack(unsigned long bx) +{ +/* +* This is needed to make gcc realize it doesn't own the +* "struct pt_regs" +*/ +struct pt_regs *regs = (struct pt_regs *)&bx; +const stack_t __user *uss = (const stack_t __user *)bx; +stack_t __user *uoss = (stack_t __user *)regs->cx; + +return do_sigaltstack (uss, uoss, regs->sp); +} +#else /* !CONFIG_X86_32 */ +asmlinkage long +sys_sigaltstack (const stack_t __user *uss,stack_t __user *uoss, +struct pt_regs *regs) +{ +return do_sigaltstack (uss, uoss, regs->sp); +} +#endif /* CONFIG_X86_32 */ + +/* +* Do a signal return; undo the signal stack. +*/ +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 (¤t->sighand->siglock); + current->blocked = set; +recalc_sigpending (); +spin_unlock_irq (¤t->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 ; +} + +static long do_rt_sigreturn (struct pt_regs *regs) +{ +struct rt_sigframe __user *frame; +unsigned long ax; +sigset_t set; + + frame = (struct rt_sigframe __user *)(regs->sp -sizeof (long )); +if (!access_ok (VERIFY_READ , frame,sizeof (*frame))) + goto badframe; +if (__copy_from_user (&set, &frame->uc.uc_sigmask,sizeof (set))) + goto badframe; + +sigdelsetmask (&set, ~_BLOCKABLE); +spin_lock_irq (¤t->sighand->siglock); + current->blocked = set; +recalc_sigpending (); +spin_unlock_irq (¤t->sighand->siglock); + +if (restore_sigcontext (regs, &frame->uc.uc_mcontext, &ax)) + goto badframe; + +if (do_sigaltstack (&frame->uc.uc_stack,NULL , regs->sp) == -EFAULT ) + goto badframe; + +return ax; + +badframe: +signal_fault (regs, frame,"rt_sigreturn" ); +return 0 ; +} + +#ifdef CONFIG_X86_32 +asmlinkage int sys_rt_sigreturn(unsigned long __unused) +{ +struct pt_regs *regs = (struct pt_regs *)&__unused; + +return do_rt_sigreturn (regs); +} +#else /* !CONFIG_X86_32 */ +asmlinkage long sys_rt_sigreturn (struct pt_regs *regs) +{ +return do_rt_sigreturn (regs); +} +#endif /* CONFIG_X86_32 */ /* * OK, we're invoking a handler:
arch/x86/kernel/signal_64.c +256 -53
342 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH 3/3 x86: signal: unify signal_{32|64}.c
In reply to Hiroshi ShimamotoFrom: Hiroshi Shimamoto <[email protected]>
Impact: cleanup
Add #ifdef directive for 32-bit only code and unify signal_{32|64}.c
--- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/signal.c | 915 +++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/signal_32.c | 909 ------------------------------------------ arch/x86/kernel/signal_64.c | 801 ------------------------------------- 4 files changed, 916 insertions(+), 1711 deletions(-) create mode 100644 arch/x86/kernel/signal.c delete mode 100644 arch/x86/kernel/signal_32.c delete mode 100644 arch/x86/kernel/signal_64.c
arch/x86/kernel/Makefile +1 -1
@@ -30,7 +30,7 @@ CFLAGS_hpet.o := $(nostackp) CFLAGS_tsc.o := $(nostackp) CFLAGS_paravirt.o := $(nostackp) -obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o +obj-y := process_$(BITS).o signal.o entry_$(BITS).o obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
arch/x86/kernel/signal.c new file +915 -0
915 lines not on this page · raw message
arch/x86/kernel/signal_32.c deleted +0 -909
909 lines not on this page · raw message
arch/x86/kernel/signal_64.c deleted +0 -801
801 lines not on this page · raw message
Signature · 1 line
1.6.0.4
Ingo Molnar
AppliedRe: [PATCH 3/3] x86: signal: unify signal_{32|64}.c
Quoted 7 lines · Hiroshi Shimamoto
From: Hiroshi Shimamoto <[email protected]>
Impact: cleanup
Add #ifdef directive for 32-bit only code and unify signal_{32|64}.c
Signed-off-by Hiroshi Shimamoto <[email protected]>
Quoted 9 lines
--- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/signal.c | 915 +++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/signal_32.c | 909 ------------------------------------------ arch/x86/kernel/signal_64.c | 801 ------------------------------------- 4 files changed, 916 insertions(+), 1711 deletions(-) create mode 100644 arch/x86/kernel/signal.c delete mode 100644 arch/x86/kernel/signal_32.c delete mode 100644 arch/x86/kernel/signal_64.c
yay! :-)
applied to tip/x86/signal, thanks Hiroshi!
One small detail, i inserted yet another commit in the middle:
5ceb40d: x86: signal: unify signal_{32|64}.c
e5fa2d0: x86: signal: unify signal_{32|64}.c, prepare
bfeb91a: x86: signal: cosmetic unification of __setup_sigframe() and __setup_rt_sigframe() 2601657: x86: signal: move {setup|restore}_sigcontext()
the e5fa2d0 commit (see it below) contains all the non-mechanic modifications that you did in the final unification commit. It's best to keep this separate - because a big unification commit is hard to review and debug, should it cause any problems.
the 5ceb40d commit can thus do pure unification:
arch/x86/kernel/signal.c | 915 +++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/signal_32.c | 915 ------------------------------------------- arch/x86/kernel/signal_64.c | 915 -------------------------------------------
... and the end result is still the same as with your series.
Thanks,
Ingo
------------------>
Quoted 1 line
From
e5fa2d063cf2ca38eae5fb3469315db669d5c041Mon Sep 17 00:00:00 2001
From: Hiroshi Shimamoto <[email protected]>
Date: Mon, 24 Nov 2008 18:24:11 -0800
Subject: [PATCH] x86: signal: unify signal_{32|64}.c, prepare
Impact: cleanup
Add #ifdef directive for 32-bit only code.
--- arch/x86/kernel/signal_32.c | 6 ++ arch/x86/kernel/signal_64.c | 116 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 1 deletions(-)
arch/x86/kernel/signal_32.c +6 -0
@@ -1,8 +1,10 @@/* * 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 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes +* 2000-2002 x86-64 support by Andi Kleen */ #include <linux/sched.h>
@@ -481,6 +483,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, }#endif /* CONFIG_X86_32 */ +#ifdef CONFIG_X86_32 /* * 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,return ret; } +#endif /* CONFIG_X86_32 */ #ifdef CONFIG_X86_32 asmlinkage int sys_sigaltstack(unsigned long bx)
@@ -561,6 +565,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,/* * Do a signal return; undo the signal stack. */ +#ifdef CONFIG_X86_32 asmlinkage unsigned long sys_sigreturn (unsigned long __unused) {struct sigframe __user *frame;
@@ -603,6 +608,7 @@ badframe: return 0; } +#endif /* CONFIG_X86_32 */ static long do_rt_sigreturn (struct pt_regs *regs) {
arch/x86/kernel/signal_64.c +115 -1
146 lines not on this page · raw message
Re: [PATCH 3/3] x86: signal: unify signal_{32|64}.c
Quoted 30 lines · Ingo Molnar
Quoted 7 lines · Hiroshi Shimamoto
From: Hiroshi Shimamoto <[email protected]>
Impact: cleanup
Add #ifdef directive for 32-bit only code and unify signal_{32|64}.c
Signed-off-by Hiroshi Shimamoto <[email protected]>Quoted 9 lines
--- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/signal.c | 915 +++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/signal_32.c | 909 ------------------------------------------ arch/x86/kernel/signal_64.c | 801 ------------------------------------- 4 files changed, 916 insertions(+), 1711 deletions(-) create mode 100644 arch/x86/kernel/signal.c delete mode 100644 arch/x86/kernel/signal_32.c delete mode 100644 arch/x86/kernel/signal_64.cyay! :-)
applied to tip/x86/signal, thanks Hiroshi!
One small detail, i inserted yet another commit in the middle:
5ceb40d: x86: signal: unify signal_{32|64}.c
e5fa2d0: x86: signal: unify signal_{32|64}.c, prepare
bfeb91a: x86: signal: cosmetic unification of__setup_sigframe()and__setup_rt_sigframe()2601657: x86: signal: move {setup|restore}_sigcontext()
Quoted 4 lines
the e5fa2d0 commit (see it below) contains all the non-mechanic modifications that you did in the final unification commit. It's best to keep this separate - because a big unification commit is hard to review and debug, should it cause any problems.
Hi Ingo,
thanks for the above change, I think I was in a hurry because of Thanksgiving Day week.
thanks,
Hiroshi Shimamoto