X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=arch%2Fx86_64%2Fmm%2Ffault.c;h=2074bddd4f04eea21a6dd9d6a8b848bf95a22be2;hb=021daae2c265a844fd27bb6cc49c2bd114571069;hp=de99dba2c515503f716501aafd9f0eab57ed0142;hpb=2d56d3c43cc97ae48586745556f5a5b564d61582;p=powerpc.git diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index de99dba2c5..2074bddd4f 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -15,22 +15,22 @@ #include #include #include -#include #include #include #include #include /* For unblank_screen() */ #include +#include #include #include #include +#include #include #include #include #include #include -#include #include /* Page fault error code bits */ @@ -301,7 +301,7 @@ static int vmalloc_fault(unsigned long address) return 0; } -int page_fault_trace = 0; +static int page_fault_trace; int exception_trace = 1; /* @@ -317,7 +317,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, struct vm_area_struct * vma; unsigned long address; const struct exception_table_entry *fixup; - int write; + int write, fault; unsigned long flags; siginfo_t info; @@ -450,19 +450,18 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ - switch (handle_mm_fault(mm, vma, address, write)) { - case VM_FAULT_MINOR: - tsk->min_flt++; - break; - case VM_FAULT_MAJOR: - tsk->maj_flt++; - break; - case VM_FAULT_SIGBUS: - goto do_sigbus; - default: - goto out_of_memory; + fault = handle_mm_fault(mm, vma, address, write); + if (unlikely(fault & VM_FAULT_ERROR)) { + if (fault & VM_FAULT_OOM) + goto out_of_memory; + else if (fault & VM_FAULT_SIGBUS) + goto do_sigbus; + BUG(); } - + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; up_read(&mm->mmap_sem); return; @@ -476,6 +475,12 @@ bad_area: bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (error_code & PF_USER) { + + /* + * It's possible to have interrupts off here. + */ + local_irq_enable(); + if (is_prefetch(regs, address, error_code)) return; @@ -563,7 +568,7 @@ out_of_memory: } printk("VM: killing process %s\n", tsk->comm); if (error_code & 4) - do_exit(SIGKILL); + do_group_exit(SIGKILL); goto no_context; do_sigbus: