Skip to content

Commit 75aa996

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390: Revert "s390/irq/idle: Remove psw bits early"
This reverts commit d8b5cf9. Mikhail Zaslonko reported that linux-next doesn't boot anymore [2]. Reason for this is recent change [2] was supposed to slightly optimize the irq entry/exit path by removing some psw bits early in case of an idle exit. This however is incorrect since irqentry_exit() requires the correct old psw state at irq entry. Otherwise the embedded regs_irqs_disabled() will not provide the correct result. With linux-next and HRTIMER_REARM_DEFERRED this leads to the observed boot problems, however the commit is broken in any case. Revert the commit which introduced this. Thanks to Peter Zijlstra for pointing out that this is a bug in the s390 entry code. Fixes: d8b5cf9 ("s390/irq/idle: Remove psw bits early") [1] Reported-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Reported-by: Peter Zijlstra <peterz@infradead.org> Closes: https://lore.kernel.org/r/af549a19-db99-4b16-8511-bf315177a13e@linux.ibm.com/ [2] Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Acked-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Tested-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Acked-by: Vasily Gorbik <gor@linux.ibm.com> Link: https://lore.kernel.org/r/20260306111919.362559-1-hca@linux.ibm.com Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 674c5ff commit 75aa996

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

arch/s390/kernel/irq.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,8 @@ void noinstr do_io_irq(struct pt_regs *regs)
147147
bool from_idle;
148148

149149
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
150-
if (from_idle) {
150+
if (from_idle)
151151
update_timer_idle();
152-
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
153-
}
154152

155153
irq_enter_rcu();
156154

@@ -176,6 +174,9 @@ void noinstr do_io_irq(struct pt_regs *regs)
176174

177175
set_irq_regs(old_regs);
178176
irqentry_exit(regs, state);
177+
178+
if (from_idle)
179+
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
179180
}
180181

181182
void noinstr do_ext_irq(struct pt_regs *regs)
@@ -185,10 +186,8 @@ void noinstr do_ext_irq(struct pt_regs *regs)
185186
bool from_idle;
186187

187188
from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT);
188-
if (from_idle) {
189+
if (from_idle)
189190
update_timer_idle();
190-
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
191-
}
192191

193192
irq_enter_rcu();
194193

@@ -210,6 +209,9 @@ void noinstr do_ext_irq(struct pt_regs *regs)
210209
irq_exit_rcu();
211210
set_irq_regs(old_regs);
212211
irqentry_exit(regs, state);
212+
213+
if (from_idle)
214+
regs->psw.mask &= ~(PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_WAIT);
213215
}
214216

215217
static void show_msi_interrupt(struct seq_file *p, int irq)

0 commit comments

Comments
 (0)