aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2013-07-09 10:16:06 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2013-07-23 06:00:24 -0400
commit82b2f495fba338d1e3098dde1df54944a9c19751 (patch)
tree866012a9d6b7bb010d8ea6fcde80da1954549f52 /arch
parent3b2f64d00c46e1e4e9bd0bb9bb12619adac27a4b (diff)
arm64: virt: ensure visibility of __boot_cpu_mode
Secondary CPUs write to __boot_cpu_mode with caches disabled, and thus a cached value of __boot_cpu_mode may be incoherent with that in memory. This could lead to a failure to detect mismatched boot modes. This patch adds flushing to ensure that writes by secondaries to __boot_cpu_mode are made visible before we test against it. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Christoffer Dall <cdall@cs.columbia.edu> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/include/asm/virt.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 439827271e3d..26e310c54344 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -21,6 +21,7 @@
21#define BOOT_CPU_MODE_EL2 (0x0e12b007) 21#define BOOT_CPU_MODE_EL2 (0x0e12b007)
22 22
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24#include <asm/cacheflush.h>
24 25
25/* 26/*
26 * __boot_cpu_mode records what mode CPUs were booted in. 27 * __boot_cpu_mode records what mode CPUs were booted in.
@@ -36,9 +37,20 @@ extern u32 __boot_cpu_mode[2];
36void __hyp_set_vectors(phys_addr_t phys_vector_base); 37void __hyp_set_vectors(phys_addr_t phys_vector_base);
37phys_addr_t __hyp_get_vectors(void); 38phys_addr_t __hyp_get_vectors(void);
38 39
40static inline void sync_boot_mode(void)
41{
42 /*
43 * As secondaries write to __boot_cpu_mode with caches disabled, we
44 * must flush the corresponding cache entries to ensure the visibility
45 * of their writes.
46 */
47 __flush_dcache_area(__boot_cpu_mode, sizeof(__boot_cpu_mode));
48}
49
39/* Reports the availability of HYP mode */ 50/* Reports the availability of HYP mode */
40static inline bool is_hyp_mode_available(void) 51static inline bool is_hyp_mode_available(void)
41{ 52{
53 sync_boot_mode();
42 return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 && 54 return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 &&
43 __boot_cpu_mode[1] == BOOT_CPU_MODE_EL2); 55 __boot_cpu_mode[1] == BOOT_CPU_MODE_EL2);
44} 56}
@@ -46,6 +58,7 @@ static inline bool is_hyp_mode_available(void)
46/* Check if the bootloader has booted CPUs in different modes */ 58/* Check if the bootloader has booted CPUs in different modes */
47static inline bool is_hyp_mode_mismatched(void) 59static inline bool is_hyp_mode_mismatched(void)
48{ 60{
61 sync_boot_mode();
49 return __boot_cpu_mode[0] != __boot_cpu_mode[1]; 62 return __boot_cpu_mode[0] != __boot_cpu_mode[1];
50} 63}
51 64