Commit 0999d978 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-fixes-for-linus' of...

Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: fix compat-vdso
  x86/mm: unify init task OOM handling
  x86/mm: do not trigger a kernel warning if user-space disables interrupts and generates a page fault
parents 70a3075d f61f1b57
...@@ -640,24 +640,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -640,24 +640,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
} }
#ifdef CONFIG_X86_32
/* It's safe to allow irq's after cr2 has been saved and the vmalloc
fault has been handled. */
if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
local_irq_enable();
/* /*
* If we're in an interrupt, have no user context or are running in an * It's safe to allow irq's after cr2 has been saved and the
* atomic region then we must not take the fault. * vmalloc fault has been handled.
*
* User-mode registers count as a user access even for any
* potential system fault or CPU buglet.
*/ */
if (in_atomic() || !mm) if (user_mode_vm(regs)) {
goto bad_area_nosemaphore; local_irq_enable();
#else /* CONFIG_X86_64 */ error_code |= PF_USER;
if (likely(regs->flags & X86_EFLAGS_IF)) } else if (regs->flags & X86_EFLAGS_IF)
local_irq_enable(); local_irq_enable();
#ifdef CONFIG_X86_64
if (unlikely(error_code & PF_RSVD)) if (unlikely(error_code & PF_RSVD))
pgtable_bad(address, regs, error_code); pgtable_bad(address, regs, error_code);
#endif
/* /*
* If we're in an interrupt, have no user context or are running in an * If we're in an interrupt, have no user context or are running in an
...@@ -666,15 +665,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -666,15 +665,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (unlikely(in_atomic() || !mm)) if (unlikely(in_atomic() || !mm))
goto bad_area_nosemaphore; goto bad_area_nosemaphore;
/*
* User-mode registers count as a user access even for any
* potential system fault or CPU buglet.
*/
if (user_mode_vm(regs))
error_code |= PF_USER;
again: again:
#endif /*
/* When running in the kernel we expect faults to occur only to * When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the * addresses in user space. All other faults represent errors in the
* kernel and should generate an OOPS. Unfortunately, in the case of an * kernel and should generate an OOPS. Unfortunately, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem * erroneous fault occurring in a code path which already holds mmap_sem
...@@ -737,9 +730,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -737,9 +730,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
goto bad_area; goto bad_area;
} }
#ifdef CONFIG_X86_32
survive:
#endif
/* /*
* If for any reason at all we couldn't handle the fault, * If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo * make sure we exit gracefully rather than endlessly redo
...@@ -874,12 +864,11 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -874,12 +864,11 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
if (is_global_init(tsk)) { if (is_global_init(tsk)) {
yield(); yield();
#ifdef CONFIG_X86_32 /*
down_read(&mm->mmap_sem); * Re-lookup the vma - in theory the vma tree might
goto survive; * have changed:
#else */
goto again; goto again;
#endif
} }
printk("VM: killing process %s\n", tsk->comm); printk("VM: killing process %s\n", tsk->comm);
......
...@@ -148,8 +148,13 @@ ...@@ -148,8 +148,13 @@
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC #define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
#else #else
/*
* For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
* bits are combined, this will alow user to access the high address mapped
* VDSO in the presence of CONFIG_COMPAT_VDSO
*/
#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */ #define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */ #define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment