Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0587d409 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390/time: return with irqs disabled from psw_idle



Modify the psw_idle waiting logic in entry[64].S to return with
interrupts disabled. This avoids potential issues with udelay
and interrupt loops as interrupts are not reenabled after
clock comparator interrupts.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 6b169ac9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -886,13 +886,13 @@ cleanup_idle:
	stm	%r9,%r10,__LC_SYSTEM_TIMER
	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
	# prepare return psw
	n	%r8,BASED(cleanup_idle_wait)	# clear wait state bit
	n	%r8,BASED(cleanup_idle_wait)	# clear irq & wait state bits
	l	%r9,24(%r11)			# return from psw_idle
	br	%r14
cleanup_idle_insn:
	.long	psw_idle_lpsw + 0x80000000
cleanup_idle_wait:
	.long	0xfffdffff
	.long	0xfcfdffff

/*
 * Integer constants
+1 −1
Original line number Diff line number Diff line
@@ -929,7 +929,7 @@ cleanup_idle:
	stg	%r9,__LC_SYSTEM_TIMER
	mvc	__LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
	# prepare return psw
	nihh	%r8,0xfffd		# clear wait state bit
	nihh	%r8,0xfcfd		# clear irq & wait state bits
	lg	%r9,48(%r11)		# return from psw_idle
	br	%r14
cleanup_idle_insn:
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ void arch_cpu_idle(void)
	}
	/* Halt the cpu and keep track of cpu time accounting. */
	vtime_stop_cpu();
	local_irq_enable();
}

void arch_cpu_idle_exit(void)
+0 −1
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ void clock_comparator_work(void)
	struct clock_event_device *cd;

	S390_lowcore.clock_comparator = -1ULL;
	set_clock_comparator(S390_lowcore.clock_comparator);
	cd = &__get_cpu_var(comparators);
	cd->event_handler(cd);
}
+0 −2
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ static void __udelay_disabled(unsigned long long usecs)
	do {
		set_clock_comparator(end);
		vtime_stop_cpu();
		local_irq_disable();
	} while (get_tod_clock() < end);
	lockdep_on();
	__ctl_load(cr0, 0, 0);
@@ -64,7 +63,6 @@ static void __udelay_enabled(unsigned long long usecs)
			set_clock_comparator(end);
		}
		vtime_stop_cpu();
		local_irq_disable();
		if (clock_saved)
			local_tick_enable(clock_saved);
	} while (get_tod_clock() < end);