]> pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'x86/mm' into x86/core
authorIngo Molnar <mingo@elte.hu>
Fri, 13 Feb 2009 08:47:24 +0000 (09:47 +0100)
committerIngo Molnar <mingo@elte.hu>
Fri, 13 Feb 2009 08:47:24 +0000 (09:47 +0100)
1  2 
arch/x86/mm/fault.c

diff --combined arch/x86/mm/fault.c
index 2a9ea3aee4935b801f1405550592988eefc59236,817a78d5acafb79bb69bdc5161d664adfbb1c7a2..94c4e7262197f0c61659c02993ba109a89837112
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/kprobes.h>
  #include <linux/uaccess.h>
  #include <linux/kdebug.h>
 +#include <linux/magic.h>
  
  #include <asm/system.h>
  #include <asm/desc.h>
@@@ -433,8 -432,6 +433,8 @@@ static noinline void no_context(struct 
                        unsigned long error_code, unsigned long address)
  {
        struct task_struct *tsk = current;
 +      unsigned long *stackend;
 +
  #ifdef CONFIG_X86_64
        unsigned long flags;
        int sig;
  
        show_fault_oops(regs, error_code, address);
  
 +      stackend = end_of_stack(tsk);
 +      if (*stackend != STACK_END_MAGIC)
 +              printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
 +
        tsk->thread.cr2 = address;
        tsk->thread.trap_no = 14;
        tsk->thread.error_code = error_code;
@@@ -782,6 -775,15 +782,15 @@@ static inline int access_error(unsigne
        return 0;
  }
  
+ static int fault_in_kernel_space(unsigned long address)
+ {
+ #ifdef CONFIG_X86_32
+       return address >= TASK_SIZE;
+ #else /* !CONFIG_X86_32 */
+       return address >= TASK_SIZE64;
+ #endif /* CONFIG_X86_32 */
+ }
  /*
   * This routine handles page faults.  It determines the address,
   * and the problem, and then passes it off to one of the appropriate
@@@ -822,11 -824,7 +831,7 @@@ void __kprobes do_page_fault(struct pt_
         * (error_code & 4) == 0, and that the fault was not a
         * protection error (error_code & 9) == 0.
         */
- #ifdef CONFIG_X86_32
-       if (unlikely(address >= TASK_SIZE)) {
- #else
-       if (unlikely(address >= TASK_SIZE64)) {
- #endif
+       if (unlikely(fault_in_kernel_space(address))) {
                if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
                    vmalloc_fault(address) >= 0)
                        return;
                        return;
                }
                down_read(&mm->mmap_sem);
+       } else {
+               /*
+                * The above down_read_trylock() might have succeeded in which
+                * case we'll have missed the might_sleep() from down_read().
+                */
+               might_sleep();
        }
  
        vma = find_vma(mm, address);