diff options
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bdf2dd141598..77a7581dcb1c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -1151,6 +1151,16 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1151 | } | 1151 | } |
1152 | #endif | 1152 | #endif |
1153 | 1153 | ||
1154 | /* | ||
1155 | * If we took the program check in the kernel skip down to sending a | ||
1156 | * SIGILL. The subsequent cases all relate to emulating instructions | ||
1157 | * which we should only do for userspace. We also do not want to enable | ||
1158 | * interrupts for kernel faults because that might lead to further | ||
1159 | * faults, and loose the context of the original exception. | ||
1160 | */ | ||
1161 | if (!user_mode(regs)) | ||
1162 | goto sigill; | ||
1163 | |||
1154 | /* We restore the interrupt state now */ | 1164 | /* We restore the interrupt state now */ |
1155 | if (!arch_irq_disabled_regs(regs)) | 1165 | if (!arch_irq_disabled_regs(regs)) |
1156 | local_irq_enable(); | 1166 | local_irq_enable(); |
@@ -1179,6 +1189,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1179 | } | 1189 | } |
1180 | } | 1190 | } |
1181 | 1191 | ||
1192 | sigill: | ||
1182 | if (reason & REASON_PRIVILEGED) | 1193 | if (reason & REASON_PRIVILEGED) |
1183 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); | 1194 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); |
1184 | else | 1195 | else |