aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r--arch/s390/mm/fault.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fc102e70d9c2..2505b2ea0ef1 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -30,6 +30,7 @@
30#include <linux/kprobes.h> 30#include <linux/kprobes.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <linux/hugetlb.h> 32#include <linux/hugetlb.h>
33#include <asm/asm-offsets.h>
33#include <asm/system.h> 34#include <asm/system.h>
34#include <asm/pgtable.h> 35#include <asm/pgtable.h>
35#include <asm/s390_ext.h> 36#include <asm/s390_ext.h>
@@ -47,10 +48,6 @@
47#define __PF_RES_FIELD 0x8000000000000000ULL 48#define __PF_RES_FIELD 0x8000000000000000ULL
48#endif /* CONFIG_64BIT */ 49#endif /* CONFIG_64BIT */
49 50
50#ifdef CONFIG_SYSCTL
51extern int sysctl_userprocess_debug;
52#endif
53
54#define VM_FAULT_BADCONTEXT 0x010000 51#define VM_FAULT_BADCONTEXT 0x010000
55#define VM_FAULT_BADMAP 0x020000 52#define VM_FAULT_BADMAP 0x020000
56#define VM_FAULT_BADACCESS 0x040000 53#define VM_FAULT_BADACCESS 0x040000
@@ -59,15 +56,13 @@ static inline int notify_page_fault(struct pt_regs *regs)
59{ 56{
60 int ret = 0; 57 int ret = 0;
61 58
62#ifdef CONFIG_KPROBES
63 /* kprobe_running() needs smp_processor_id() */ 59 /* kprobe_running() needs smp_processor_id() */
64 if (!user_mode(regs)) { 60 if (kprobes_built_in() && !user_mode(regs)) {
65 preempt_disable(); 61 preempt_disable();
66 if (kprobe_running() && kprobe_fault_handler(regs, 14)) 62 if (kprobe_running() && kprobe_fault_handler(regs, 14))
67 ret = 1; 63 ret = 1;
68 preempt_enable(); 64 preempt_enable();
69 } 65 }
70#endif
71 return ret; 66 return ret;
72} 67}
73 68
@@ -121,6 +116,22 @@ static inline int user_space_fault(unsigned long trans_exc_code)
121 return trans_exc_code != 3; 116 return trans_exc_code != 3;
122} 117}
123 118
119static 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
124/* 135/*
125 * Send SIGSEGV to task. This is an external routine 136 * Send SIGSEGV to task. This is an external routine
126 * to keep the stack usage of do_page_fault small. 137 * to keep the stack usage of do_page_fault small.
@@ -134,17 +145,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
134 address = trans_exc_code & __FAIL_ADDR_MASK; 145 address = trans_exc_code & __FAIL_ADDR_MASK;
135 current->thread.prot_addr = address; 146 current->thread.prot_addr = address;
136 current->thread.trap_no = int_code; 147 current->thread.trap_no = int_code;
137#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) 148 report_user_fault(regs, int_code, SIGSEGV, address);
138#if defined(CONFIG_SYSCTL)
139 if (sysctl_userprocess_debug)
140#endif
141 {
142 printk("User process fault: interruption code 0x%lX\n",
143 int_code);
144 printk("failing address: %lX\n", address);
145 show_regs(regs);
146 }
147#endif
148 si.si_signo = SIGSEGV; 149 si.si_signo = SIGSEGV;
149 si.si_code = si_code; 150 si.si_code = si_code;
150 si.si_addr = (void __user *) address; 151 si.si_addr = (void __user *) address;