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
This commit is contained in:
@@ -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)
|
|||||||
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 @@ good_area:
|
|||||||
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 @@ out_of_memory:
|
|||||||
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 @@
|
|||||||
#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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user