Commit 4627c87c authored by David S. Miller's avatar David S. Miller

[SPARC]: Catchup with signal infrastructure changes.

parent 2f752fa9
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
static struct fs_struct init_fs = INIT_FS; static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES; static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS; static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm); struct mm_struct init_mm = INIT_MM(init_mm);
struct task_struct init_task = INIT_TASK(init_task); struct task_struct init_task = INIT_TASK(init_task);
......
...@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr); ...@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int restart_syscall); unsigned long orig_o0, int restart_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* Signal frames: the original one (compatible with SunOS): /* Signal frames: the original one (compatible with SunOS):
* *
* Set up a signal frame... Make the stack look the way SunOS * Set up a signal frame... Make the stack look the way SunOS
...@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old ...@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
synchronize_user_stack(); synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ); sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){ if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that /* Don't change signal code and address, so that
* post mortem debuggers can have a look. * post mortem debuggers can have a look.
*/ */
...@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size)) if (invalid_frame_pointer (sf, sigframe_size))
goto sigill_and_return; goto sigill_and_return;
if (current->thread.w_saved != 0) { if (current->thread.w_saved != 0)
#ifdef DEBUG_SIGNALS
printk ("%s [%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill_and_return; goto sigill_and_return;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs)); err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs));
...@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
synchronize_user_stack(); synchronize_user_stack();
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ); sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){ if (invalid_frame_pointer (sfp, sizeof (*sfp)))
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
goto sigill_and_return; goto sigill_and_return;
}
/* Start with a clean frame pointer and fill it */ /* Start with a clean frame pointer and fill it */
err = __clear_user(sfp, sizeof (*sfp)); err = __clear_user(sfp, sizeof (*sfp));
...@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->pc = (unsigned long) sa->sa_handler; regs->pc = (unsigned long) sa->sa_handler;
regs->npc = (regs->pc + 4); regs->npc = (regs->pc + 4);
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
#endif
/* Arguments passed to signal handler */ /* Arguments passed to signal handler */
if (regs->u_regs [14]){ if (regs->u_regs [14]){
struct reg_window *rw = (struct reg_window *) regs->u_regs [14]; struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
...@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -1152,7 +1074,6 @@ static inline void read_maps (void) ...@@ -1152,7 +1074,6 @@ static inline void read_maps (void)
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
struct k_sigaction *ka; struct k_sigaction *ka;
siginfo_t info; siginfo_t info;
...@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
oldset = &current->blocked; oldset = &current->blocked;
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
restart_syscall = 0; restart_syscall = 0;
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
/* This happens to be SMP safe so no need to /* This happens to be SMP safe so no need to
* grab master kernel lock even in this case. * grab master kernel lock even in this case.
...@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (is_orphaned_pgrp(current->pgrp)) if (is_orphaned_pgrp(current->pgrp))
continue; continue;
case SIGSTOP: case SIGSTOP: {
if (current->ptrace & PT_PTRACED) struct signal_struct *sig;
continue; set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig;
/* notify_parent() is SMP safe */ if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
if(!(current->parent->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
continue; continue;
}
case SIGQUIT: case SIGILL: case SIGTRAP: case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sigaddset(&current->pending.signal, signr); sig_exit(signr, exit_code, &info);
recalc_sigpending();
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOT REACHED */ /* NOT REACHED */
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
static struct fs_struct init_fs = INIT_FS; static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES; static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS; static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm); struct mm_struct init_mm = INIT_MM(init_mm);
/* .text section in head.S is aligned at 2 page boundry and this gets linked /* .text section in head.S is aligned at 2 page boundry and this gets linked
......
...@@ -36,11 +36,6 @@ ...@@ -36,11 +36,6 @@
static int do_signal(sigset_t *oldset, struct pt_regs * regs, static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int ret_from_syscall); unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{ {
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
...@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size)) if (invalid_frame_pointer (sf, sigframe_size))
goto sigill; goto sigill;
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
err = copy_to_user(&sf->regs, regs, sizeof (*regs)); err = copy_to_user(&sf->regs, regs, sizeof (*regs));
...@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -694,7 +628,6 @@ static inline void read_maps (void) ...@@ -694,7 +628,6 @@ static inline void read_maps (void)
static int do_signal(sigset_t *oldset, struct pt_regs * regs, static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
siginfo_t info; siginfo_t info;
struct k_sigaction *ka; struct k_sigaction *ka;
...@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
} }
#endif #endif
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
...@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
...@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug the dynamic linker */
printk ("Sig %d going...\n", (int)signr);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
unsigned long ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sig_exit(signr, exit_code, &info); sig_exit(signr, exit_code, &info);
/* NOT REACHED */ /* NOT REACHED */
......
...@@ -34,12 +34,6 @@ ...@@ -34,12 +34,6 @@
int do_signal32(sigset_t *oldset, struct pt_regs *regs, int do_signal32(sigset_t *oldset, struct pt_regs *regs,
unsigned long orig_o0, int ret_from_syscall); unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* #define DEBUG_SIGNALS_TLB 1 */
/* Signal frames: the original one (compatible with SunOS): /* Signal frames: the original one (compatible with SunOS):
* *
* Set up a signal frame... Make the stack look the way SunOS * Set up a signal frame... Make the stack look the way SunOS
...@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o ...@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ); sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){ if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%016lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that /* Don't change signal code and address, so that
* post mortem debuggers can have a look. * post mortem debuggers can have a look.
*/ */
...@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg ...@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) { if (invalid_frame_pointer (sf, sigframe_size))
#ifdef DEBUG_SIGNALS
printk("new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
goto sigill; goto sigill;
}
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { if (test_thread_flag(TIF_32BIT)) {
...@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED); sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){ if (invalid_frame_pointer (sfp, sizeof (*sfp)))
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
do_exit(SIGILL); do_exit(SIGILL);
}
/* Start with a clean frame pointer and fill it */ /* Start with a clean frame pointer and fill it */
err = clear_user(sfp, sizeof (*sfp)); err = clear_user(sfp, sizeof (*sfp));
...@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->tnpc &= 0xffffffff; regs->tnpc &= 0xffffffff;
} }
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc);
#endif
/* Arguments passed to signal handler */ /* Arguments passed to signal handler */
if (regs->u_regs [14]){ if (regs->u_regs [14]){
struct reg_window32 *rw = (struct reg_window32 *) struct reg_window32 *rw = (struct reg_window32 *)
...@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) ...@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
synchronize_user_stack(); synchronize_user_stack();
save_and_clear_fpu(); save_and_clear_fpu();
if (get_thread_wsaved()) { if (get_thread_wsaved())
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is not zero (%d)\n", (int) get_thread_wsaved());
#endif
do_exit (SIGSEGV); do_exit (SIGSEGV);
}
err = clear_user(uc, sizeof (*uc)); err = clear_user(uc, sizeof (*uc));
/* Setup convenience variables */ /* Setup convenience variables */
...@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) ...@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
*/ */
flush_user_windows(); flush_user_windows();
if (get_thread_wsaved()) { if (get_thread_wsaved())
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is: 0x%x\n", get_thread_wsaved());
#endif
goto sigsegv; goto sigsegv;
}
if (((unsigned long) c) & 3){ if (((unsigned long) c) & 3){
printk ("Unaligned structure passed\n"); printk ("Unaligned structure passed\n");
goto sigsegv; goto sigsegv;
...@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) ...@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
gr = &c->mcontext.greg; gr = &c->mcontext.greg;
err = __get_user(pc, &((*gr)[SVR4_PC])); err = __get_user(pc, &((*gr)[SVR4_PC]));
err |= __get_user(npc, &((*gr)[SVR4_NPC])); err |= __get_user(npc, &((*gr)[SVR4_NPC]));
if ((pc | npc) & 3) { if ((pc | npc) & 3)
#ifdef DEBUG_SIGNALS
printk ("setcontext, PC or nPC were bogus\n");
#endif
goto sigsegv; goto sigsegv;
}
/* Retrieve information from passed ucontext */ /* Retrieve information from passed ucontext */
/* note that nPC is ored a 1, this is used to inform entry.S */ /* note that nPC is ored a 1, this is used to inform entry.S */
...@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs ...@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) { if (invalid_frame_pointer (sf, sigframe_size))
#ifdef DEBUG_SIGNALS
printk("rt_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
goto sigill; goto sigill;
}
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { if (test_thread_flag(TIF_32BIT)) {
...@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs ...@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -1380,16 +1275,27 @@ static inline void read_maps (void) ...@@ -1380,16 +1275,27 @@ static inline void read_maps (void)
int do_signal32(sigset_t *oldset, struct pt_regs * regs, int do_signal32(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
struct k_sigaction *ka; struct k_sigaction *ka;
siginfo_t info; siginfo_t info;
int svr4_signal = current->personality == PER_SVR4; int svr4_signal = current->personality == PER_SVR4;
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
...@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
...@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
/* On SMP we are only interested in the current
* CPU's registers.
*/
__show_regs (regs);
#ifdef DEBUG_SIGNALS_TLB
do {
extern void sparc_ultra_dump_itlb(void);
extern void sparc_ultra_dump_dtlb(void);
sparc_ultra_dump_dtlb();
sparc_ultra_dump_itlb();
} while (0);
#endif
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window32 *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sig_exit(signr, exit_code, &info); sig_exit(signr, exit_code, &info);
/* NOT REACHED */ /* NOT REACHED */
......
...@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, ...@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
return -EINVAL; return -EINVAL;
} }
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sig->siglock);
sig = dequeue_signal(&these, &info); spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
if (!sig) { if (!sig) {
/* None ready -- temporarily unblock those we're interested
in so that we'll be awakened when they arrive. */
sigset_t oldblocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
timeout = MAX_SCHEDULE_TIMEOUT; timeout = MAX_SCHEDULE_TIMEOUT;
if (uts) if (uts)
timeout = (timespec_to_jiffies(&ts) timeout = (timespec_to_jiffies(&ts)
+ (ts.tv_sec || ts.tv_nsec)); + (ts.tv_sec || ts.tv_nsec));
current->state = TASK_INTERRUPTIBLE; if (timeout) {
timeout = schedule_timeout(timeout); /* None ready -- temporarily unblock those we're
* interested while we are sleeping in so that we'll
spin_lock_irq(&current->sigmask_lock); * be awakened when they arrive. */
sig = dequeue_signal(&these, &info); current->real_blocked = current->blocked;
current->blocked = oldblocked; sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending(); recalc_sigpending();
spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
spin_lock_irq(&current->sig->siglock);
spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
current->blocked = current->real_blocked;
siginitset(&current->real_blocked, 0);
recalc_sigpending();
}
} }
spin_unlock_irq(&current->sigmask_lock); spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
if (sig) { if (sig) {
ret = sig; ret = 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