forked from Minki/linux
[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>
This commit is contained in:
parent
8209003547
commit
04903a30a3
@ -739,20 +739,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
|
|||||||
extern int do_mathemu(struct pt_regs *regs);
|
extern int do_mathemu(struct pt_regs *regs);
|
||||||
|
|
||||||
/* We can now get here via a FP Unavailable exception if the core
|
/* We can now get here via a FP Unavailable exception if the core
|
||||||
* has no FPU, in that case no reason flags will be set */
|
* has no FPU, in that case the reason flags will be 0 */
|
||||||
#ifdef CONFIG_MATH_EMULATION
|
|
||||||
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
|
|
||||||
* but there seems to be a hardware bug on the 405GP (RevD)
|
|
||||||
* that means ESR is sometimes set incorrectly - either to
|
|
||||||
* ESR_DST (!?) or 0. In the process of chasing this with the
|
|
||||||
* hardware people - not sure if it can happen on any illegal
|
|
||||||
* instruction or only on FP instructions, whether there is a
|
|
||||||
* pattern to occurences etc. -dgibson 31/Mar/2003 */
|
|
||||||
if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
|
|
||||||
emulate_single_step(regs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_MATH_EMULATION */
|
|
||||||
|
|
||||||
if (reason & REASON_FP) {
|
if (reason & REASON_FP) {
|
||||||
/* IEEE FP exception */
|
/* IEEE FP exception */
|
||||||
@ -778,6 +765,20 @@ void __kprobes program_check_exception(struct pt_regs *regs)
|
|||||||
|
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
|
#ifdef CONFIG_MATH_EMULATION
|
||||||
|
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
|
||||||
|
* but there seems to be a hardware bug on the 405GP (RevD)
|
||||||
|
* that means ESR is sometimes set incorrectly - either to
|
||||||
|
* ESR_DST (!?) or 0. In the process of chasing this with the
|
||||||
|
* hardware people - not sure if it can happen on any illegal
|
||||||
|
* instruction or only on FP instructions, whether there is a
|
||||||
|
* pattern to occurences etc. -dgibson 31/Mar/2003 */
|
||||||
|
if (do_mathemu(regs) == 0) {
|
||||||
|
emulate_single_step(regs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MATH_EMULATION */
|
||||||
|
|
||||||
/* Try to emulate it if we should. */
|
/* Try to emulate it if we should. */
|
||||||
if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
|
if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
|
||||||
switch (emulate_instruction(regs)) {
|
switch (emulate_instruction(regs)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user