]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/s390/mm/fault.c
Merge branch 'reiserfs-updates' from Jeff Mahoney
[linux-2.6-omap-h63xx.git] / arch / s390 / mm / fault.c
index ed13d429a487d01c4cf927b6d7cfc4a7e519faf9..833e8366c351d08238466e21f660c66dc47e0845 100644 (file)
 #include <linux/hardirq.h>
 #include <linux/kprobes.h>
 #include <linux/uaccess.h>
-
+#include <linux/hugetlb.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/s390_ext.h>
 #include <asm/mmu_context.h>
+#include "../kernel/entry.h"
 
 #ifndef CONFIG_64BIT
 #define __FAIL_ADDR_MASK 0x7ffff000
@@ -50,8 +51,6 @@
 extern int sysctl_userprocess_debug;
 #endif
 
-extern void die(const char *,struct pt_regs *,long);
-
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs *regs, long err)
 {
@@ -201,29 +200,6 @@ static void do_low_address(struct pt_regs *regs, unsigned long error_code)
        do_no_context(regs, error_code, 0);
 }
 
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
-                           unsigned long address)
-{
-       struct task_struct *tsk = current;
-       struct mm_struct *mm = tsk->mm;
-
-       up_read(&mm->mmap_sem);
-       if (is_global_init(tsk)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               return 1;
-       }
-       printk("VM: killing process %s\n", tsk->comm);
-       if (regs->psw.mask & PSW_MASK_PSTATE)
-               do_group_exit(SIGKILL);
-       do_no_context(regs, error_code, address);
-       return 0;
-}
-
 static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
                      unsigned long address)
 {
@@ -245,11 +221,6 @@ static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
 }
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-extern long sys_sigreturn(struct pt_regs *regs);
-extern long sys_rt_sigreturn(struct pt_regs *regs);
-extern long sys32_sigreturn(struct pt_regs *regs);
-extern long sys32_rt_sigreturn(struct pt_regs *regs);
-
 static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
                         unsigned long address, unsigned long error_code)
 {
@@ -270,15 +241,15 @@ static int signal_return(struct mm_struct *mm, struct pt_regs *regs,
 #ifdef CONFIG_COMPAT
        compat = test_tsk_thread_flag(current, TIF_31BIT);
        if (compat && instruction == 0x0a77)
-               sys32_sigreturn(regs);
+               sys32_sigreturn();
        else if (compat && instruction == 0x0aad)
-               sys32_rt_sigreturn(regs);
+               sys32_rt_sigreturn();
        else
 #endif
        if (instruction == 0x0a77)
-               sys_sigreturn(regs);
+               sys_sigreturn();
        else if (instruction == 0x0aad)
-               sys_rt_sigreturn(regs);
+               sys_rt_sigreturn();
        else {
                current->thread.prot_addr = address;
                current->thread.trap_no = error_code;
@@ -373,7 +344,8 @@ good_area:
                        goto bad_area;
        }
 
-survive:
+       if (is_vm_hugetlb_page(vma))
+               address &= HPAGE_MASK;
        /*
         * If for any reason at all we couldn't handle the fault,
         * make sure we exit gracefully rather than endlessly redo
@@ -382,8 +354,8 @@ survive:
        fault = handle_mm_fault(mm, vma, address, write);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM) {
-                       if (do_out_of_memory(regs, error_code, address))
-                               goto survive;
+                       up_read(&mm->mmap_sem);
+                       pagefault_out_of_memory();
                        return;
                } else if (fault & VM_FAULT_SIGBUS) {
                        do_sigbus(regs, error_code, address);
@@ -424,7 +396,7 @@ no_context:
 }
 
 void __kprobes do_protection_exception(struct pt_regs *regs,
-                                      unsigned long error_code)
+                                      long error_code)
 {
        /* Protection exception is supressing, decrement psw address. */
        regs->psw.addr -= (error_code >> 16);
@@ -440,7 +412,7 @@ void __kprobes do_protection_exception(struct pt_regs *regs,
        do_exception(regs, 4, 1);
 }
 
-void __kprobes do_dat_exception(struct pt_regs *regs, unsigned long error_code)
+void __kprobes do_dat_exception(struct pt_regs *regs, long error_code)
 {
        do_exception(regs, error_code & 0xff, 0);
 }