diff options
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/fault.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index a742d753d5b0..ac2ad781da00 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -645,24 +645,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
645 | } | 645 | } |
646 | 646 | ||
647 | 647 | ||
648 | #ifdef CONFIG_X86_32 | ||
649 | /* It's safe to allow irq's after cr2 has been saved and the vmalloc | ||
650 | fault has been handled. */ | ||
651 | if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK)) | ||
652 | local_irq_enable(); | ||
653 | |||
654 | /* | 648 | /* |
655 | * If we're in an interrupt, have no user context or are running in an | 649 | * It's safe to allow irq's after cr2 has been saved and the |
656 | * atomic region then we must not take the fault. | 650 | * vmalloc fault has been handled. |
651 | * | ||
652 | * User-mode registers count as a user access even for any | ||
653 | * potential system fault or CPU buglet. | ||
657 | */ | 654 | */ |
658 | if (in_atomic() || !mm) | 655 | if (user_mode_vm(regs)) { |
659 | goto bad_area_nosemaphore; | 656 | local_irq_enable(); |
660 | #else /* CONFIG_X86_64 */ | 657 | error_code |= PF_USER; |
661 | if (likely(regs->flags & X86_EFLAGS_IF)) | 658 | } else if (regs->flags & X86_EFLAGS_IF) |
662 | local_irq_enable(); | 659 | local_irq_enable(); |
663 | 660 | ||
661 | #ifdef CONFIG_X86_64 | ||
664 | if (unlikely(error_code & PF_RSVD)) | 662 | if (unlikely(error_code & PF_RSVD)) |
665 | pgtable_bad(address, regs, error_code); | 663 | pgtable_bad(address, regs, error_code); |
664 | #endif | ||
666 | 665 | ||
667 | /* | 666 | /* |
668 | * If we're in an interrupt, have no user context or are running in an | 667 | * If we're in an interrupt, have no user context or are running in an |
@@ -671,14 +670,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
671 | if (unlikely(in_atomic() || !mm)) | 670 | if (unlikely(in_atomic() || !mm)) |
672 | goto bad_area_nosemaphore; | 671 | goto bad_area_nosemaphore; |
673 | 672 | ||
674 | /* | ||
675 | * User-mode registers count as a user access even for any | ||
676 | * potential system fault or CPU buglet. | ||
677 | */ | ||
678 | if (user_mode_vm(regs)) | ||
679 | error_code |= PF_USER; | ||
680 | again: | 673 | again: |
681 | #endif | ||
682 | /* When running in the kernel we expect faults to occur only to | 674 | /* When running in the kernel we expect faults to occur only to |
683 | * addresses in user space. All other faults represent errors in the | 675 | * addresses in user space. All other faults represent errors in the |
684 | * kernel and should generate an OOPS. Unfortunately, in the case of an | 676 | * kernel and should generate an OOPS. Unfortunately, in the case of an |