aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/fault_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/fault_64.c')
-rw-r--r--arch/sparc/mm/fault_64.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 43b0da96a4fb..b9d4ff02b8fc 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -16,6 +16,7 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/perf_event.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/kprobes.h> 21#include <linux/kprobes.h>
21#include <linux/kdebug.h> 22#include <linux/kdebug.h>
@@ -31,13 +32,12 @@
31#include <asm/sections.h> 32#include <asm/sections.h>
32#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
33 34
34#ifdef CONFIG_KPROBES 35static inline __kprobes int notify_page_fault(struct pt_regs *regs)
35static inline int notify_page_fault(struct pt_regs *regs)
36{ 36{
37 int ret = 0; 37 int ret = 0;
38 38
39 /* kprobe_running() needs smp_processor_id() */ 39 /* kprobe_running() needs smp_processor_id() */
40 if (!user_mode(regs)) { 40 if (kprobes_built_in() && !user_mode(regs)) {
41 preempt_disable(); 41 preempt_disable();
42 if (kprobe_running() && kprobe_fault_handler(regs, 0)) 42 if (kprobe_running() && kprobe_fault_handler(regs, 0))
43 ret = 1; 43 ret = 1;
@@ -45,12 +45,6 @@ static inline int notify_page_fault(struct pt_regs *regs)
45 } 45 }
46 return ret; 46 return ret;
47} 47}
48#else
49static inline int notify_page_fault(struct pt_regs *regs)
50{
51 return 0;
52}
53#endif
54 48
55static void __kprobes unhandled_fault(unsigned long address, 49static void __kprobes unhandled_fault(unsigned long address,
56 struct task_struct *tsk, 50 struct task_struct *tsk,
@@ -73,7 +67,7 @@ static void __kprobes unhandled_fault(unsigned long address,
73 die_if_kernel("Oops", regs); 67 die_if_kernel("Oops", regs);
74} 68}
75 69
76static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) 70static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
77{ 71{
78 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", 72 printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
79 regs->tpc); 73 regs->tpc);
@@ -170,8 +164,9 @@ static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
170 return insn; 164 return insn;
171} 165}
172 166
173static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, 167static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
174 unsigned int insn, unsigned long address) 168 int fault_code, unsigned int insn,
169 unsigned long address)
175{ 170{
176 unsigned char asi = ASI_P; 171 unsigned char asi = ASI_P;
177 172
@@ -225,7 +220,7 @@ cannot_handle:
225 unhandled_fault (address, current, regs); 220 unhandled_fault (address, current, regs);
226} 221}
227 222
228static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) 223static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
229{ 224{
230 static int times; 225 static int times;
231 226
@@ -237,8 +232,8 @@ static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs)
237 show_regs(regs); 232 show_regs(regs);
238} 233}
239 234
240static void noinline bogus_32bit_fault_address(struct pt_regs *regs, 235static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
241 unsigned long addr) 236 unsigned long addr)
242{ 237{
243 static int times; 238 static int times;
244 239
@@ -302,6 +297,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
302 if (in_atomic() || !mm) 297 if (in_atomic() || !mm)
303 goto intr_or_no_mm; 298 goto intr_or_no_mm;
304 299
300 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
301
305 if (!down_read_trylock(&mm->mmap_sem)) { 302 if (!down_read_trylock(&mm->mmap_sem)) {
306 if ((regs->tstate & TSTATE_PRIV) && 303 if ((regs->tstate & TSTATE_PRIV) &&
307 !search_exception_tables(regs->tpc)) { 304 !search_exception_tables(regs->tpc)) {
@@ -406,11 +403,15 @@ good_area:
406 goto do_sigbus; 403 goto do_sigbus;
407 BUG(); 404 BUG();
408 } 405 }
409 if (fault & VM_FAULT_MAJOR) 406 if (fault & VM_FAULT_MAJOR) {
410 current->maj_flt++; 407 current->maj_flt++;
411 else 408 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
409 regs, address);
410 } else {
412 current->min_flt++; 411 current->min_flt++;
413 412 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
413 regs, address);
414 }
414 up_read(&mm->mmap_sem); 415 up_read(&mm->mmap_sem);
415 416
416 mm_rss = get_mm_rss(mm); 417 mm_rss = get_mm_rss(mm);