powerpc: Convert pmac_pic_lock to raw_spinlock
[safe/jmp/linux-2.6] / arch / powerpc / mm / fault.c
index 17bbf6f..26fb6b9 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/firmware.h>
 #include <asm/page.h>
@@ -40,7 +40,7 @@
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/siginfo.h>
-
+#include <mm/mmu_decl.h>
 
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs *regs)
@@ -171,7 +171,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
                die("Weird page fault", regs, SIGSEGV);
        }
 
-       perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs);
+       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
        /* When running in the kernel we expect faults to occur only to
         * addresses in user space.  All other faults represent errors in the
@@ -246,6 +246,12 @@ good_area:
                goto bad_area;
 #endif /* CONFIG_6xx */
 #if defined(CONFIG_8xx)
+       /* 8xx sometimes need to load a invalid/non-present TLBs.
+        * These must be invalidated separately as linux mm don't.
+        */
+       if (error_code & 0x40000000) /* no translation? */
+               _tlbil_va(address, 0, 0, 0);
+
         /* The MPC8xx seems to always set 0x80000000, which is
          * "undefined".  Of those that can be set, this is the only
          * one which seems bad.
@@ -302,7 +308,7 @@ good_area:
         * the fault.
         */
  survive:
-       ret = handle_mm_fault(mm, vma, address, is_write);
+       ret = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
        if (unlikely(ret & VM_FAULT_ERROR)) {
                if (ret & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -312,7 +318,8 @@ good_area:
        }
        if (ret & VM_FAULT_MAJOR) {
                current->maj_flt++;
-               perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs);
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+                                    regs, address);
 #ifdef CONFIG_PPC_SMLPAR
                if (firmware_has_feature(FW_FEATURE_CMO)) {
                        preempt_disable();
@@ -322,7 +329,8 @@ good_area:
 #endif
        } else {
                current->min_flt++;
-               perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs);
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+                                    regs, address);
        }
        up_read(&mm->mmap_sem);
        return 0;