Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 210901
b: refs/heads/master
c: 392c218
h: refs/heads/master
i:
  210899: 41c5699
v: v3
  • Loading branch information
David S. Miller committed Sep 22, 2010
1 parent f2e0eb3 commit a4a229b
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 59 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: 05c5e7698bdc54b3079a3517d86077f49ebcc788
refs/heads/master: 392c21802ee3aa85cee0e703105f797a8a7b9416
55 changes: 34 additions & 21 deletions trunk/arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,8 @@ static void flush_signal_insns(unsigned long address)

}

static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
{
struct signal_frame32 __user *sf;
int sigframe_size;
Expand Down Expand Up @@ -620,13 +620,16 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,

sigill:
do_exit(SIGILL);
return -EINVAL;

sigsegv:
force_sigsegv(signo, current);
return -EFAULT;
}

static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long signr, sigset_t *oldset,
siginfo_t *info)
static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long signr, sigset_t *oldset,
siginfo_t *info)
{
struct rt_signal_frame32 __user *sf;
int sigframe_size;
Expand Down Expand Up @@ -738,29 +741,41 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,

flush_signal_insns(address);
}
return;
return 0;

sigill:
do_exit(SIGILL);
return -EINVAL;

sigsegv:
force_sigsegv(signr, current);
return -EFAULT;
}

static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
int err;

if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame32(ka, regs, signr, oldset, info);
err = setup_rt_frame32(ka, regs, signr, oldset, info);
else
setup_frame32(ka, regs, signr, oldset);
err = setup_frame32(ka, regs, signr, oldset);

if (err)
return err;

spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(&current->blocked,signr);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);

tracehook_signal_handler(signr, info, ka, regs, 0);

return 0;
}

static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
Expand Down Expand Up @@ -807,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
if (signr > 0) {
if (restart_syscall)
syscall_restart32(orig_i0, regs, &ka.sa);
handle_signal32(signr, &ka, &info, oldset, regs);

/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;

tracehook_signal_handler(signr, &info, &ka, regs, 0);
if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return;
}
if (restart_syscall &&
Expand Down
53 changes: 33 additions & 20 deletions trunk/arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
return err;
}

static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
{
struct signal_frame __user *sf;
int sigframe_size, err;
Expand Down Expand Up @@ -384,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* Flush instruction space. */
flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
}
return;
return 0;

sigill_and_return:
do_exit(SIGILL);
return -EINVAL;

sigsegv:
force_sigsegv(signo, current);
return -EFAULT;
}

static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
struct rt_signal_frame __user *sf;
int sigframe_size;
Expand Down Expand Up @@ -466,29 +469,41 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* Flush instruction space. */
flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
}
return;
return 0;

sigill:
do_exit(SIGILL);
return -EINVAL;

sigsegv:
force_sigsegv(signo, current);
return -EFAULT;
}

static inline void
static inline int
handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
int err;

if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(ka, regs, signr, oldset, info);
err = setup_rt_frame(ka, regs, signr, oldset, info);
else
setup_frame(ka, regs, signr, oldset);
err = setup_frame(ka, regs, signr, oldset);

if (err)
return err;

spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(&current->blocked, signr);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);

tracehook_signal_handler(signr, info, ka, regs, 0);

return 0;
}

static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
Expand Down Expand Up @@ -546,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
handle_signal(signr, &ka, &info, oldset, regs);

/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);

tracehook_signal_handler(signr, &info, &ka, regs, 0);
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TIF_RESTORE_SIGMASK flag.
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
return;
}
if (restart_syscall &&
Expand Down
43 changes: 26 additions & 17 deletions trunk/arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *
return (void __user *) sp;
}

static inline void
static inline int
setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
Expand Down Expand Up @@ -483,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
}
/* 4. return to kernel instructions */
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
return;
return 0;

sigill:
do_exit(SIGILL);
return -EINVAL;

sigsegv:
force_sigsegv(signo, current);
return -EFAULT;
}

static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
int err;

err = setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (err)
return err;
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
sigaddset(&current->blocked,signr);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);

tracehook_signal_handler(signr, info, ka, regs, 0);

return 0;
}

static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
Expand Down Expand Up @@ -571,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
if (signr > 0) {
if (restart_syscall)
syscall_restart(orig_i0, regs, &ka.sa);
handle_signal(signr, &ka, &info, oldset, regs);

/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;

tracehook_signal_handler(signr, &info, &ka, regs, 0);
if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
/* A signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
* clear the TS_RESTORE_SIGMASK flag.
*/
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
}
return;
}
if (restart_syscall &&
Expand Down

0 comments on commit a4a229b

Please sign in to comment.