diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-03-07 00:48:45 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-03-08 18:55:08 -0500 |
commit | a546498f3bf9aac311c66f965186373aee2ca0b0 (patch) | |
tree | 86fb9a778aba26df3810acd8e52a921a2d84489b /arch | |
parent | 1b70117924a4f254840ed70fbe3020d4519a1a9a (diff) |
powerpc: Call do_page_fault() with interrupts off
We currently turn interrupts back to their previous state before
calling do_page_fault(). This can be annoying when debugging as
a bad fault will potentially have lost some processor state before
getting into the debugger.
We also end up calling some generic code with interrupts enabled
such as notify_page_fault() with interrupts enabled, which could
be unexpected.
This changes our code to behave more like other architectures,
and make the assembly entry code call into do_page_faults() with
interrupts disabled. They are conditionally re-enabled from
within do_page_fault() in the same spot x86 does it.
While there, add the might_sleep() test in the case of a successful
trylock of the mmap semaphore, again like x86.
Also fix a bug in the existing assembly where r12 (_MSR) could get
clobbered by C calls (the DTL accounting in the exception common
macro and DISABLE_INTS) in some cases.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
v2. Add the r12 clobber fix
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/hw_irq.h | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 59 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_32.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_40x.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_8xx.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_booke.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 2 | ||||
-rw-r--r-- | arch/powerpc/mm/fault.c | 11 |
9 files changed, 49 insertions, 54 deletions
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index bb712c9488b3..531ba00fcbab 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h | |||
@@ -79,6 +79,11 @@ static inline bool arch_irqs_disabled(void) | |||
79 | get_paca()->hard_enabled = 0; \ | 79 | get_paca()->hard_enabled = 0; \ |
80 | } while(0) | 80 | } while(0) |
81 | 81 | ||
82 | static inline bool arch_irq_disabled_regs(struct pt_regs *regs) | ||
83 | { | ||
84 | return !regs->softe; | ||
85 | } | ||
86 | |||
82 | #else /* CONFIG_PPC64 */ | 87 | #else /* CONFIG_PPC64 */ |
83 | 88 | ||
84 | #define SET_MSR_EE(x) mtmsr(x) | 89 | #define SET_MSR_EE(x) mtmsr(x) |
@@ -139,6 +144,11 @@ static inline bool arch_irqs_disabled(void) | |||
139 | 144 | ||
140 | #define hard_irq_disable() arch_local_irq_disable() | 145 | #define hard_irq_disable() arch_local_irq_disable() |
141 | 146 | ||
147 | static inline bool arch_irq_disabled_regs(struct pt_regs *regs) | ||
148 | { | ||
149 | return !(regs->msr & MSR_EE); | ||
150 | } | ||
151 | |||
142 | #endif /* CONFIG_PPC64 */ | 152 | #endif /* CONFIG_PPC64 */ |
143 | 153 | ||
144 | #define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST | 154 | #define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 429983c06f91..573613d747ac 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -313,7 +313,7 @@ interrupt_end_book3e: | |||
313 | NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS) | 313 | NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS) |
314 | mfspr r14,SPRN_DEAR | 314 | mfspr r14,SPRN_DEAR |
315 | mfspr r15,SPRN_ESR | 315 | mfspr r15,SPRN_ESR |
316 | EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_KEEP) | 316 | EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_DISABLE_ALL) |
317 | b storage_fault_common | 317 | b storage_fault_common |
318 | 318 | ||
319 | /* Instruction Storage Interrupt */ | 319 | /* Instruction Storage Interrupt */ |
@@ -321,7 +321,7 @@ interrupt_end_book3e: | |||
321 | NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS) | 321 | NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS) |
322 | li r15,0 | 322 | li r15,0 |
323 | mr r14,r10 | 323 | mr r14,r10 |
324 | EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_KEEP) | 324 | EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_DISABLE_ALL) |
325 | b storage_fault_common | 325 | b storage_fault_common |
326 | 326 | ||
327 | /* External Input Interrupt */ | 327 | /* External Input Interrupt */ |
@@ -591,7 +591,6 @@ storage_fault_common: | |||
591 | mr r5,r15 | 591 | mr r5,r15 |
592 | ld r14,PACA_EXGEN+EX_R14(r13) | 592 | ld r14,PACA_EXGEN+EX_R14(r13) |
593 | ld r15,PACA_EXGEN+EX_R15(r13) | 593 | ld r15,PACA_EXGEN+EX_R15(r13) |
594 | INTS_RESTORE_HARD | ||
595 | bl .do_page_fault | 594 | bl .do_page_fault |
596 | cmpdi r3,0 | 595 | cmpdi r3,0 |
597 | bne- 1f | 596 | bne- 1f |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3af80e82830b..d8ff6d37fc4d 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -559,6 +559,8 @@ data_access_common: | |||
559 | mfspr r10,SPRN_DSISR | 559 | mfspr r10,SPRN_DSISR |
560 | stw r10,PACA_EXGEN+EX_DSISR(r13) | 560 | stw r10,PACA_EXGEN+EX_DSISR(r13) |
561 | EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) | 561 | EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) |
562 | DISABLE_INTS | ||
563 | ld r12,_MSR(r1) | ||
562 | ld r3,PACA_EXGEN+EX_DAR(r13) | 564 | ld r3,PACA_EXGEN+EX_DAR(r13) |
563 | lwz r4,PACA_EXGEN+EX_DSISR(r13) | 565 | lwz r4,PACA_EXGEN+EX_DSISR(r13) |
564 | li r5,0x300 | 566 | li r5,0x300 |
@@ -573,6 +575,7 @@ h_data_storage_common: | |||
573 | stw r10,PACA_EXGEN+EX_DSISR(r13) | 575 | stw r10,PACA_EXGEN+EX_DSISR(r13) |
574 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) | 576 | EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) |
575 | bl .save_nvgprs | 577 | bl .save_nvgprs |
578 | DISABLE_INTS | ||
576 | addi r3,r1,STACK_FRAME_OVERHEAD | 579 | addi r3,r1,STACK_FRAME_OVERHEAD |
577 | bl .unknown_exception | 580 | bl .unknown_exception |
578 | b .ret_from_except | 581 | b .ret_from_except |
@@ -581,6 +584,8 @@ h_data_storage_common: | |||
581 | .globl instruction_access_common | 584 | .globl instruction_access_common |
582 | instruction_access_common: | 585 | instruction_access_common: |
583 | EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) | 586 | EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) |
587 | DISABLE_INTS | ||
588 | ld r12,_MSR(r1) | ||
584 | ld r3,_NIP(r1) | 589 | ld r3,_NIP(r1) |
585 | andis. r4,r12,0x5820 | 590 | andis. r4,r12,0x5820 |
586 | li r5,0x400 | 591 | li r5,0x400 |
@@ -884,24 +889,6 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) | |||
884 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ | 889 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ |
885 | andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ | 890 | andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ |
886 | bne 77f /* then don't call hash_page now */ | 891 | bne 77f /* then don't call hash_page now */ |
887 | |||
888 | /* We run with interrupts both soft and hard disabled */ | ||
889 | DISABLE_INTS | ||
890 | |||
891 | /* | ||
892 | * Currently, trace_hardirqs_off() will be called by DISABLE_INTS | ||
893 | * and will clobber volatile registers when irq tracing is enabled | ||
894 | * so we need to reload them. It may be possible to be smarter here | ||
895 | * and move the irq tracing elsewhere but let's keep it simple for | ||
896 | * now | ||
897 | */ | ||
898 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
899 | ld r3,_DAR(r1) | ||
900 | ld r4,_DSISR(r1) | ||
901 | ld r5,_TRAP(r1) | ||
902 | ld r12,_MSR(r1) | ||
903 | clrrdi r5,r5,4 | ||
904 | #endif /* CONFIG_TRACE_IRQFLAGS */ | ||
905 | /* | 892 | /* |
906 | * We need to set the _PAGE_USER bit if MSR_PR is set or if we are | 893 | * We need to set the _PAGE_USER bit if MSR_PR is set or if we are |
907 | * accessing a userspace segment (even from the kernel). We assume | 894 | * accessing a userspace segment (even from the kernel). We assume |
@@ -931,36 +918,16 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB) | |||
931 | beq fast_exc_return_irq /* Return from exception on success */ | 918 | beq fast_exc_return_irq /* Return from exception on success */ |
932 | 919 | ||
933 | /* For a hash failure, we don't bother re-enabling interrupts */ | 920 | /* For a hash failure, we don't bother re-enabling interrupts */ |
934 | ble- 12f | 921 | ble- 13f |
935 | |||
936 | /* | ||
937 | * hash_page couldn't handle it, set soft interrupt enable back | ||
938 | * to what it was before the trap. Note that .arch_local_irq_restore | ||
939 | * handles any interrupts pending at this point. | ||
940 | */ | ||
941 | ld r3,SOFTE(r1) | ||
942 | TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f) | ||
943 | bl .arch_local_irq_restore | ||
944 | b 11f | ||
945 | |||
946 | /* We have a data breakpoint exception - handle it */ | ||
947 | handle_dabr_fault: | ||
948 | bl .save_nvgprs | ||
949 | ld r4,_DAR(r1) | ||
950 | ld r5,_DSISR(r1) | ||
951 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
952 | bl .do_dabr | ||
953 | b .ret_from_except_lite | ||
954 | 922 | ||
955 | /* Here we have a page fault that hash_page can't handle. */ | 923 | /* Here we have a page fault that hash_page can't handle. */ |
956 | handle_page_fault: | 924 | handle_page_fault: |
957 | ENABLE_INTS | ||
958 | 11: ld r4,_DAR(r1) | 925 | 11: ld r4,_DAR(r1) |
959 | ld r5,_DSISR(r1) | 926 | ld r5,_DSISR(r1) |
960 | addi r3,r1,STACK_FRAME_OVERHEAD | 927 | addi r3,r1,STACK_FRAME_OVERHEAD |
961 | bl .do_page_fault | 928 | bl .do_page_fault |
962 | cmpdi r3,0 | 929 | cmpdi r3,0 |
963 | beq+ 13f | 930 | beq+ 12f |
964 | bl .save_nvgprs | 931 | bl .save_nvgprs |
965 | mr r5,r3 | 932 | mr r5,r3 |
966 | addi r3,r1,STACK_FRAME_OVERHEAD | 933 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -968,12 +935,20 @@ handle_page_fault: | |||
968 | bl .bad_page_fault | 935 | bl .bad_page_fault |
969 | b .ret_from_except | 936 | b .ret_from_except |
970 | 937 | ||
971 | 13: b .ret_from_except_lite | 938 | /* We have a data breakpoint exception - handle it */ |
939 | handle_dabr_fault: | ||
940 | bl .save_nvgprs | ||
941 | ld r4,_DAR(r1) | ||
942 | ld r5,_DSISR(r1) | ||
943 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
944 | bl .do_dabr | ||
945 | 12: b .ret_from_except_lite | ||
946 | |||
972 | 947 | ||
973 | /* We have a page fault that hash_page could handle but HV refused | 948 | /* We have a page fault that hash_page could handle but HV refused |
974 | * the PTE insertion | 949 | * the PTE insertion |
975 | */ | 950 | */ |
976 | 12: bl .save_nvgprs | 951 | 13: bl .save_nvgprs |
977 | mr r5,r3 | 952 | mr r5,r3 |
978 | addi r3,r1,STACK_FRAME_OVERHEAD | 953 | addi r3,r1,STACK_FRAME_OVERHEAD |
979 | ld r4,_DAR(r1) | 954 | ld r4,_DAR(r1) |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 0654dba2c1f1..dc0488b6f6e1 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -395,7 +395,7 @@ DataAccess: | |||
395 | bl hash_page | 395 | bl hash_page |
396 | 1: lwz r5,_DSISR(r11) /* get DSISR value */ | 396 | 1: lwz r5,_DSISR(r11) /* get DSISR value */ |
397 | mfspr r4,SPRN_DAR | 397 | mfspr r4,SPRN_DAR |
398 | EXC_XFER_EE_LITE(0x300, handle_page_fault) | 398 | EXC_XFER_LITE(0x300, handle_page_fault) |
399 | 399 | ||
400 | 400 | ||
401 | /* Instruction access exception. */ | 401 | /* Instruction access exception. */ |
@@ -410,7 +410,7 @@ InstructionAccess: | |||
410 | bl hash_page | 410 | bl hash_page |
411 | 1: mr r4,r12 | 411 | 1: mr r4,r12 |
412 | mr r5,r9 | 412 | mr r5,r9 |
413 | EXC_XFER_EE_LITE(0x400, handle_page_fault) | 413 | EXC_XFER_LITE(0x400, handle_page_fault) |
414 | 414 | ||
415 | /* External interrupt */ | 415 | /* External interrupt */ |
416 | EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) | 416 | EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) |
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index 872a6af83bad..4989661b710b 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S | |||
@@ -394,7 +394,7 @@ label: | |||
394 | NORMAL_EXCEPTION_PROLOG | 394 | NORMAL_EXCEPTION_PROLOG |
395 | mr r4,r12 /* Pass SRR0 as arg2 */ | 395 | mr r4,r12 /* Pass SRR0 as arg2 */ |
396 | li r5,0 /* Pass zero as arg3 */ | 396 | li r5,0 /* Pass zero as arg3 */ |
397 | EXC_XFER_EE_LITE(0x400, handle_page_fault) | 397 | EXC_XFER_LITE(0x400, handle_page_fault) |
398 | 398 | ||
399 | /* 0x0500 - External Interrupt Exception */ | 399 | /* 0x0500 - External Interrupt Exception */ |
400 | EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) | 400 | EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) |
@@ -747,7 +747,7 @@ DataAccess: | |||
747 | mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ | 747 | mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ |
748 | stw r5,_ESR(r11) | 748 | stw r5,_ESR(r11) |
749 | mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ | 749 | mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ |
750 | EXC_XFER_EE_LITE(0x300, handle_page_fault) | 750 | EXC_XFER_LITE(0x300, handle_page_fault) |
751 | 751 | ||
752 | /* Other PowerPC processors, namely those derived from the 6xx-series | 752 | /* Other PowerPC processors, namely those derived from the 6xx-series |
753 | * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. | 753 | * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. |
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index b68cb173ba2c..b2a5860accfb 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -220,7 +220,7 @@ DataAccess: | |||
220 | mfspr r4,SPRN_DAR | 220 | mfspr r4,SPRN_DAR |
221 | li r10,0x00f0 | 221 | li r10,0x00f0 |
222 | mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ | 222 | mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */ |
223 | EXC_XFER_EE_LITE(0x300, handle_page_fault) | 223 | EXC_XFER_LITE(0x300, handle_page_fault) |
224 | 224 | ||
225 | /* Instruction access exception. | 225 | /* Instruction access exception. |
226 | * This is "never generated" by the MPC8xx. We jump to it for other | 226 | * This is "never generated" by the MPC8xx. We jump to it for other |
@@ -231,7 +231,7 @@ InstructionAccess: | |||
231 | EXCEPTION_PROLOG | 231 | EXCEPTION_PROLOG |
232 | mr r4,r12 | 232 | mr r4,r12 |
233 | mr r5,r9 | 233 | mr r5,r9 |
234 | EXC_XFER_EE_LITE(0x400, handle_page_fault) | 234 | EXC_XFER_LITE(0x400, handle_page_fault) |
235 | 235 | ||
236 | /* External interrupt */ | 236 | /* External interrupt */ |
237 | EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) | 237 | EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) |
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index fc921bf62e15..0e4175388f47 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h | |||
@@ -359,7 +359,7 @@ label: | |||
359 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ | 359 | mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ |
360 | stw r5,_ESR(r11); \ | 360 | stw r5,_ESR(r11); \ |
361 | mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ | 361 | mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ |
362 | EXC_XFER_EE_LITE(0x0300, handle_page_fault) | 362 | EXC_XFER_LITE(0x0300, handle_page_fault) |
363 | 363 | ||
364 | #define INSTRUCTION_STORAGE_EXCEPTION \ | 364 | #define INSTRUCTION_STORAGE_EXCEPTION \ |
365 | START_EXCEPTION(InstructionStorage) \ | 365 | START_EXCEPTION(InstructionStorage) \ |
@@ -368,7 +368,7 @@ label: | |||
368 | stw r5,_ESR(r11); \ | 368 | stw r5,_ESR(r11); \ |
369 | mr r4,r12; /* Pass SRR0 as arg2 */ \ | 369 | mr r4,r12; /* Pass SRR0 as arg2 */ \ |
370 | li r5,0; /* Pass zero as arg3 */ \ | 370 | li r5,0; /* Pass zero as arg3 */ \ |
371 | EXC_XFER_EE_LITE(0x0400, handle_page_fault) | 371 | EXC_XFER_LITE(0x0400, handle_page_fault) |
372 | 372 | ||
373 | #define ALIGNMENT_EXCEPTION \ | 373 | #define ALIGNMENT_EXCEPTION \ |
374 | START_EXCEPTION(Alignment) \ | 374 | START_EXCEPTION(Alignment) \ |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index d5d78c4ceef6..28e62598d0e8 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -319,7 +319,7 @@ interrupt_base: | |||
319 | mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ | 319 | mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ |
320 | andis. r10,r5,(ESR_ILK|ESR_DLK)@h | 320 | andis. r10,r5,(ESR_ILK|ESR_DLK)@h |
321 | bne 1f | 321 | bne 1f |
322 | EXC_XFER_EE_LITE(0x0300, handle_page_fault) | 322 | EXC_XFER_LITE(0x0300, handle_page_fault) |
323 | 1: | 323 | 1: |
324 | addi r3,r1,STACK_FRAME_OVERHEAD | 324 | addi r3,r1,STACK_FRAME_OVERHEAD |
325 | EXC_XFER_EE_LITE(0x0300, CacheLockingException) | 325 | EXC_XFER_EE_LITE(0x0300, CacheLockingException) |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 2f0d1b032a89..7e890065cf39 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -179,6 +179,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
179 | } | 179 | } |
180 | #endif | 180 | #endif |
181 | 181 | ||
182 | /* We restore the interrupt state now */ | ||
183 | if (!arch_irq_disabled_regs(regs)) | ||
184 | local_irq_enable(); | ||
185 | |||
182 | if (in_atomic() || mm == NULL) { | 186 | if (in_atomic() || mm == NULL) { |
183 | if (!user_mode(regs)) | 187 | if (!user_mode(regs)) |
184 | return SIGSEGV; | 188 | return SIGSEGV; |
@@ -213,6 +217,13 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
213 | goto bad_area_nosemaphore; | 217 | goto bad_area_nosemaphore; |
214 | 218 | ||
215 | down_read(&mm->mmap_sem); | 219 | down_read(&mm->mmap_sem); |
220 | } else { | ||
221 | /* | ||
222 | * The above down_read_trylock() might have succeeded in | ||
223 | * which case we'll have missed the might_sleep() from | ||
224 | * down_read(): | ||
225 | */ | ||
226 | might_sleep(); | ||
216 | } | 227 | } |
217 | 228 | ||
218 | vma = find_vma(mm, address); | 229 | vma = find_vma(mm, address); |