summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/s390/Kconfig7
-rw-r--r--arch/s390/kernel/traps.c31
-rw-r--r--arch/s390/mm/fault.c32
-rw-r--r--kernel/sysctl.c5
4 files changed, 33 insertions, 42 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 0d8cd9bbe101..79d0ca086820 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -444,13 +444,6 @@ config FORCE_MAX_ZONEORDER
int
default "9"
-config PROCESS_DEBUG
- bool "Show crashed user process info"
- help
- Say Y to print all process fault locations to the console. This is
- a debugging option; you probably do not want to set it unless you
- are an S390 port maintainer.
-
config PFAULT
bool "Pseudo page fault support"
help
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index e605f070610c..5d8f0f3d0250 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -46,13 +46,7 @@
pgm_check_handler_t *pgm_check_table[128];
-#ifdef CONFIG_SYSCTL
-#ifdef CONFIG_PROCESS_DEBUG
-int sysctl_userprocess_debug = 1;
-#else
-int sysctl_userprocess_debug = 0;
-#endif
-#endif
+int show_unhandled_signals;
extern pgm_check_handler_t do_protection_exception;
extern pgm_check_handler_t do_dat_exception;
@@ -315,18 +309,19 @@ void die(const char * str, struct pt_regs * regs, long err)
do_exit(SIGSEGV);
}
-static void inline
-report_user_fault(long interruption_code, struct pt_regs *regs)
+static void inline report_user_fault(struct pt_regs *regs, long int_code,
+ int signr)
{
-#if defined(CONFIG_SYSCTL)
- if (!sysctl_userprocess_debug)
+ if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
return;
-#endif
-#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
- printk("User process fault: interruption code 0x%lX\n",
- interruption_code);
+ if (!unhandled_signal(current, signr))
+ return;
+ if (!printk_ratelimit())
+ return;
+ printk("User process fault: interruption code 0x%lX ", int_code);
+ print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
+ printk("\n");
show_regs(regs);
-#endif
}
int is_valid_bugaddr(unsigned long addr)
@@ -354,7 +349,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
tsk->thread.trap_no = interruption_code & 0xffff;
force_sig_info(signr, info, tsk);
- report_user_fault(interruption_code, regs);
+ report_user_fault(regs, interruption_code, signr);
} else {
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -390,7 +385,7 @@ static void default_trap_handler(struct pt_regs * regs, long interruption_code)
{
if (regs->psw.mask & PSW_MASK_PSTATE) {
local_irq_enable();
- report_user_fault(interruption_code, regs);
+ report_user_fault(regs, interruption_code, SIGSEGV);
do_exit(SIGSEGV);
} else
die("Unknown program exception", regs, interruption_code);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 3040d7c78fe0..2505b2ea0ef1 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -48,10 +48,6 @@
#define __PF_RES_FIELD 0x8000000000000000ULL
#endif /* CONFIG_64BIT */
-#ifdef CONFIG_SYSCTL
-extern int sysctl_userprocess_debug;
-#endif
-
#define VM_FAULT_BADCONTEXT 0x010000
#define VM_FAULT_BADMAP 0x020000
#define VM_FAULT_BADACCESS 0x040000
@@ -120,6 +116,22 @@ static inline int user_space_fault(unsigned long trans_exc_code)
return trans_exc_code != 3;
}
+static inline void report_user_fault(struct pt_regs *regs, long int_code,
+ int signr, unsigned long address)
+{
+ if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
+ return;
+ if (!unhandled_signal(current, signr))
+ return;
+ if (!printk_ratelimit())
+ return;
+ printk("User process fault: interruption code 0x%lX ", int_code);
+ print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
+ printk("\n");
+ printk("failing address: %lX\n", address);
+ show_regs(regs);
+}
+
/*
* Send SIGSEGV to task. This is an external routine
* to keep the stack usage of do_page_fault small.
@@ -133,17 +145,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
address = trans_exc_code & __FAIL_ADDR_MASK;
current->thread.prot_addr = address;
current->thread.trap_no = int_code;
-#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
-#if defined(CONFIG_SYSCTL)
- if (sysctl_userprocess_debug)
-#endif
- {
- printk("User process fault: interruption code 0x%lX\n",
- int_code);
- printk("failing address: %lX\n", address);
- show_regs(regs);
- }
-#endif
+ report_user_fault(regs, int_code, SIGSEGV, address);
si.si_signo = SIGSEGV;
si.si_code = si_code;
si.si_addr = (void __user *) address;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8686b0f5fc12..90f536d84643 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -621,7 +621,7 @@ static struct ctl_table kern_table[] = {
#endif
{
.procname = "userprocess_debug",
- .data = &sysctl_userprocess_debug,
+ .data = &show_unhandled_signals,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
@@ -1431,7 +1431,8 @@ static struct ctl_table fs_table[] = {
};
static struct ctl_table debug_table[] = {
-#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
+ defined(CONFIG_S390)
{
.procname = "exception-trace",
.data = &show_unhandled_signals,