aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2014-05-02 11:24:13 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-05-09 12:04:12 -0400
commitd0488597a1b7105957b6d7d1bb0b6ee88aa51b37 (patch)
tree31a9510d904a5df21edb0dd6e7bc58494d2336fb /arch
parentbe6209a6107e0f63544e3e7d00fd5c95434ec80a (diff)
arm64: head: fix cache flushing and barriers in set_cpu_boot_mode_flag
set_cpu_boot_mode_flag is used to identify which exception levels are encountered across the system by CPUs trying to enter the kernel. The basic algorithm is: if a CPU is booting at EL2, it will set a flag at an offset of #4 from __boot_cpu_mode, a cacheline-aligned variable. Otherwise, a flag is set at an offset of zero into the same cacheline. This enables us to check that all CPUs booted at the same exception level. This cacheline is written with the stage-1 MMU off (that is, via a strongly-ordered mapping) and will bypass any clean lines in the cache, leading to potential coherence problems when the variable is later checked via the normal, cacheable mapping of the kernel image. This patch reworks the broken flushing code so that we: (1) Use a DMB to order the strongly-ordered write of the cacheline against the subsequent cache-maintenance operation (by-VA operations only hazard against normal, cacheable accesses). (2) Use a single dc ivac instruction to invalidate any clean lines containing a stale copy of the line after it has been updated. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/kernel/head.S8
1 files changed, 3 insertions, 5 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 0fd565000772..b96a732e4859 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -230,11 +230,9 @@ ENTRY(set_cpu_boot_mode_flag)
230 cmp w20, #BOOT_CPU_MODE_EL2 230 cmp w20, #BOOT_CPU_MODE_EL2
231 b.ne 1f 231 b.ne 1f
232 add x1, x1, #4 232 add x1, x1, #4
2331: dc cvac, x1 // Clean potentially dirty cache line 2331: str w20, [x1] // This CPU has booted in EL1
234 dsb sy 234 dmb sy
235 str w20, [x1] // This CPU has booted in EL1 235 dc ivac, x1 // Invalidate potentially stale cache line
236 dc civac, x1 // Clean&invalidate potentially stale cache line
237 dsb sy
238 ret 236 ret
239ENDPROC(set_cpu_boot_mode_flag) 237ENDPROC(set_cpu_boot_mode_flag)
240 238