linux/arch/powerpc/kernel/signal.c
<<
>>
Prefs
   1/*
   2 * Common signal handling code for both 32 and 64 bits
   3 *
   4 *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
   5 *    Extracted from signal_32.c and signal_64.c
   6 *
   7 * This file is subject to the terms and conditions of the GNU General
   8 * Public License.  See the file README.legal in the main directory of
   9 * this archive for more details.
  10 */
  11
  12#include <linux/tracehook.h>
  13#include <linux/signal.h>
  14#include <asm/hw_breakpoint.h>
  15#include <asm/uaccess.h>
  16#include <asm/unistd.h>
  17
  18#include "signal.h"
  19
  20/* Log an error when sending an unhandled signal to a process. Controlled
  21 * through debug.exception-trace sysctl.
  22 */
  23
  24int show_unhandled_signals = 0;
  25
  26/*
  27 * Allocate space for the signal frame
  28 */
  29void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
  30                           size_t frame_size, int is_32)
  31{
  32        unsigned long oldsp, newsp;
  33
  34        /* Default to using normal stack */
  35        oldsp = get_clean_sp(regs, is_32);
  36
  37        /* Check for alt stack */
  38        if ((ka->sa.sa_flags & SA_ONSTACK) &&
  39            current->sas_ss_size && !on_sig_stack(oldsp))
  40                oldsp = (current->sas_ss_sp + current->sas_ss_size);
  41
  42        /* Get aligned frame */
  43        newsp = (oldsp - frame_size) & ~0xFUL;
  44
  45        /* Check access */
  46        if (!access_ok(VERIFY_WRITE, (void __user *)newsp, oldsp - newsp))
  47                return NULL;
  48
  49        return (void __user *)newsp;
  50}
  51
  52
  53/*
  54 * Restore the user process's signal mask
  55 */
  56void restore_sigmask(sigset_t *set)
  57{
  58        sigdelsetmask(set, ~_BLOCKABLE);
  59        spin_lock_irq(&current->sighand->siglock);
  60        current->blocked = *set;
  61        recalc_sigpending();
  62        spin_unlock_irq(&current->sighand->siglock);
  63}
  64
  65static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
  66                                  int has_handler)
  67{
  68        unsigned long ret = regs->gpr[3];
  69        int restart = 1;
  70
  71        /* syscall ? */
  72        if (TRAP(regs) != 0x0C00)
  73                return;
  74
  75        /* error signalled ? */
  76        if (!(regs->ccr & 0x10000000))
  77                return;
  78
  79        switch (ret) {
  80        case ERESTART_RESTARTBLOCK:
  81        case ERESTARTNOHAND:
  82                /* ERESTARTNOHAND means that the syscall should only be
  83                 * restarted if there was no handler for the signal, and since
  84                 * we only get here if there is a handler, we dont restart.
  85                 */
  86                restart = !has_handler;
  87                break;
  88        case ERESTARTSYS:
  89                /* ERESTARTSYS means to restart the syscall if there is no
  90                 * handler or the handler was registered with SA_RESTART
  91                 */
  92                restart = !has_handler || (ka->sa.sa_flags & SA_RESTART) != 0;
  93                break;
  94        case ERESTARTNOINTR:
  95                /* ERESTARTNOINTR means that the syscall should be
  96                 * called again after the signal handler returns.
  97                 */
  98                break;
  99        default:
 100                return;
 101        }
 102        if (restart) {
 103                if (ret == ERESTART_RESTARTBLOCK)
 104                        regs->gpr[0] = __NR_restart_syscall;
 105                else
 106                        regs->gpr[3] = regs->orig_gpr3;
 107                regs->nip -= 4;
 108                regs->result = 0;
 109        } else {
 110                regs->result = -EINTR;
 111                regs->gpr[3] = EINTR;
 112                regs->ccr |= 0x10000000;
 113        }
 114}
 115
 116static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
 117{
 118        siginfo_t info;
 119        int signr;
 120        struct k_sigaction ka;
 121        int ret;
 122        int is32 = is_32bit_task();
 123
 124        if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
 125                oldset = &current->saved_sigmask;
 126        else if (!oldset)
 127                oldset = &current->blocked;
 128
 129        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 130
 131        /* Is there any syscall restart business here ? */
 132        check_syscall_restart(regs, &ka, signr > 0);
 133
 134        if (signr <= 0) {
 135                struct thread_info *ti = current_thread_info();
 136                /* No signal to deliver -- put the saved sigmask back */
 137                if (ti->local_flags & _TLF_RESTORE_SIGMASK) {
 138                        ti->local_flags &= ~_TLF_RESTORE_SIGMASK;
 139                        sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 140                }
 141                regs->trap = 0;
 142                return 0;               /* no signals delivered */
 143        }
 144
 145#ifndef CONFIG_PPC_ADV_DEBUG_REGS
 146        /*
 147         * Reenable the DABR before delivering the signal to
 148         * user space. The DABR will have been cleared if it
 149         * triggered inside the kernel.
 150         */
 151        if (current->thread.dabr)
 152                set_dabr(current->thread.dabr);
 153#endif
 154        /* Re-enable the breakpoints for the signal stack */
 155        thread_change_pc(current, regs);
 156
 157        if (is32) {
 158                if (ka.sa.sa_flags & SA_SIGINFO)
 159                        ret = handle_rt_signal32(signr, &ka, &info, oldset,
 160                                        regs);
 161                else
 162                        ret = handle_signal32(signr, &ka, &info, oldset,
 163                                        regs);
 164        } else {
 165                ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
 166        }
 167
 168        regs->trap = 0;
 169        if (ret) {
 170                spin_lock_irq(&current->sighand->siglock);
 171                sigorsets(&current->blocked, &current->blocked,
 172                          &ka.sa.sa_mask);
 173                if (!(ka.sa.sa_flags & SA_NODEFER))
 174                        sigaddset(&current->blocked, signr);
 175                recalc_sigpending();
 176                spin_unlock_irq(&current->sighand->siglock);
 177
 178                /*
 179                 * A signal was successfully delivered; the saved sigmask is in
 180                 * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
 181                 */
 182                current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
 183
 184                /*
 185                 * Let tracing know that we've done the handler setup.
 186                 */
 187                tracehook_signal_handler(signr, &info, &ka, regs,
 188                                         test_thread_flag(TIF_SINGLESTEP));
 189        }
 190
 191        return ret;
 192}
 193
 194void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
 195{
 196        if (thread_info_flags & _TIF_SIGPENDING)
 197                do_signal_pending(NULL, regs);
 198
 199        if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 200                clear_thread_flag(TIF_NOTIFY_RESUME);
 201                tracehook_notify_resume(regs);
 202        }
 203}
 204
 205long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 206                unsigned long r5, unsigned long r6, unsigned long r7,
 207                unsigned long r8, struct pt_regs *regs)
 208{
 209        return do_sigaltstack(uss, uoss, regs->gpr[1]);
 210}
 211