aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/traps.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2007-02-07 02:13:32 -0500
committerKumar Gala <galak@kernel.crashing.org>2007-02-07 02:13:32 -0500
commit04903a30a327513b97c1271fc6bc4dad6502d1b8 (patch)
tree9761b3fbe0606102ee47d5fed12a50b9c9931280 /arch/powerpc/kernel/traps.c
parent8209003547c4b1006943eac8dc6c1fb6493cafda (diff)
[POWERPC] Enable interrupts if we are doing fp math emulation
Anytime we are emulating an instruction we are going to be doing some form of get_user() to get the instruction image to decode. Since get_user() might sleep we need to ensure we have interrupts enabled or we might see something like: Debug: sleeping function called from invalid context at arch/powerpc/kernel/traps.c:697 in_atomic():0, irqs_disabled():1 Call Trace: [D6023EB0] [C0007F84] show_stack+0x58/0x174 (unreliable) [D6023EE0] [C0022C34] __might_sleep+0xbc/0xd0 [D6023EF0] [C000D158] program_check_exception+0x1d8/0x4fc [D6023F40] [C000E744] ret_from_except_full+0x0/0x4c --- Exception: 700 at 0x102a7100 LR = 0xdb9ef04 However, we want to ensure that interrupts are disabled when handling a trap exception that might be used for a kernel breakpoint. This is why ProgramCheck is marked as EXC_XFER_STD instead of EXC_XFER_EE. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r--arch/powerpc/kernel/traps.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6915b91868b8..f038caa3c2b9 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -739,20 +739,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
739 extern int do_mathemu(struct pt_regs *regs); 739 extern int do_mathemu(struct pt_regs *regs);
740 740
741 /* We can now get here via a FP Unavailable exception if the core 741 /* We can now get here via a FP Unavailable exception if the core
742 * has no FPU, in that case no reason flags will be set */ 742 * has no FPU, in that case the reason flags will be 0 */
743#ifdef CONFIG_MATH_EMULATION
744 /* (reason & REASON_ILLEGAL) would be the obvious thing here,
745 * but there seems to be a hardware bug on the 405GP (RevD)
746 * that means ESR is sometimes set incorrectly - either to
747 * ESR_DST (!?) or 0. In the process of chasing this with the
748 * hardware people - not sure if it can happen on any illegal
749 * instruction or only on FP instructions, whether there is a
750 * pattern to occurences etc. -dgibson 31/Mar/2003 */
751 if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
752 emulate_single_step(regs);
753 return;
754 }
755#endif /* CONFIG_MATH_EMULATION */
756 743
757 if (reason & REASON_FP) { 744 if (reason & REASON_FP) {
758 /* IEEE FP exception */ 745 /* IEEE FP exception */
@@ -778,6 +765,20 @@ void __kprobes program_check_exception(struct pt_regs *regs)
778 765
779 local_irq_enable(); 766 local_irq_enable();
780 767
768#ifdef CONFIG_MATH_EMULATION
769 /* (reason & REASON_ILLEGAL) would be the obvious thing here,
770 * but there seems to be a hardware bug on the 405GP (RevD)
771 * that means ESR is sometimes set incorrectly - either to
772 * ESR_DST (!?) or 0. In the process of chasing this with the
773 * hardware people - not sure if it can happen on any illegal
774 * instruction or only on FP instructions, whether there is a
775 * pattern to occurences etc. -dgibson 31/Mar/2003 */
776 if (do_mathemu(regs) == 0) {
777 emulate_single_step(regs);
778 return;
779 }
780#endif /* CONFIG_MATH_EMULATION */
781
781 /* Try to emulate it if we should. */ 782 /* Try to emulate it if we should. */
782 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { 783 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
783 switch (emulate_instruction(regs)) { 784 switch (emulate_instruction(regs)) {