summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7/nonsec_virt.S
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-07-12 14:24:00 +0100
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-07-28 17:06:28 +0200
commit64fd44dcae0daafb011f98d4b2d4e1f28036b99e (patch)
tree8248f7a20fe05be8e87dac0987b00841f8b3ce7f /arch/arm/cpu/armv7/nonsec_virt.S
parent800c83522ca6a7d6fd0b058f423501b4cc52d6d6 (diff)
ARM: non-sec: reset CNTVOFF to zero
Before switching to non-secure, make sure that CNTVOFF is set to zero on all CPUs. Otherwise, kernel running in non-secure without HYP enabled (hence using virtual timers) may observe timers that are not synchronized, effectively seeing time going backward... Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>
Diffstat (limited to 'arch/arm/cpu/armv7/nonsec_virt.S')
-rw-r--r--arch/arm/cpu/armv7/nonsec_virt.S9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index 12de5c2d17..b5c946fc4e 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -38,10 +38,10 @@ _secure_monitor:
bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits
orr r1, r1, #0x31 @ enable NS, AW, FW bits
-#ifdef CONFIG_ARMV7_VIRT
mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
+#ifdef CONFIG_ARMV7_VIRT
orreq r1, r1, #0x100 @ allow HVC instruction
#endif
@@ -52,7 +52,14 @@ _secure_monitor:
mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value
mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR
#endif
+ bne 1f
+ @ Reset CNTVOFF to 0 before leaving monitor mode
+ mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
+ ands r0, r0, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits
+ movne r0, #0
+ mcrrne p15, 4, r0, r0, c14 @ Reset CNTVOFF to zero
+1:
movs pc, lr @ return to non-secure SVC
_hyp_trap: