diff options
Diffstat (limited to 'arch/sparc/mm/fault_64.c')
| -rw-r--r-- | arch/sparc/mm/fault_64.c | 37 |
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 | 35 | static inline __kprobes int notify_page_fault(struct pt_regs *regs) |
| 35 | static 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 | ||
| 49 | static inline int notify_page_fault(struct pt_regs *regs) | ||
| 50 | { | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | #endif | ||
| 54 | 48 | ||
| 55 | static void __kprobes unhandled_fault(unsigned long address, | 49 | static 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 | ||
| 76 | static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr) | 70 | static 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 | ||
| 173 | static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, | 167 | static 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 | ||
| 228 | static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) | 223 | static 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 | ||
| 240 | static void noinline bogus_32bit_fault_address(struct pt_regs *regs, | 235 | static 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); |
