1867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 2867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Copyright (C) 1991, 1992 Linus Torvalds 3867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Copyright 2010 Tilera Corporation. All Rights Reserved. 4867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 5867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is free software; you can redistribute it and/or 6867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * modify it under the terms of the GNU General Public License 7867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * as published by the Free Software Foundation, version 2. 8867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 9867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is distributed in the hope that it will be useful, but 10867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * WITHOUT ANY WARRANTY; without even the implied warranty of 11867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 12867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * NON INFRINGEMENT. See the GNU General Public License for 13867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * more details. 14867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 15867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 16867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/sched.h> 17867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/mm.h> 18867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/smp.h> 19867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/kernel.h> 20867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/signal.h> 21867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/errno.h> 22867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/wait.h> 23867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/unistd.h> 24867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/stddef.h> 25867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/personality.h> 26867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/suspend.h> 27867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/ptrace.h> 28867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/elf.h> 29867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/compat.h> 30867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/syscalls.h> 31867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/uaccess.h> 32867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/processor.h> 33867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/ucontext.h> 34867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/sigframe.h> 350707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf#include <asm/syscalls.h> 36867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <arch/interrupts.h> 37867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 38867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#define DEBUG_SIG 0 39867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 40867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 41867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 42d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris MetcalfSYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, 43d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris Metcalf stack_t __user *, uoss, struct pt_regs *, regs) 44867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 45867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return do_sigaltstack(uss, uoss, regs->sp); 46867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 47867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 48867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 49867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 50867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Do a signal return; undo the signal stack. 51867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 52867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 53867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfint restore_sigcontext(struct pt_regs *regs, 5481711cee933599fa114abb0d258d8bbabef8adfbChris Metcalf struct sigcontext __user *sc) 55867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 56867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int err = 0; 57867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int i; 58867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 59867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Always make any pending restarted system calls return -EINTR */ 60867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->restart_block.fn = do_no_restart_syscall; 61867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 6274fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf /* 6374fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * Enforce that sigcontext is like pt_regs, and doesn't mess 6474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * up our stack alignment rules. 6574fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf */ 6674fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); 6774fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); 6874fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf 69867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) 7074fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf err |= __get_user(regs->regs[i], &sc->gregs[i]); 71867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 721deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf /* Ensure that the PL is always set to USER_PL. */ 731deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); 741deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf 75867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->faultnum = INT_SWINT_1_SIGRETURN; 76867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 77867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return err; 78867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 79867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 80571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalfvoid signal_fault(const char *type, struct pt_regs *regs, 81571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf void __user *frame, int sig) 82571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf{ 83571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf trace_unhandled_signal(type, regs, (unsigned long)frame, SIGSEGV); 84571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf force_sigsegv(sig, current); 85571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf} 86571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 8781711cee933599fa114abb0d258d8bbabef8adfbChris Metcalf/* The assembly shim for this function arranges to ignore the return value. */ 88d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris MetcalfSYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) 89867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 90867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct rt_sigframe __user *frame = 91867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf (struct rt_sigframe __user *)(regs->sp); 92867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t set; 93867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 94867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 95867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 96867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 97867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 98867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 99867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigdelsetmask(&set, ~_BLOCKABLE); 100ad092338350e517608a41341095b6b1e312c4eb1Matt Fleming set_current_blocked(&set); 101867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 10281711cee933599fa114abb0d258d8bbabef8adfbChris Metcalf if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 103867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 104867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 105867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 106867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 107867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 10881711cee933599fa114abb0d258d8bbabef8adfbChris Metcalf return 0; 109867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 110867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfbadframe: 111571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf signal_fault("bad sigreturn frame", regs, frame, 0); 112867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return 0; 113867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 114867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 115867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 116867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Set up a signal frame. 117867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 118867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 119867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfint setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) 120867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 121867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int i, err = 0; 122867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 123867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) 12474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf err |= __put_user(regs->regs[i], &sc->gregs[i]); 125867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 126867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return err; 127867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 128867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 129867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 130867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Determine which stack to use.. 131867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 132867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline void __user *get_sigframe(struct k_sigaction *ka, 133867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct pt_regs *regs, 134867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf size_t frame_size) 135867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 136867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long sp; 137867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 138867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Default to using normal stack */ 139867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp = regs->sp; 140867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 141867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 142867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * If we are on the alternate signal stack and would overflow 143867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * it, don't. Return an always-bogus address instead so we 144867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * will die with SIGSEGV. 145867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 146867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) 1470707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf return (void __user __force *)-1UL; 148867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 149867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* This is the X/Open sanctioned signal stack switching. */ 150867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_ONSTACK) { 151867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (sas_ss_flags(sp) == 0) 152867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp = current->sas_ss_sp + current->sas_ss_size; 153867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 154867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 155867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp -= frame_size; 156867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 157867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Align the stack pointer according to the TILE ABI, 158867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * i.e. so that on function entry (sp & 15) == 0. 159867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 160867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp &= -16UL; 161867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return (void __user *) sp; 162867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 163867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 164867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 165867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t *set, struct pt_regs *regs) 166867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 167867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long restorer; 168867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct rt_sigframe __user *frame; 169867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int err = 0; 170867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int usig; 171867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 172867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf frame = get_sigframe(ka, regs, sizeof(*frame)); 173867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 174867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 175867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto give_sigsegv; 176867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 177867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf usig = current_thread_info()->exec_domain 178867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf && current_thread_info()->exec_domain->signal_invmap 179867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf && sig < 32 180867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ? current_thread_info()->exec_domain->signal_invmap[sig] 181867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf : sig; 182867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 183867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Always write at least the signal number for the stack backtracer. */ 184867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_SIGINFO) { 185867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* At sigreturn time, restore the callee-save registers too. */ 186867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= copy_siginfo_to_user(&frame->info, info); 187867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_RESTORE_REGS; 188867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } else { 189867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(info->si_signo, &frame->info.si_signo); 190867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 191867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 192867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Create the ucontext. */ 193867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __clear_user(&frame->save_area, sizeof(frame->save_area)); 194867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(0, &frame->uc.uc_flags); 1950707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf err |= __put_user(NULL, &frame->uc.uc_link); 1960707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf err |= __put_user((void __user *)(current->sas_ss_sp), 197867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf &frame->uc.uc_stack.ss_sp); 198867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(sas_ss_flags(regs->sp), 199867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf &frame->uc.uc_stack.ss_flags); 200867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 201867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 202867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 203867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (err) 204867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto give_sigsegv; 205867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 206867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf restorer = VDSO_BASE; 207867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_RESTORER) 208867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf restorer = (unsigned long) ka->sa.sa_restorer; 209867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 210867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 211867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Set up registers for signal handler. 212867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Registers that we don't modify keep the value they had from 213867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * user-space at the time we took the signal. 21474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 21574fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * since some things rely on this (e.g. glibc's debug/segfault.c). 216867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 217867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc = (unsigned long) ka->sa.sa_handler; 218867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 219867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->sp = (unsigned long) frame; 220867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->lr = restorer; 221867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = (unsigned long) usig; 22274fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->regs[1] = (unsigned long) &frame->info; 22374fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->regs[2] = (unsigned long) &frame->uc; 22474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 225867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 226867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 227867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Notify any tracer that was single-stepping it. 228867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * The tracer may want to single-step inside the 229867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * handler too. 230867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 231867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (test_thread_flag(TIF_SINGLESTEP)) 232867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ptrace_notify(SIGTRAP); 233867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 234867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return 0; 235867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 236867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfgive_sigsegv: 237571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf signal_fault("bad setup frame", regs, frame, sig); 238867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return -EFAULT; 239867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 240867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 241867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 242867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * OK, we're invoking a handler 243867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 244867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 245867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic int handle_signal(unsigned long sig, siginfo_t *info, 246867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct k_sigaction *ka, sigset_t *oldset, 247867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct pt_regs *regs) 248867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 249867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int ret; 250867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 251867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Are we from a system call? */ 252867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (regs->faultnum == INT_SWINT_1) { 253867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* If so, check system call restarting.. */ 254867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf switch (regs->regs[0]) { 255867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTART_RESTARTBLOCK: 256867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOHAND: 257867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = -EINTR; 258867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 259867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 260867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTSYS: 261867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!(ka->sa.sa_flags & SA_RESTART)) { 262867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = -EINTR; 263867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 264867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 265867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* fallthrough */ 266867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOINTR: 267867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Reload caller-saves to restore r0..r5 and r10. */ 268867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 269867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = regs->orig_r0; 270867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 271867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 272867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 273867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 274867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Set up the stack frame */ 275867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#ifdef CONFIG_COMPAT 276867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (is_compat_task()) 277867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ret = compat_setup_rt_frame(sig, ka, info, oldset, regs); 278867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf else 279867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#endif 280867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ret = setup_rt_frame(sig, ka, info, oldset, regs); 281867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ret == 0) { 282867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* This code is only called from system calls or from 283867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * the work_pending path in the return-to-user code, and 284867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * either way we can re-enable interrupts unconditionally. 285867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 286ad092338350e517608a41341095b6b1e312c4eb1Matt Fleming block_sigmask(ka, sig); 287867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 288867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 289867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return ret; 290867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 291867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 292867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 293867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Note that 'init' is a special process: it doesn't get signals it doesn't 294867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * want to handle. Thus you cannot kill init even with a SIGKILL even by 295867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * mistake. 296867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 297867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfvoid do_signal(struct pt_regs *regs) 298867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 299867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf siginfo_t info; 300867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int signr; 301867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct k_sigaction ka; 302867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t *oldset; 303867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 304867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 305867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * i386 will check if we're coming from kernel mode and bail out 306867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * here. In my experience this just turns weird crashes into 307867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * weird spin-hangs. But if we find a case where this seems 308867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * helpful, we can reinstate the check on "!user_mode(regs)". 309867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 310867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 311867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (current_thread_info()->status & TS_RESTORE_SIGMASK) 312867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf oldset = ¤t->saved_sigmask; 313867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf else 314867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf oldset = ¤t->blocked; 315867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 316867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf signr = get_signal_to_deliver(&info, &ka, regs, NULL); 317867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (signr > 0) { 318867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Whee! Actually deliver the signal. */ 319867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 320867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 321867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * A signal was successfully delivered; the saved 322867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * sigmask will have been stored in the signal frame, 323867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * and will be restored by sigreturn, so we can simply 324867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * clear the TS_RESTORE_SIGMASK flag. 325867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 326867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 327867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 328867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 32934a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf goto done; 330867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 331867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 332867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Did we come from a system call? */ 333867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (regs->faultnum == INT_SWINT_1) { 334867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Restart the system call - no handlers present */ 335867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf switch (regs->regs[0]) { 336867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOHAND: 337867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTSYS: 338867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOINTR: 339867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 340867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = regs->orig_r0; 341867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 342867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 343867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 344867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTART_RESTARTBLOCK: 345867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 346867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall; 347867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 348867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 349867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 350867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 351867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 352867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* If there's no signal to deliver, just put the saved sigmask back. */ 353867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 354867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 355867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 356867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 35734a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf 35834a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalfdone: 35934a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf /* Avoid double syscall restart if there are nested signals. */ 36034a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf regs->faultnum = INT_SWINT_1_SIGRETURN; 361867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 362571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 363571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalfint show_unhandled_signals = 1; 364571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 365571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalfstatic int __init crashinfo(char *str) 366571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf{ 367571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf unsigned long val; 368571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf const char *word; 369571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 370571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (*str == '\0') 371571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf val = 2; 372571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf else if (*str != '=' || strict_strtoul(++str, 0, &val) != 0) 373571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return 0; 374571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf show_unhandled_signals = val; 375571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf switch (show_unhandled_signals) { 376571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case 0: 377571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf word = "No"; 378571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf break; 379571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case 1: 380571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf word = "One-line"; 381571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf break; 382571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf default: 383571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf word = "Detailed"; 384571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf break; 385571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 386571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_info("%s crash reports will be generated on the console\n", word); 387571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return 1; 388571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf} 389571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf__setup("crashinfo", crashinfo); 390571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 391571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalfstatic void dump_mem(void __user *address) 392571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf{ 393571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf void __user *addr; 394571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf enum { region_size = 256, bytes_per_line = 16 }; 395571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf int i, j, k; 396571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf int found_readable_mem = 0; 397571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 398571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("\n"); 399571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (!access_ok(VERIFY_READ, address, 1)) { 400571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("Not dumping at address 0x%lx (kernel address)\n", 401571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf (unsigned long)address); 402571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return; 403571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 404571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 405571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf addr = (void __user *) 406571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf (((unsigned long)address & -bytes_per_line) - region_size/2); 407571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (addr > address) 408571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf addr = NULL; 409571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf for (i = 0; i < region_size; 410571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf addr += bytes_per_line, i += bytes_per_line) { 411571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf unsigned char buf[bytes_per_line]; 412571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf char line[100]; 413571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (copy_from_user(buf, addr, bytes_per_line)) 414571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf continue; 415571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (!found_readable_mem) { 416571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("Dumping memory around address 0x%lx:\n", 417571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf (unsigned long)address); 418571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf found_readable_mem = 1; 419571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 420571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf j = sprintf(line, REGFMT":", (unsigned long)addr); 421571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf for (k = 0; k < bytes_per_line; ++k) 422571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf j += sprintf(&line[j], " %02x", buf[k]); 423571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("%s\n", line); 424571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 425571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (!found_readable_mem) 426571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("No readable memory around address 0x%lx\n", 427571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf (unsigned long)address); 428571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf} 429571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 430571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalfvoid trace_unhandled_signal(const char *type, struct pt_regs *regs, 431571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf unsigned long address, int sig) 432571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf{ 433571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf struct task_struct *tsk = current; 434571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 435571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (show_unhandled_signals == 0) 436571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return; 437571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 438571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf /* If the signal is handled, don't show it here. */ 439571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (!is_global_init(tsk)) { 440571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf void __user *handler = 441571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf tsk->sighand->action[sig-1].sa.sa_handler; 442571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (handler != SIG_IGN && handler != SIG_DFL) 443571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return; 444571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 445571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 446571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf /* Rate-limit the one-line output, not the detailed output. */ 447571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (show_unhandled_signals <= 1 && !printk_ratelimit()) 448571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf return; 449571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 450571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d", 451571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, 452571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig); 453571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 454571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf print_vma_addr(KERN_CONT " in ", regs->pc); 455571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 456571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf printk(KERN_CONT "\n"); 457571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf 458571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf if (show_unhandled_signals > 1) { 459571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf switch (sig) { 460571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case SIGILL: 461571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case SIGFPE: 462571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case SIGSEGV: 463571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf case SIGBUS: 464571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("User crash: signal %d," 465571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf " trap %ld, address 0x%lx\n", 466571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf sig, regs->faultnum, address); 467571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf show_regs(regs); 468571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf dump_mem((void __user *)address); 469571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf break; 470571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf default: 471571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf pr_err("User crash: signal %d, trap %ld\n", 472571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf sig, regs->faultnum); 473571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf break; 474571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 475571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf } 476571d76acdab95876aeff869ab6449f826c23aa43Chris Metcalf} 477