diff options
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r-- | arch/s390/mm/fault.c | 37 |
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 | ||
51 | extern 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 | ||
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 | |||
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; |