diff options
| -rw-r--r-- | arch/s390/Kconfig | 7 | ||||
| -rw-r--r-- | arch/s390/kernel/traps.c | 31 | ||||
| -rw-r--r-- | arch/s390/mm/fault.c | 32 | ||||
| -rw-r--r-- | kernel/sysctl.c | 5 |
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 | |||
| 444 | int | 444 | int |
| 445 | default "9" | 445 | default "9" |
| 446 | 446 | ||
| 447 | config PROCESS_DEBUG | ||
| 448 | bool "Show crashed user process info" | ||
| 449 | help | ||
| 450 | Say Y to print all process fault locations to the console. This is | ||
| 451 | a debugging option; you probably do not want to set it unless you | ||
| 452 | are an S390 port maintainer. | ||
| 453 | |||
| 454 | config PFAULT | 447 | config PFAULT |
| 455 | bool "Pseudo page fault support" | 448 | bool "Pseudo page fault support" |
| 456 | help | 449 | 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 @@ | |||
| 46 | 46 | ||
| 47 | pgm_check_handler_t *pgm_check_table[128]; | 47 | pgm_check_handler_t *pgm_check_table[128]; |
| 48 | 48 | ||
| 49 | #ifdef CONFIG_SYSCTL | 49 | int show_unhandled_signals; |
| 50 | #ifdef CONFIG_PROCESS_DEBUG | ||
| 51 | int sysctl_userprocess_debug = 1; | ||
| 52 | #else | ||
| 53 | int sysctl_userprocess_debug = 0; | ||
| 54 | #endif | ||
| 55 | #endif | ||
| 56 | 50 | ||
| 57 | extern pgm_check_handler_t do_protection_exception; | 51 | extern pgm_check_handler_t do_protection_exception; |
| 58 | extern pgm_check_handler_t do_dat_exception; | 52 | extern pgm_check_handler_t do_dat_exception; |
| @@ -315,18 +309,19 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
| 315 | do_exit(SIGSEGV); | 309 | do_exit(SIGSEGV); |
| 316 | } | 310 | } |
| 317 | 311 | ||
| 318 | static void inline | 312 | static void inline report_user_fault(struct pt_regs *regs, long int_code, |
| 319 | report_user_fault(long interruption_code, struct pt_regs *regs) | 313 | int signr) |
| 320 | { | 314 | { |
| 321 | #if defined(CONFIG_SYSCTL) | 315 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) |
| 322 | if (!sysctl_userprocess_debug) | ||
| 323 | return; | 316 | return; |
| 324 | #endif | 317 | if (!unhandled_signal(current, signr)) |
| 325 | #if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) | 318 | return; |
| 326 | printk("User process fault: interruption code 0x%lX\n", | 319 | if (!printk_ratelimit()) |
| 327 | interruption_code); | 320 | return; |
| 321 | printk("User process fault: interruption code 0x%lX ", int_code); | ||
| 322 | print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); | ||
| 323 | printk("\n"); | ||
| 328 | show_regs(regs); | 324 | show_regs(regs); |
| 329 | #endif | ||
| 330 | } | 325 | } |
| 331 | 326 | ||
| 332 | int is_valid_bugaddr(unsigned long addr) | 327 | int is_valid_bugaddr(unsigned long addr) |
| @@ -354,7 +349,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr, | |||
| 354 | 349 | ||
| 355 | tsk->thread.trap_no = interruption_code & 0xffff; | 350 | tsk->thread.trap_no = interruption_code & 0xffff; |
| 356 | force_sig_info(signr, info, tsk); | 351 | force_sig_info(signr, info, tsk); |
| 357 | report_user_fault(interruption_code, regs); | 352 | report_user_fault(regs, interruption_code, signr); |
| 358 | } else { | 353 | } else { |
| 359 | const struct exception_table_entry *fixup; | 354 | const struct exception_table_entry *fixup; |
| 360 | fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); | 355 | 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) | |||
| 390 | { | 385 | { |
| 391 | if (regs->psw.mask & PSW_MASK_PSTATE) { | 386 | if (regs->psw.mask & PSW_MASK_PSTATE) { |
| 392 | local_irq_enable(); | 387 | local_irq_enable(); |
| 393 | report_user_fault(interruption_code, regs); | 388 | report_user_fault(regs, interruption_code, SIGSEGV); |
| 394 | do_exit(SIGSEGV); | 389 | do_exit(SIGSEGV); |
| 395 | } else | 390 | } else |
| 396 | die("Unknown program exception", regs, interruption_code); | 391 | 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 @@ | |||
| 48 | #define __PF_RES_FIELD 0x8000000000000000ULL | 48 | #define __PF_RES_FIELD 0x8000000000000000ULL |
| 49 | #endif /* CONFIG_64BIT */ | 49 | #endif /* CONFIG_64BIT */ |
| 50 | 50 | ||
| 51 | #ifdef CONFIG_SYSCTL | ||
| 52 | extern int sysctl_userprocess_debug; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #define VM_FAULT_BADCONTEXT 0x010000 | 51 | #define VM_FAULT_BADCONTEXT 0x010000 |
| 56 | #define VM_FAULT_BADMAP 0x020000 | 52 | #define VM_FAULT_BADMAP 0x020000 |
| 57 | #define VM_FAULT_BADACCESS 0x040000 | 53 | #define VM_FAULT_BADACCESS 0x040000 |
| @@ -120,6 +116,22 @@ static inline int user_space_fault(unsigned long trans_exc_code) | |||
| 120 | return trans_exc_code != 3; | 116 | return trans_exc_code != 3; |
| 121 | } | 117 | } |
| 122 | 118 | ||
| 119 | static inline void report_user_fault(struct pt_regs *regs, long int_code, | ||
| 120 | int signr, unsigned long address) | ||
| 121 | { | ||
| 122 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) | ||
| 123 | return; | ||
| 124 | if (!unhandled_signal(current, signr)) | ||
| 125 | return; | ||
| 126 | if (!printk_ratelimit()) | ||
| 127 | return; | ||
| 128 | printk("User process fault: interruption code 0x%lX ", int_code); | ||
| 129 | print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); | ||
| 130 | printk("\n"); | ||
| 131 | printk("failing address: %lX\n", address); | ||
| 132 | show_regs(regs); | ||
| 133 | } | ||
| 134 | |||
| 123 | /* | 135 | /* |
| 124 | * Send SIGSEGV to task. This is an external routine | 136 | * Send SIGSEGV to task. This is an external routine |
| 125 | * to keep the stack usage of do_page_fault small. | 137 | * 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, | |||
| 133 | address = trans_exc_code & __FAIL_ADDR_MASK; | 145 | address = trans_exc_code & __FAIL_ADDR_MASK; |
| 134 | current->thread.prot_addr = address; | 146 | current->thread.prot_addr = address; |
| 135 | current->thread.trap_no = int_code; | 147 | current->thread.trap_no = int_code; |
| 136 | #if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) | 148 | report_user_fault(regs, int_code, SIGSEGV, address); |
| 137 | #if defined(CONFIG_SYSCTL) | ||
| 138 | if (sysctl_userprocess_debug) | ||
| 139 | #endif | ||
| 140 | { | ||
| 141 | printk("User process fault: interruption code 0x%lX\n", | ||
| 142 | int_code); | ||
| 143 | printk("failing address: %lX\n", address); | ||
| 144 | show_regs(regs); | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | si.si_signo = SIGSEGV; | 149 | si.si_signo = SIGSEGV; |
| 148 | si.si_code = si_code; | 150 | si.si_code = si_code; |
| 149 | si.si_addr = (void __user *) address; | 151 | 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[] = { | |||
| 621 | #endif | 621 | #endif |
| 622 | { | 622 | { |
| 623 | .procname = "userprocess_debug", | 623 | .procname = "userprocess_debug", |
| 624 | .data = &sysctl_userprocess_debug, | 624 | .data = &show_unhandled_signals, |
| 625 | .maxlen = sizeof(int), | 625 | .maxlen = sizeof(int), |
| 626 | .mode = 0644, | 626 | .mode = 0644, |
| 627 | .proc_handler = proc_dointvec, | 627 | .proc_handler = proc_dointvec, |
| @@ -1431,7 +1431,8 @@ static struct ctl_table fs_table[] = { | |||
| 1431 | }; | 1431 | }; |
| 1432 | 1432 | ||
| 1433 | static struct ctl_table debug_table[] = { | 1433 | static struct ctl_table debug_table[] = { |
| 1434 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) | 1434 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \ |
| 1435 | defined(CONFIG_S390) | ||
| 1435 | { | 1436 | { |
| 1436 | .procname = "exception-trace", | 1437 | .procname = "exception-trace", |
| 1437 | .data = &show_unhandled_signals, | 1438 | .data = &show_unhandled_signals, |
