* [PATCH 0/8] arm64: 2016 head.S spring cleaning
@ 2016-04-04 14:52 Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
After having been responsible for obfuscating the head.S code in the v4.6
cycle to implement KASLR support, this series attempts to make amends by
performing some janitorial duties as well.
The main point of this series is to get rid of the file scoped callee saved
registers in head.S to store the FDT pointer, ID map and swapper dir addresses,
KASLR offset, PHYS offset etc. The fact that these are file scoped makes it
unnecessarily complicated to reason about lifetimes etc, especially since the
code is called by both the boot CPU and secondaries.
Since some of these functions are called without a stack, we still need to use
callee saved registers to preserve values across function calls without
stacking/unstacking the previous values, but these instances are now function
scoped, not file scoped, and documented.
Patch #1 gets rid of the confusing subtraction of address and offset values to
obtain __secondary_switched.
Patch #2 gets rid of x21 in head.S
Patch #3 creates moves the stack pointer init to an earlier time in
__mmap_switched, and creates a proper stack frame.
Patch #4 changes the EL2 detection code to simply use x0 as a return value and
first argument.
Patch #5 gets rid of x25 and x26 to store idmap_pg_dir and swapper_pg_dir
Patch #6 gets rid of x27 to store __mmap_switched or __secondary_switched
Patch #7 gets rid of x24 to store PHYS_OFFSET
Patch #8 gets rid of x23 to store the kaslr offset
@Maintainers: feel free to cherry pick if not all [or none] of these patches
make sense to you
Ard Biesheuvel (8):
arm64/kernel: use literal for relocated address of
__secondary_switched
arm64/kernel: reuse boot_args array to get to __fdt_pointer
arm64/kernel: use a proper stack frame in __mmap_switched()
arm64/kernel: use ordinary calling convention for EL2 setup
arm64/kernel: refer to idmap_pg_dir and swapper_pg_dir directly
arm64/kernel: pass virtual entry point as __enable_mmu() argument
arm64/kernel: drop __PHYS_OFFSET register with file scope from head.S
arm64/kernel: drop global kaslr_offset in x23 from head.S
arch/arm64/kernel/head.S | 177 +++++++++++---------
arch/arm64/kernel/setup.c | 4 +-
2 files changed, 95 insertions(+), 86 deletions(-)
--
2.5.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-07 9:38 ` Will Deacon
2016-04-04 14:52 ` [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer Ard Biesheuvel
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
We can simply use a relocated 64-bit literal to store the address of
__secondary_switched(), and the relocation code will ensure that it
holds the correct value at secondary entry time, as long as we make sure
that the literal value is visible to the secondaries before they enable
their MMUs. So place the literal next to kimage_vaddr, and set the alignment
so that it is covered by the same cacheline that we already have to clean
for a similar purpose.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 4203d5f257bc..69b33535911e 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -471,7 +471,8 @@ __mmap_switched:
b 0b
2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
- dc cvac, x8 // value visible to secondaries
+ // and __secondary_switched
+ dc cvac, x8 // values visible to secondaries
dsb sy // with MMU off
#endif
@@ -506,10 +507,12 @@ ENDPROC(__mmap_switched)
* end early head section, begin head code that is also used for
* hotplug and needs to have the same protections as the text region
*/
- .section ".text","ax"
-
+ .section ".text","ax"
+ .align 4
ENTRY(kimage_vaddr)
.quad _text - TEXT_OFFSET
+.L__secondary_switched:
+ .quad __secondary_switched
/*
* If we're fortunate enough to boot at EL2, ensure that the world is
@@ -701,12 +704,9 @@ ENTRY(secondary_startup)
adrp x26, swapper_pg_dir
bl __cpu_setup // initialise processor
- ldr x8, kimage_vaddr
- ldr w9, 0f
- sub x27, x8, w9, sxtw // address to jump to after enabling the MMU
+ ldr x27, .L__secondary_switched
b __enable_mmu
ENDPROC(secondary_startup)
-0: .long (_text - TEXT_OFFSET) - __secondary_switched
ENTRY(__secondary_switched)
adr_l x5, vectors
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 15:13 ` James Morse
2016-04-04 14:52 ` [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched() Ard Biesheuvel
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Since we record the boot_args [x0 .. x3] early at boot anyway, there is
no need to keep the FDT address in a callee saved register with file scope
in head.S. So simply refer to boot_args[0] directly in the call to
setup_machine(), and drop the handling of x21 from head.S entirely.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 14 ++++++--------
arch/arm64/kernel/setup.c | 4 +---
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 69b33535911e..9d8f928c355c 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -234,16 +234,15 @@ ENDPROC(stext)
* Preserve the arguments passed by the bootloader in x0 .. x3
*/
preserve_boot_args:
- mov x21, x0 // x21=FDT
-
- adr_l x0, boot_args // record the contents of
- stp x21, x1, [x0] // x0 .. x3 at kernel entry
- stp x2, x3, [x0, #16]
+ adr_l x4, boot_args // record the contents of
+ stp x0, x1, [x4] // x0 .. x3 at kernel entry
+ stp x2, x3, [x4, #16]
dmb sy // needed before dc ivac with
// MMU off
- add x1, x0, #0x20 // 4 x 8 bytes
+ mov x0, x4
+ add x1, x4, #0x20 // 4 x 8 bytes
b __inval_cache_range // tail call
ENDPROC(preserve_boot_args)
@@ -480,7 +479,6 @@ __mmap_switched:
mov x4, sp
and x4, x4, #~(THREAD_SIZE - 1)
msr sp_el0, x4 // Save thread_info
- str_l x21, __fdt_pointer, x5 // Save FDT pointer
ldr_l x4, kimage_vaddr // Save the offset between
sub x4, x4, x24 // the kernel virtual and
@@ -492,7 +490,7 @@ __mmap_switched:
#endif
#ifdef CONFIG_RANDOMIZE_BASE
cbnz x23, 0f // already running randomized?
- mov x0, x21 // pass FDT address in x0
+ ldr_l x0, boot_args // pass FDT address in x0
bl kaslr_early_init // parse FDT for KASLR options
cbz x0, 0f // KASLR disabled? just proceed
mov x23, x0 // record KASLR offset
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 9dc67769b6a4..83a3e484a90a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -64,8 +64,6 @@
#include <asm/xen/hypervisor.h>
#include <asm/mmu_context.h>
-phys_addr_t __fdt_pointer __initdata;
-
/*
* Standard memory resources
*/
@@ -304,7 +302,7 @@ void __init setup_arch(char **cmdline_p)
early_fixmap_init();
early_ioremap_init();
- setup_machine_fdt(__fdt_pointer);
+ setup_machine_fdt(boot_args[0]);
parse_early_param();
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched()
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 15:33 ` James Morse
2016-04-04 14:52 ` [PATCH 4/8] arm64/kernel: use ordinary calling convention for EL2 setup Ard Biesheuvel
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Considering that we can expect stack accesses from the moment we assign
VBAR_EL1, let's initialize the stack pointer first in __mmap_switched(),
and set up a proper stack frame while we're at it.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 9d8f928c355c..f441fc73a7a2 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -421,9 +421,14 @@ kernel_img_size:
/*
* The following fragment of code is executed with the MMU enabled.
*/
- .set initial_sp, init_thread_union + THREAD_START_SP
__mmap_switched:
- mov x28, lr // preserve LR
+ adrp x4, init_thread_union
+ add sp, x4, #THREAD_SIZE
+ msr sp_el0, x4 // Save thread_info
+
+ stp xzr, x30, [sp, #-16]!
+ mov x29, sp
+
adr_l x8, vectors // load VBAR_EL1 with virtual
msr vbar_el1, x8 // vector table address
isb
@@ -475,16 +480,9 @@ __mmap_switched:
dsb sy // with MMU off
#endif
- adr_l sp, initial_sp, x4
- mov x4, sp
- and x4, x4, #~(THREAD_SIZE - 1)
- msr sp_el0, x4 // Save thread_info
-
ldr_l x4, kimage_vaddr // Save the offset between
sub x4, x4, x24 // the kernel virtual and
str_l x4, kimage_voffset, x5 // physical mappings
-
- mov x29, #0
#ifdef CONFIG_KASAN
bl kasan_early_init
#endif
@@ -494,8 +492,8 @@ __mmap_switched:
bl kaslr_early_init // parse FDT for KASLR options
cbz x0, 0f // KASLR disabled? just proceed
mov x23, x0 // record KASLR offset
- ret x28 // we must enable KASLR, return
- // to __enable_mmu()
+ ldp x29, x30, [sp], #16 // we must enable KASLR, return
+ ret // to __enable_mmu()
0:
#endif
b start_kernel
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/8] arm64/kernel: use ordinary calling convention for EL2 setup
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
` (2 preceding siblings ...)
2016-04-04 14:52 ` [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched() Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 5/8] arm64/kernel: refer to idmap_pg_dir and swapper_pg_dir directly Ard Biesheuvel
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Since the return value of el2_setup() is almost immediately passed to
set_cpu_boot_mode_flag() in all cases, there is no need to use a callee
saved register w20, but we can use simply use w0 instead.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index f441fc73a7a2..2a1b3ba1d81c 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -211,7 +211,7 @@ section_table:
ENTRY(stext)
bl preserve_boot_args
- bl el2_setup // Drop to EL1, w20=cpu_boot_mode
+ bl el2_setup // Drop to EL1, w0=cpu_boot_mode
mov x23, xzr // KASLR offset, defaults to 0
adrp x24, __PHYS_OFFSET
bl set_cpu_boot_mode_flag
@@ -530,7 +530,7 @@ CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2
CPU_BE( orr x0, x0, #(3 << 24) ) // Set the EE and E0E bits for EL1
CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1
msr sctlr_el1, x0
- mov w20, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
+ mov w0, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
isb
ret
@@ -616,7 +616,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
cbz x2, install_el2_stub
- mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
+ mov w0, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
isb
ret
@@ -631,20 +631,20 @@ install_el2_stub:
PSR_MODE_EL1h)
msr spsr_el2, x0
msr elr_el2, lr
- mov w20, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
+ mov w0, #BOOT_CPU_MODE_EL2 // This CPU booted in EL2
eret
ENDPROC(el2_setup)
/*
* Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
- * in x20. See arch/arm64/include/asm/virt.h for more info.
+ * in x0. See arch/arm64/include/asm/virt.h for more info.
*/
ENTRY(set_cpu_boot_mode_flag)
adr_l x1, __boot_cpu_mode
- cmp w20, #BOOT_CPU_MODE_EL2
+ cmp w0, #BOOT_CPU_MODE_EL2
b.ne 1f
add x1, x1, #4
-1: str w20, [x1] // This CPU has booted in EL1
+1: str w0, [x1] // This CPU has booted in EL1
dmb sy
dc ivac, x1 // Invalidate potentially stale cache line
ret
@@ -669,7 +669,7 @@ ENTRY(__boot_cpu_mode)
* cores are held until we're ready for them to initialise.
*/
ENTRY(secondary_holding_pen)
- bl el2_setup // Drop to EL1, w20=cpu_boot_mode
+ bl el2_setup // Drop to EL1, w0=cpu_boot_mode
bl set_cpu_boot_mode_flag
mrs x0, mpidr_el1
ldr x1, =MPIDR_HWID_BITMASK
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/8] arm64/kernel: refer to idmap_pg_dir and swapper_pg_dir directly
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
` (3 preceding siblings ...)
2016-04-04 14:52 ` [PATCH 4/8] arm64/kernel: use ordinary calling convention for EL2 setup Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 6/8] arm64/kernel: pass virtual entry point as __enable_mmu() argument Ard Biesheuvel
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Instead of keeping their addresses in globals in x25 and x26 in head.S,
just refer to idmap_pg_dir or swapper_pg_dir directly using adrp
instructions when needed. This reduces the number of callee saved register
with file scope, which should increase maintainability.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 28 +++++++++-----------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 2a1b3ba1d81c..9201cddb53bc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -215,7 +215,7 @@ ENTRY(stext)
mov x23, xzr // KASLR offset, defaults to 0
adrp x24, __PHYS_OFFSET
bl set_cpu_boot_mode_flag
- bl __create_page_tables // x25=TTBR0, x26=TTBR1
+ bl __create_page_tables
/*
* The following calls CPU setup code, see arch/arm64/mm/proc.S for
* details.
@@ -313,23 +313,21 @@ ENDPROC(preserve_boot_args)
* been enabled
*/
__create_page_tables:
- adrp x25, idmap_pg_dir
- adrp x26, swapper_pg_dir
mov x28, lr
/*
* Invalidate the idmap and swapper page tables to avoid potential
* dirty cache lines being evicted.
*/
- mov x0, x25
- add x1, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE
bl __inval_cache_range
/*
* Clear the idmap and swapper page tables.
*/
- mov x0, x25
- add x6, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x6, swapper_pg_dir + SWAPPER_DIR_SIZE
1: stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
stp xzr, xzr, [x0], #16
@@ -342,7 +340,7 @@ __create_page_tables:
/*
* Create the identity mapping.
*/
- mov x0, x25 // idmap_pg_dir
+ adrp x0, idmap_pg_dir
adrp x3, __idmap_text_start // __pa(__idmap_text_start)
#ifndef CONFIG_ARM64_VA_BITS_48
@@ -392,7 +390,7 @@ __create_page_tables:
/*
* Map the kernel image (starting with PHYS_OFFSET).
*/
- mov x0, x26 // swapper_pg_dir
+ adrp x0, swapper_pg_dir
ldr x5, =KIMAGE_VADDR
add x5, x5, x23 // add KASLR displacement
create_pgd_entry x0, x5, x3, x6
@@ -406,8 +404,8 @@ __create_page_tables:
* accesses (MMU disabled), invalidate the idmap and swapper page
* tables again to remove any speculatively loaded cache lines.
*/
- mov x0, x25
- add x1, x26, #SWAPPER_DIR_SIZE
+ adrp x0, idmap_pg_dir
+ adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE
dmb sy
bl __inval_cache_range
@@ -696,8 +694,6 @@ ENTRY(secondary_startup)
/*
* Common entry point for secondary CPUs.
*/
- adrp x25, idmap_pg_dir
- adrp x26, swapper_pg_dir
bl __cpu_setup // initialise processor
ldr x27, .L__secondary_switched
@@ -760,8 +756,10 @@ __enable_mmu:
cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
b.ne __no_granule_support
update_early_cpu_boot_status 0, x1, x2
- msr ttbr0_el1, x25 // load TTBR0
- msr ttbr1_el1, x26 // load TTBR1
+ adrp x4, idmap_pg_dir
+ adrp x5, swapper_pg_dir
+ msr ttbr0_el1, x4 // load TTBR0
+ msr ttbr1_el1, x5 // load TTBR1
isb
msr sctlr_el1, x0
isb
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/8] arm64/kernel: pass virtual entry point as __enable_mmu() argument
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
` (4 preceding siblings ...)
2016-04-04 14:52 ` [PATCH 5/8] arm64/kernel: refer to idmap_pg_dir and swapper_pg_dir directly Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 7/8] arm64/kernel: drop __PHYS_OFFSET register with file scope from head.S Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 8/8] arm64/kernel: drop global kaslr_offset in x23 " Ard Biesheuvel
7 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Instead of keeping the virtual entry point to be invoked by __enable_mmu
in a callee saved register with file scope, simply pass it as the second
argument. This makes the code easier to maintain.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 27 ++++++++++----------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 9201cddb53bc..d28fc345bec3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -222,10 +222,10 @@ ENTRY(stext)
* On return, the CPU will be ready for the MMU to be turned on and
* the TCR will have been set.
*/
- ldr x27, 0f // address to jump to after
+ bl __cpu_setup // initialise processor
+ ldr x1, 0f // address to jump to after
// MMU has been enabled
- adr_l lr, __enable_mmu // return (PIC) address
- b __cpu_setup // initialise processor
+ b __enable_mmu
ENDPROC(stext)
.align 3
0: .quad __mmap_switched - (_head - TEXT_OFFSET) + KIMAGE_VADDR
@@ -696,7 +696,7 @@ ENTRY(secondary_startup)
*/
bl __cpu_setup // initialise processor
- ldr x27, .L__secondary_switched
+ ldr x1, .L__secondary_switched
b __enable_mmu
ENDPROC(secondary_startup)
@@ -741,7 +741,7 @@ ENTRY(__early_cpu_boot_status)
* Enable the MMU.
*
* x0 = SCTLR_EL1 value for turning on the MMU.
- * x27 = *virtual* address to jump to upon completion
+ * x1 = *virtual* address to jump to upon completion
*
* Other registers depend on the function called upon completion.
*
@@ -751,11 +751,11 @@ ENTRY(__early_cpu_boot_status)
.section ".idmap.text", "ax"
__enable_mmu:
mrs x22, sctlr_el1 // preserve old SCTLR_EL1 value
- mrs x1, ID_AA64MMFR0_EL1
- ubfx x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4
- cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
+ mrs x2, ID_AA64MMFR0_EL1
+ ubfx x3, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4
+ cmp x3, #ID_AA64MMFR0_TGRAN_SUPPORTED
b.ne __no_granule_support
- update_early_cpu_boot_status 0, x1, x2
+ update_early_cpu_boot_status 0, x2, x3
adrp x4, idmap_pg_dir
adrp x5, swapper_pg_dir
msr ttbr0_el1, x4 // load TTBR0
@@ -771,9 +771,10 @@ __enable_mmu:
ic iallu
dsb nsh
isb
+ mov x20, x1 // preserve branch target
#ifdef CONFIG_RANDOMIZE_BASE
mov x19, x0 // preserve new SCTLR_EL1 value
- blr x27
+ blr x1
/*
* If we return here, we have a KASLR displacement in x23 which we need
@@ -789,14 +790,14 @@ __enable_mmu:
ic iallu // flush instructions fetched
dsb nsh // via old mapping
isb
- add x27, x27, x23 // relocated __mmap_switched
+ add x20, x20, x23 // relocated __mmap_switched
#endif
- br x27
+ br x20
ENDPROC(__enable_mmu)
__no_granule_support:
/* Indicate that this CPU can't boot and is stuck in the kernel */
- update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x1, x2
+ update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x2, x3
1:
wfe
wfi
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/8] arm64/kernel: drop __PHYS_OFFSET register with file scope from head.S
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
` (5 preceding siblings ...)
2016-04-04 14:52 ` [PATCH 6/8] arm64/kernel: pass virtual entry point as __enable_mmu() argument Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 8/8] arm64/kernel: drop global kaslr_offset in x23 " Ard Biesheuvel
7 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Instead of keeping __PHYS_OFFSET in a callee saved register with file
scope in head.S, derive the value on demand. This makes for cleaner
and more maintainable code.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 26 +++++++++++---------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index d28fc345bec3..23d03da7ecfe 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -213,7 +213,6 @@ ENTRY(stext)
bl preserve_boot_args
bl el2_setup // Drop to EL1, w0=cpu_boot_mode
mov x23, xzr // KASLR offset, defaults to 0
- adrp x24, __PHYS_OFFSET
bl set_cpu_boot_mode_flag
bl __create_page_tables
/*
@@ -396,7 +395,7 @@ __create_page_tables:
create_pgd_entry x0, x5, x3, x6
ldr w6, kernel_img_size
add x6, x6, x5
- mov x3, x24 // phys offset
+ adrp x3, __PHYS_OFFSET
create_block_map x0, x7, x3, x5, x6
/*
@@ -417,7 +416,7 @@ kernel_img_size:
.ltorg
/*
- * The following fragment of code is executed with the MMU enabled.
+ * __mmap_switched(u64 phys_offset) - virtual entry point for the boot CPU
*/
__mmap_switched:
adrp x4, init_thread_union
@@ -431,14 +430,6 @@ __mmap_switched:
msr vbar_el1, x8 // vector table address
isb
- // Clear BSS
- adr_l x0, __bss_start
- mov x1, xzr
- adr_l x2, __bss_stop
- sub x2, x2, x0
- bl __pi_memset
- dsb ishst // Make zero page visible to PTW
-
#ifdef CONFIG_RELOCATABLE
/*
@@ -479,8 +470,17 @@ __mmap_switched:
#endif
ldr_l x4, kimage_vaddr // Save the offset between
- sub x4, x4, x24 // the kernel virtual and
+ sub x4, x4, x0 // the kernel virtual and
str_l x4, kimage_voffset, x5 // physical mappings
+
+ // Clear BSS
+ adr_l x0, __bss_start
+ mov x1, xzr
+ adr_l x2, __bss_stop
+ sub x2, x2, x0
+ bl __pi_memset
+ dsb ishst // Make zero page visible to PTW
+
#ifdef CONFIG_KASAN
bl kasan_early_init
#endif
@@ -774,6 +774,7 @@ __enable_mmu:
mov x20, x1 // preserve branch target
#ifdef CONFIG_RANDOMIZE_BASE
mov x19, x0 // preserve new SCTLR_EL1 value
+ adrp x0, __PHYS_OFFSET
blr x1
/*
@@ -792,6 +793,7 @@ __enable_mmu:
isb
add x20, x20, x23 // relocated __mmap_switched
#endif
+ adrp x0, __PHYS_OFFSET
br x20
ENDPROC(__enable_mmu)
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 8/8] arm64/kernel: drop global kaslr_offset in x23 from head.S
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
` (6 preceding siblings ...)
2016-04-04 14:52 ` [PATCH 7/8] arm64/kernel: drop __PHYS_OFFSET register with file scope from head.S Ard Biesheuvel
@ 2016-04-04 14:52 ` Ard Biesheuvel
7 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 14:52 UTC (permalink / raw)
To: linux-arm-kernel
Instead of keeping a global kaslr_offset variable with file scope in
head.S, pass the kaslr_offset as an argument to __create_page_tables()
and __mmap_switched(), and return the new kaslr_offset from the latter
if it returns to __enable_mmu() in order to configure KASLR.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/kernel/head.S | 46 +++++++++++++-------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 23d03da7ecfe..02e37f052263 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -212,8 +212,9 @@ section_table:
ENTRY(stext)
bl preserve_boot_args
bl el2_setup // Drop to EL1, w0=cpu_boot_mode
- mov x23, xzr // KASLR offset, defaults to 0
bl set_cpu_boot_mode_flag
+
+ mov x0, xzr // KASLR offset, defaults to 0
bl __create_page_tables
/*
* The following calls CPU setup code, see arch/arm64/mm/proc.S for
@@ -305,14 +306,19 @@ ENDPROC(preserve_boot_args)
.endm
/*
+ * __create_page_tables(u64 kaslr_offset)
+ *
* Setup the initial page tables. We only setup the barest amount which is
* required to get the kernel running. The following sections are required:
* - identity mapping to enable the MMU (low address, TTBR0)
* - first few MB of the kernel linear mapping to jump to once the MMU has
* been enabled
+ *
+ * Clobbers callee saved registers x27 and x28
*/
__create_page_tables:
mov x28, lr
+ mov x27, x0
/*
* Invalidate the idmap and swapper page tables to avoid potential
@@ -391,7 +397,7 @@ __create_page_tables:
*/
adrp x0, swapper_pg_dir
ldr x5, =KIMAGE_VADDR
- add x5, x5, x23 // add KASLR displacement
+ add x5, x5, x27 // add KASLR displacement
create_pgd_entry x0, x5, x3, x6
ldr w6, kernel_img_size
add x6, x6, x5
@@ -416,7 +422,10 @@ kernel_img_size:
.ltorg
/*
- * __mmap_switched(u64 phys_offset) - virtual entry point for the boot CPU
+ * __mmap_switched(u64 phys_offset, u64 kaslr_offset) - virtual entry point for
+ * the boot CPU
+ *
+ * Clobbers callee saved register x26
*/
__mmap_switched:
adrp x4, init_thread_union
@@ -431,6 +440,7 @@ __mmap_switched:
isb
#ifdef CONFIG_RELOCATABLE
+ mov x26, x1 // preserve kaslr_offset
/*
* Iterate over each entry in the relocation table, and apply the
@@ -446,8 +456,8 @@ __mmap_switched:
ldr x13, [x9, #-8]
cmp w12, #R_AARCH64_RELATIVE
b.ne 1f
- add x13, x13, x23 // relocate
- str x13, [x11, x23]
+ add x13, x13, x1 // relocate
+ str x13, [x11, x1]
b 0b
1: cmp w12, #R_AARCH64_ABS64
@@ -457,10 +467,10 @@ __mmap_switched:
ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx
ldr x15, [x12, #8] // Elf64_Sym::st_value
cmp w14, #-0xf // SHN_ABS (0xfff1) ?
- add x14, x15, x23 // relocate
+ add x14, x15, x1 // relocate
csel x15, x14, x15, ne
add x15, x13, x15
- str x15, [x11, x23]
+ str x15, [x11, x1]
b 0b
2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
@@ -485,11 +495,10 @@ __mmap_switched:
bl kasan_early_init
#endif
#ifdef CONFIG_RANDOMIZE_BASE
- cbnz x23, 0f // already running randomized?
+ cbnz x26, 0f // already running randomized?
ldr_l x0, boot_args // pass FDT address in x0
bl kaslr_early_init // parse FDT for KASLR options
cbz x0, 0f // KASLR disabled? just proceed
- mov x23, x0 // record KASLR offset
ldp x29, x30, [sp], #16 // we must enable KASLR, return
ret // to __enable_mmu()
0:
@@ -747,6 +756,8 @@ ENTRY(__early_cpu_boot_status)
*
* Checks if the selected granule size is supported by the CPU.
* If it isn't, park the CPU
+ *
+ * Clobbers callee saved registers x22, x23, x24 and x25
*/
.section ".idmap.text", "ax"
__enable_mmu:
@@ -771,30 +782,33 @@ __enable_mmu:
ic iallu
dsb nsh
isb
- mov x20, x1 // preserve branch target
+ mov x25, x1 // preserve branch target
+ mov x1, xzr
#ifdef CONFIG_RANDOMIZE_BASE
- mov x19, x0 // preserve new SCTLR_EL1 value
+ mov x24, x0 // preserve new SCTLR_EL1 value
adrp x0, __PHYS_OFFSET
- blr x1
+ blr x25
/*
- * If we return here, we have a KASLR displacement in x23 which we need
+ * If we return here, we have a KASLR displacement in x0 which we need
* to take into account by discarding the current kernel mapping and
* creating a new one.
*/
msr sctlr_el1, x22 // disable the MMU
isb
+ mov x23, x0 // preserve new kaslr_offset
bl __create_page_tables // recreate kernel mapping
- msr sctlr_el1, x19 // re-enable the MMU
+ msr sctlr_el1, x24 // re-enable the MMU
isb
ic iallu // flush instructions fetched
dsb nsh // via old mapping
isb
- add x20, x20, x23 // relocated __mmap_switched
+ add x25, x25, x23 // relocated __mmap_switched
+ mov x1, x23
#endif
adrp x0, __PHYS_OFFSET
- br x20
+ br x25
ENDPROC(__enable_mmu)
__no_granule_support:
--
2.5.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer
2016-04-04 14:52 ` [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer Ard Biesheuvel
@ 2016-04-04 15:13 ` James Morse
2016-04-04 15:19 ` Ard Biesheuvel
0 siblings, 1 reply; 16+ messages in thread
From: James Morse @ 2016-04-04 15:13 UTC (permalink / raw)
To: linux-arm-kernel
Hi Ard,
On 04/04/16 15:52, Ard Biesheuvel wrote:
> Since we record the boot_args [x0 .. x3] early at boot anyway, there is
> no need to keep the FDT address in a callee saved register with file scope
> in head.S. So simply refer to boot_args[0] directly in the call to
> setup_machine(), and drop the handling of x21 from head.S entirely.
Won't this break Big Endian?
(or more accurately: bootloader-endian != kernel-endian)
The stores in preserve_boot_args happen before the EE/E0E bits have been
set/cleared by el2_setup(), so they happen with boot-loader:endianness. The
loads after el2_setup() happen with kernel:endianness.
Thanks,
James
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/head.S | 14 ++++++--------
> arch/arm64/kernel/setup.c | 4 +---
> 2 files changed, 7 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 69b33535911e..9d8f928c355c 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -234,16 +234,15 @@ ENDPROC(stext)
> * Preserve the arguments passed by the bootloader in x0 .. x3
> */
> preserve_boot_args:
> - mov x21, x0 // x21=FDT
> -
> - adr_l x0, boot_args // record the contents of
> - stp x21, x1, [x0] // x0 .. x3 at kernel entry
> - stp x2, x3, [x0, #16]
> + adr_l x4, boot_args // record the contents of
> + stp x0, x1, [x4] // x0 .. x3 at kernel entry
> + stp x2, x3, [x4, #16]
>
> dmb sy // needed before dc ivac with
> // MMU off
>
> - add x1, x0, #0x20 // 4 x 8 bytes
> + mov x0, x4
> + add x1, x4, #0x20 // 4 x 8 bytes
> b __inval_cache_range // tail call
> ENDPROC(preserve_boot_args)
>
> @@ -480,7 +479,6 @@ __mmap_switched:
> mov x4, sp
> and x4, x4, #~(THREAD_SIZE - 1)
> msr sp_el0, x4 // Save thread_info
> - str_l x21, __fdt_pointer, x5 // Save FDT pointer
>
> ldr_l x4, kimage_vaddr // Save the offset between
> sub x4, x4, x24 // the kernel virtual and
> @@ -492,7 +490,7 @@ __mmap_switched:
> #endif
> #ifdef CONFIG_RANDOMIZE_BASE
> cbnz x23, 0f // already running randomized?
> - mov x0, x21 // pass FDT address in x0
> + ldr_l x0, boot_args // pass FDT address in x0
> bl kaslr_early_init // parse FDT for KASLR options
> cbz x0, 0f // KASLR disabled? just proceed
> mov x23, x0 // record KASLR offset
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 9dc67769b6a4..83a3e484a90a 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -64,8 +64,6 @@
> #include <asm/xen/hypervisor.h>
> #include <asm/mmu_context.h>
>
> -phys_addr_t __fdt_pointer __initdata;
> -
> /*
> * Standard memory resources
> */
> @@ -304,7 +302,7 @@ void __init setup_arch(char **cmdline_p)
> early_fixmap_init();
> early_ioremap_init();
>
> - setup_machine_fdt(__fdt_pointer);
> + setup_machine_fdt(boot_args[0]);
>
> parse_early_param();
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer
2016-04-04 15:13 ` James Morse
@ 2016-04-04 15:19 ` Ard Biesheuvel
2016-04-05 11:09 ` Ard Biesheuvel
0 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 15:19 UTC (permalink / raw)
To: linux-arm-kernel
On 4 April 2016 at 17:13, James Morse <james.morse@arm.com> wrote:
> Hi Ard,
>
> On 04/04/16 15:52, Ard Biesheuvel wrote:
>> Since we record the boot_args [x0 .. x3] early at boot anyway, there is
>> no need to keep the FDT address in a callee saved register with file scope
>> in head.S. So simply refer to boot_args[0] directly in the call to
>> setup_machine(), and drop the handling of x21 from head.S entirely.
>
> Won't this break Big Endian?
> (or more accurately: bootloader-endian != kernel-endian)
>
> The stores in preserve_boot_args happen before the EE/E0E bits have been
> set/cleared by el2_setup(), so they happen with boot-loader:endianness. The
> loads after el2_setup() happen with kernel:endianness.
>
That is a very good point.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched()
2016-04-04 14:52 ` [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched() Ard Biesheuvel
@ 2016-04-04 15:33 ` James Morse
2016-04-04 15:40 ` Ard Biesheuvel
0 siblings, 1 reply; 16+ messages in thread
From: James Morse @ 2016-04-04 15:33 UTC (permalink / raw)
To: linux-arm-kernel
Hi Ard,
On 04/04/16 15:52, Ard Biesheuvel wrote:
> Considering that we can expect stack accesses from the moment we assign
> VBAR_EL1, let's initialize the stack pointer first in __mmap_switched(),
> and set up a proper stack frame while we're at it.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/head.S | 20 +++++++++-----------
> 1 file changed, 9 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 9d8f928c355c..f441fc73a7a2 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -421,9 +421,14 @@ kernel_img_size:
> /*
> * The following fragment of code is executed with the MMU enabled.
> */
> - .set initial_sp, init_thread_union + THREAD_START_SP
> __mmap_switched:
> - mov x28, lr // preserve LR
> + adrp x4, init_thread_union
> + add sp, x4, #THREAD_SIZE
> + msr sp_el0, x4 // Save thread_info
(Terms describing the stack are confusing, here goes!)
The address you have in x4 is the 'highest' address on the stack, (the first
that gets used), thread_info is at the other end, the 'lowest' address.
You used THREAD_SIZE instead of THREAD_START_SP, so the x4 value points to the
'bottom' of the page after the stack, this isn't a problem because the pre-index
addressing decrements sp before it writes, but it does break the 'and x4, x4,
#~(THREAD_SIZE - 1)' trick to find thread_info, which I think is what the '-16'
in THREAD_START_SP is for...
6cdf9c7ca687 ("arm64: Store struct thread_info in sp_el0") got rid of most of
the users of this masking trick, maybe we can get rid of THREAD_START_SP too?
(unless it is there for some other clever reason!)
Thanks,
James
> +
> + stp xzr, x30, [sp, #-16]!
> + mov x29, sp
> +
> adr_l x8, vectors // load VBAR_EL1 with virtual
> msr vbar_el1, x8 // vector table address
> isb
> @@ -475,16 +480,9 @@ __mmap_switched:
> dsb sy // with MMU off
> #endif
>
> - adr_l sp, initial_sp, x4
> - mov x4, sp
> - and x4, x4, #~(THREAD_SIZE - 1)
> - msr sp_el0, x4 // Save thread_info
> -
> ldr_l x4, kimage_vaddr // Save the offset between
> sub x4, x4, x24 // the kernel virtual and
> str_l x4, kimage_voffset, x5 // physical mappings
> -
> - mov x29, #0
> #ifdef CONFIG_KASAN
> bl kasan_early_init
> #endif
> @@ -494,8 +492,8 @@ __mmap_switched:
> bl kaslr_early_init // parse FDT for KASLR options
> cbz x0, 0f // KASLR disabled? just proceed
> mov x23, x0 // record KASLR offset
> - ret x28 // we must enable KASLR, return
> - // to __enable_mmu()
> + ldp x29, x30, [sp], #16 // we must enable KASLR, return
> + ret // to __enable_mmu()
> 0:
> #endif
> b start_kernel
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched()
2016-04-04 15:33 ` James Morse
@ 2016-04-04 15:40 ` Ard Biesheuvel
0 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-04 15:40 UTC (permalink / raw)
To: linux-arm-kernel
On 4 April 2016 at 17:33, James Morse <james.morse@arm.com> wrote:
> Hi Ard,
>
> On 04/04/16 15:52, Ard Biesheuvel wrote:
>> Considering that we can expect stack accesses from the moment we assign
>> VBAR_EL1, let's initialize the stack pointer first in __mmap_switched(),
>> and set up a proper stack frame while we're at it.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> arch/arm64/kernel/head.S | 20 +++++++++-----------
>> 1 file changed, 9 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 9d8f928c355c..f441fc73a7a2 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -421,9 +421,14 @@ kernel_img_size:
>> /*
>> * The following fragment of code is executed with the MMU enabled.
>> */
>> - .set initial_sp, init_thread_union + THREAD_START_SP
>> __mmap_switched:
>> - mov x28, lr // preserve LR
>> + adrp x4, init_thread_union
>> + add sp, x4, #THREAD_SIZE
>> + msr sp_el0, x4 // Save thread_info
>
> (Terms describing the stack are confusing, here goes!)
>
> The address you have in x4 is the 'highest' address on the stack, (the first
> that gets used), thread_info is at the other end, the 'lowest' address.
>
> You used THREAD_SIZE instead of THREAD_START_SP, so the x4 value points to the
> 'bottom' of the page after the stack, this isn't a problem because the pre-index
> addressing decrements sp before it writes, but it does break the 'and x4, x4,
> #~(THREAD_SIZE - 1)' trick to find thread_info, which I think is what the '-16'
> in THREAD_START_SP is for...
>
True. But since the sp is decremented by the same 16 bytes in the next
instruction, the net value of sp when entering start_kernel() is
identical.
> 6cdf9c7ca687 ("arm64: Store struct thread_info in sp_el0") got rid of most of
> the users of this masking trick, maybe we can get rid of THREAD_START_SP too?
> (unless it is there for some other clever reason!)
>
I agree that the whole point of the -16 is to make the masking work.
So if we can get rid of the masking, we can get rid of
THREAD_START_SP, and also of the natural alignment of the stacks.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer
2016-04-04 15:19 ` Ard Biesheuvel
@ 2016-04-05 11:09 ` Ard Biesheuvel
0 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-05 11:09 UTC (permalink / raw)
To: linux-arm-kernel
On 4 April 2016 at 17:19, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 4 April 2016 at 17:13, James Morse <james.morse@arm.com> wrote:
>> Hi Ard,
>>
>> On 04/04/16 15:52, Ard Biesheuvel wrote:
>>> Since we record the boot_args [x0 .. x3] early at boot anyway, there is
>>> no need to keep the FDT address in a callee saved register with file scope
>>> in head.S. So simply refer to boot_args[0] directly in the call to
>>> setup_machine(), and drop the handling of x21 from head.S entirely.
>>
>> Won't this break Big Endian?
>> (or more accurately: bootloader-endian != kernel-endian)
>>
>> The stores in preserve_boot_args happen before the EE/E0E bits have been
>> set/cleared by el2_setup(), so they happen with boot-loader:endianness. The
>> loads after el2_setup() happen with kernel:endianness.
>>
>
> That is a very good point.
I think it would not be unreasonable to factor out the configuration
of the endianness at the current exception level, and invoke it first
before recording the boot args, since we now rely on el2_setup() to do
that. That would also fix the 'bug' where the boot_args are recorded
in the endianness of the bootloader, although I doubt anyone cares
deeply about that one.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched
2016-04-04 14:52 ` [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel
@ 2016-04-07 9:38 ` Will Deacon
2016-04-07 9:43 ` Ard Biesheuvel
0 siblings, 1 reply; 16+ messages in thread
From: Will Deacon @ 2016-04-07 9:38 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Apr 04, 2016 at 04:52:17PM +0200, Ard Biesheuvel wrote:
> We can simply use a relocated 64-bit literal to store the address of
> __secondary_switched(), and the relocation code will ensure that it
> holds the correct value at secondary entry time, as long as we make sure
> that the literal value is visible to the secondaries before they enable
> their MMUs. So place the literal next to kimage_vaddr, and set the alignment
> so that it is covered by the same cacheline that we already have to clean
> for a similar purpose.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/head.S | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 4203d5f257bc..69b33535911e 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -471,7 +471,8 @@ __mmap_switched:
> b 0b
>
> 2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
> - dc cvac, x8 // value visible to secondaries
> + // and __secondary_switched
> + dc cvac, x8 // values visible to secondaries
> dsb sy // with MMU off
> #endif
>
> @@ -506,10 +507,12 @@ ENDPROC(__mmap_switched)
> * end early head section, begin head code that is also used for
> * hotplug and needs to have the same protections as the text region
> */
> - .section ".text","ax"
> -
> + .section ".text","ax"
> + .align 4
> ENTRY(kimage_vaddr)
Since ENTRY already has a .align 4, can you drop the explicit directive
here?
Will
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched
2016-04-07 9:38 ` Will Deacon
@ 2016-04-07 9:43 ` Ard Biesheuvel
0 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2016-04-07 9:43 UTC (permalink / raw)
To: linux-arm-kernel
On 7 April 2016 at 11:38, Will Deacon <will.deacon@arm.com> wrote:
> On Mon, Apr 04, 2016 at 04:52:17PM +0200, Ard Biesheuvel wrote:
>> We can simply use a relocated 64-bit literal to store the address of
>> __secondary_switched(), and the relocation code will ensure that it
>> holds the correct value at secondary entry time, as long as we make sure
>> that the literal value is visible to the secondaries before they enable
>> their MMUs. So place the literal next to kimage_vaddr, and set the alignment
>> so that it is covered by the same cacheline that we already have to clean
>> for a similar purpose.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> arch/arm64/kernel/head.S | 14 +++++++-------
>> 1 file changed, 7 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 4203d5f257bc..69b33535911e 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -471,7 +471,8 @@ __mmap_switched:
>> b 0b
>>
>> 2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
>> - dc cvac, x8 // value visible to secondaries
>> + // and __secondary_switched
>> + dc cvac, x8 // values visible to secondaries
>> dsb sy // with MMU off
>> #endif
>>
>> @@ -506,10 +507,12 @@ ENDPROC(__mmap_switched)
>> * end early head section, begin head code that is also used for
>> * hotplug and needs to have the same protections as the text region
>> */
>> - .section ".text","ax"
>> -
>> + .section ".text","ax"
>> + .align 4
>> ENTRY(kimage_vaddr)
>
> Since ENTRY already has a .align 4, can you drop the explicit directive
> here?
>
Sure, I hadn't realised that.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2016-04-07 9:43 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-04 14:52 [PATCH 0/8] arm64: 2016 head.S spring cleaning Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 1/8] arm64/kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel
2016-04-07 9:38 ` Will Deacon
2016-04-07 9:43 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 2/8] arm64/kernel: reuse boot_args array to get to __fdt_pointer Ard Biesheuvel
2016-04-04 15:13 ` James Morse
2016-04-04 15:19 ` Ard Biesheuvel
2016-04-05 11:09 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 3/8] arm64/kernel: use a proper stack frame in __mmap_switched() Ard Biesheuvel
2016-04-04 15:33 ` James Morse
2016-04-04 15:40 ` Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 4/8] arm64/kernel: use ordinary calling convention for EL2 setup Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 5/8] arm64/kernel: refer to idmap_pg_dir and swapper_pg_dir directly Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 6/8] arm64/kernel: pass virtual entry point as __enable_mmu() argument Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 7/8] arm64/kernel: drop __PHYS_OFFSET register with file scope from head.S Ard Biesheuvel
2016-04-04 14:52 ` [PATCH 8/8] arm64/kernel: drop global kaslr_offset in x23 " Ard Biesheuvel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.