Context |
Check |
Description |
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/merge (c6624071c338732402e8c726df6a4074473eaa0e)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/next (7074695ac6fb965d478f373b95bc5c636e9f21b0)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch linus/master (9420e8ade4353a6710908ffafa23ecaf1caa0123)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch powerpc/fixes (1d0c32ec3b860a32df593a22bad0d1dbc5546a59)
|
snowpatch_ozlabs/apply_patch |
warning
|
Failed to apply on branch linux-next (89295c59c1f063b533d071ca49d0fa0c0783ca6f)
|
snowpatch_ozlabs/apply_patch |
fail
|
Failed to apply to any branch
|
@@ -342,11 +342,15 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign
trace_hardirqs_off();
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
/*
- * Can't local_irq_enable in case we are in interrupt
- * context. Must replay directly.
+ * Can't local_irq_restore to replay if we were in
+ * interrupt context. Must replay directly.
*/
- replay_soft_interrupts();
- irq_soft_mask_set(flags);
+ if (irqs_disabled_flags(flags)) {
+ replay_soft_interrupts();
+ } else {
+ local_irq_restore(flags);
+ local_irq_save(flags);
+ }
/* Took an interrupt, may have more exit work to do. */
goto again;
}
The return-to-kernel path has to replay any soft-pending interrupts if it is returning to a context that had interrupts soft-enabled. It has to do this carefully and avoid plain enabling interrupts if this is an irq context, which can cause multiple nesting of interrupts on the stack, and other unexpected issues. The code which avoided this case got the soft-mask state wrong, and marked interrupts as enabled before going around again to retry. This seems to be mostly harmless except when PREEMPT=y, this calls preempt_schedule_irq with irqs apparently enabled and runs into a BUG in kernel/sched/core.c Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- arch/powerpc/kernel/syscall_64.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)