diff options
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 43eb74fcedde..641da9e868ce 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -229,6 +229,19 @@ notrace void arch_local_irq_restore(unsigned long en) | |||
229 | */ | 229 | */ |
230 | if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) | 230 | if (unlikely(irq_happened != PACA_IRQ_HARD_DIS)) |
231 | __hard_irq_disable(); | 231 | __hard_irq_disable(); |
232 | #ifdef CONFIG_TRACE_IRQFLAG | ||
233 | else { | ||
234 | /* | ||
235 | * We should already be hard disabled here. We had bugs | ||
236 | * where that wasn't the case so let's dbl check it and | ||
237 | * warn if we are wrong. Only do that when IRQ tracing | ||
238 | * is enabled as mfmsr() can be costly. | ||
239 | */ | ||
240 | if (WARN_ON(mfmsr() & MSR_EE)) | ||
241 | __hard_irq_disable(); | ||
242 | } | ||
243 | #endif /* CONFIG_TRACE_IRQFLAG */ | ||
244 | |||
232 | set_soft_enabled(0); | 245 | set_soft_enabled(0); |
233 | 246 | ||
234 | /* | 247 | /* |
@@ -260,11 +273,17 @@ EXPORT_SYMBOL(arch_local_irq_restore); | |||
260 | * if they are currently disabled. This is typically called before | 273 | * if they are currently disabled. This is typically called before |
261 | * schedule() or do_signal() when returning to userspace. We do it | 274 | * schedule() or do_signal() when returning to userspace. We do it |
262 | * in C to avoid the burden of dealing with lockdep etc... | 275 | * in C to avoid the burden of dealing with lockdep etc... |
276 | * | ||
277 | * NOTE: This is called with interrupts hard disabled but not marked | ||
278 | * as such in paca->irq_happened, so we need to resync this. | ||
263 | */ | 279 | */ |
264 | void restore_interrupts(void) | 280 | void restore_interrupts(void) |
265 | { | 281 | { |
266 | if (irqs_disabled()) | 282 | if (irqs_disabled()) { |
283 | local_paca->irq_happened |= PACA_IRQ_HARD_DIS; | ||
267 | local_irq_enable(); | 284 | local_irq_enable(); |
285 | } else | ||
286 | __hard_irq_enable(); | ||
268 | } | 287 | } |
269 | 288 | ||
270 | #endif /* CONFIG_PPC64 */ | 289 | #endif /* CONFIG_PPC64 */ |