Commit c9b12b59 authored by Sven Schnelle's avatar Sven Schnelle Committed by Heiko Carstens
Browse files

s390/entry: fix duplicate tracking of irq nesting level



In the current code, when exiting from idle, rcu_irq_enter() is
called twice during irq entry:

irq_entry_enter()-> rcu_irq_enter()
irq_enter() -> rcu_irq_enter()

This may lead to wrong results from rcu_is_cpu_rrupt_from_idle()
because of a wrong dynticks nmi nesting count. Fix this by only
calling irq_enter_rcu().

Cc: <stable@vger.kernel.org> # 5.12+
Reported-by: default avatarMark Rutland <mark.rutland@arm.com>
Fixes: 56e62a73 ("s390: convert to generic entry")
Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 5dcf0c30
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ void noinstr do_io_irq(struct pt_regs *regs)
	struct pt_regs *old_regs = set_irq_regs(regs);
	int from_idle;

	irq_enter();
	irq_enter_rcu();

	if (user_mode(regs)) {
		update_timer_sys();
@@ -158,7 +158,8 @@ void noinstr do_io_irq(struct pt_regs *regs)
			do_irq_async(regs, IO_INTERRUPT);
	} while (MACHINE_IS_LPAR && irq_pending(regs));

	irq_exit();
	irq_exit_rcu();

	set_irq_regs(old_regs);
	irqentry_exit(regs, state);

@@ -172,7 +173,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)
	struct pt_regs *old_regs = set_irq_regs(regs);
	int from_idle;

	irq_enter();
	irq_enter_rcu();

	if (user_mode(regs)) {
		update_timer_sys();
@@ -190,7 +191,7 @@ void noinstr do_ext_irq(struct pt_regs *regs)

	do_irq_async(regs, EXT_INTERRUPT);

	irq_exit();
	irq_exit_rcu();
	set_irq_regs(old_regs);
	irqentry_exit(regs, state);