Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Fix sampling the "stable" virtual counter in preemptible section

Ben reports that when running with CONFIG_DEBUG_PREEMPT, using
__arch_counter_get_cntvct_stable() results in well deserves warnings,
as we access a per-CPU variable without preemption disabled.

Fix the issue by disabling preemption on reading the counter. We can
probably do a lot better by not disabling preemption on systems that
do not require horrible workarounds to return a valid counter value,
but this plugs the issue for the time being.

Fixes: 29cc0f3aa7c6 ("arm64: Force the use of CNTVCT_EL0 in __delay()")
Reported-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/aZw3EGs4rbQvbAzV@e134344.arm.com
Tested-by: Ben Horgan <ben.horgan@arm.com>
Tested-by: André Draszik <andre.draszik@linaro.org>
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Marc Zyngier and committed by
Will Deacon
e5cb94ba a8f78680

+5 -1
+5 -1
arch/arm64/lib/delay.c
··· 32 32 * Note that userspace cannot change the offset behind our back either, 33 33 * as the vcpu mutex is held as long as KVM_RUN is in progress. 34 34 */ 35 - #define __delay_cycles() __arch_counter_get_cntvct_stable() 35 + static cycles_t notrace __delay_cycles(void) 36 + { 37 + guard(preempt_notrace)(); 38 + return __arch_counter_get_cntvct_stable(); 39 + } 36 40 37 41 void __delay(unsigned long cycles) 38 42 {