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

ARM: 7787/1: 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>
Acked-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: Christoffer Dall <cdall@cs.columbia.edu>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Mark Rutland and committed by
Russell King
8fbac214 ab8d46c0

+14
+12
arch/arm/include/asm/virt.h
··· 29 29 #define BOOT_CPU_MODE_MISMATCH PSR_N_BIT 30 30 31 31 #ifndef __ASSEMBLY__ 32 + #include <asm/cacheflush.h> 32 33 33 34 #ifdef CONFIG_ARM_VIRT_EXT 34 35 /* ··· 42 41 */ 43 42 extern int __boot_cpu_mode; 44 43 44 + static inline void sync_boot_mode(void) 45 + { 46 + /* 47 + * As secondaries write to __boot_cpu_mode with caches disabled, we 48 + * must flush the corresponding cache entries to ensure the visibility 49 + * of their writes. 50 + */ 51 + sync_cache_r(&__boot_cpu_mode); 52 + } 53 + 45 54 void __hyp_set_vectors(unsigned long phys_vector_base); 46 55 unsigned long __hyp_get_vectors(void); 47 56 #else 48 57 #define __boot_cpu_mode (SVC_MODE) 58 + #define sync_boot_mode() 49 59 #endif 50 60 51 61 #ifndef ZIMAGE
+2
arch/arm/kernel/setup.c
··· 836 836 void __init hyp_mode_check(void) 837 837 { 838 838 #ifdef CONFIG_ARM_VIRT_EXT 839 + sync_boot_mode(); 840 + 839 841 if (is_hyp_mode_available()) { 840 842 pr_info("CPU: All CPU(s) started in HYP mode.\n"); 841 843 pr_info("CPU: Virtualization extensions available.\n");