]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: Add an isb() before reading CNTPCT_EL0 to prevent re-ordering
authorJulien Grall <julien.grall@arm.com>
Mon, 29 Apr 2019 14:05:16 +0000 (15:05 +0100)
committerJulien Grall <julien.grall@arm.com>
Fri, 14 Jun 2019 13:38:40 +0000 (14:38 +0100)
Per D8.2.1 in ARM DDI 0487C.a, "a read to CNTPCT_EL0 can occur
speculatively and out of order relative to other instructions executed
on the same PE."

Add an instruction barrier to get accurate number of cycles when
requested in get_cycles(). For the other users of CNPCT_EL0, replace by
a call to get_cycles().

This is part of XSA-295.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/time.c
xen/include/asm-arm/time.h

index c11fcfeadd0af714d0dccc7ad9ee3227b9656836..a15b4a0dc7b526745257998ef2fe9e9c593cfa78 100644 (file)
@@ -149,7 +149,7 @@ void __init preinit_xen_time(void)
     if ( res )
         panic("Timer: Cannot initialize platform timer");
 
-    boot_count = READ_SYSREG64(CNTPCT_EL0);
+    boot_count = get_cycles();
 }
 
 static void __init init_dt_xen_time(void)
@@ -190,7 +190,7 @@ int __init init_xen_time(void)
 /* Return number of nanoseconds since boot */
 s_time_t get_s_time(void)
 {
-    uint64_t ticks = READ_SYSREG64(CNTPCT_EL0) - boot_count;
+    uint64_t ticks = get_cycles() - boot_count;
     return ticks_to_ns(ticks);
 }
 
index 5b9a31de91ea039b56c999e727eaf382230f0f25..ca30406669e33f92d5b965851d73275643a6710b 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __ARM_TIME_H__
 #define __ARM_TIME_H__
 
+#include <asm/system.h>
+
 #define DT_MATCH_TIMER                      \
     DT_MATCH_COMPATIBLE("arm,armv7-timer"), \
     DT_MATCH_COMPATIBLE("arm,armv8-timer")
@@ -9,7 +11,8 @@ typedef unsigned long cycles_t;
 
 static inline cycles_t get_cycles (void)
 {
-        return 0;
+        isb();
+        return READ_SYSREG64(CNTPCT_EL0);
 }
 
 /* List of timer's IRQ */