aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2015-03-17 05:55:12 -0400
committerWill Deacon <will.deacon@arm.com>2015-03-19 15:46:02 -0400
commitda9c177de88679c2948dc9a5e2325b0dff4677b9 (patch)
tree1ef1c5f3698aea6230899127fb1583ab55faa53c
parent6f4d57fa7021efbf135cfa068d56bc5035edffa1 (diff)
arm64: enforce x1|x2|x3 == 0 upon kernel entry as per boot protocol
According to the arm64 boot protocol, registers x1 to x3 should be zero upon kernel entry, and non-zero values are reserved for future use. This future use is going to be problematic if we never enforce the current rules, so start enforcing them now, by emitting a warning if non-zero values are detected. Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/kernel/head.S19
-rw-r--r--arch/arm64/kernel/setup.c11
2 files changed, 29 insertions, 1 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index f5ac337f9598..1fdf42041f42 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -233,7 +233,7 @@ section_table:
233#endif 233#endif
234 234
235ENTRY(stext) 235ENTRY(stext)
236 mov x21, x0 // x21=FDT 236 bl preserve_boot_args
237 bl el2_setup // Drop to EL1, w20=cpu_boot_mode 237 bl el2_setup // Drop to EL1, w20=cpu_boot_mode
238 adrp x24, __PHYS_OFFSET 238 adrp x24, __PHYS_OFFSET
239 bl set_cpu_boot_mode_flag 239 bl set_cpu_boot_mode_flag
@@ -253,6 +253,23 @@ ENTRY(stext)
253ENDPROC(stext) 253ENDPROC(stext)
254 254
255/* 255/*
256 * Preserve the arguments passed by the bootloader in x0 .. x3
257 */
258preserve_boot_args:
259 mov x21, x0 // x21=FDT
260
261 adr_l x0, boot_args // record the contents of
262 stp x21, x1, [x0] // x0 .. x3 at kernel entry
263 stp x2, x3, [x0, #16]
264
265 dmb sy // needed before dc ivac with
266 // MMU off
267
268 add x1, x0, #0x20 // 4 x 8 bytes
269 b __inval_cache_range // tail call
270ENDPROC(preserve_boot_args)
271
272/*
256 * Determine validity of the x21 FDT pointer. 273 * Determine validity of the x21 FDT pointer.
257 * The dtb must be 8-byte aligned and live in the first 512M of memory. 274 * The dtb must be 8-byte aligned and live in the first 512M of memory.
258 */ 275 */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 1783b38cf4c0..51ef97274b52 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -115,6 +115,11 @@ void __init early_print(const char *str, ...)
115 printk("%s", buf); 115 printk("%s", buf);
116} 116}
117 117
118/*
119 * The recorded values of x0 .. x3 upon kernel entry.
120 */
121u64 __cacheline_aligned boot_args[4];
122
118void __init smp_setup_processor_id(void) 123void __init smp_setup_processor_id(void)
119{ 124{
120 u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; 125 u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
@@ -412,6 +417,12 @@ void __init setup_arch(char **cmdline_p)
412 conswitchp = &dummy_con; 417 conswitchp = &dummy_con;
413#endif 418#endif
414#endif 419#endif
420 if (boot_args[1] || boot_args[2] || boot_args[3]) {
421 pr_err("WARNING: x1-x3 nonzero in violation of boot protocol:\n"
422 "\tx1: %016llx\n\tx2: %016llx\n\tx3: %016llx\n"
423 "This indicates a broken bootloader or old kernel\n",
424 boot_args[1], boot_args[2], boot_args[3]);
425 }
415} 426}
416 427
417static int __init arm64_device_init(void) 428static int __init arm64_device_init(void)