aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Murzin <vladimir.murzin@arm.com>2014-08-08 11:35:08 +0100
committerMark Rutland <mark.rutland@arm.com>2014-11-06 17:34:24 +0000
commit119f54ca240684f47d8c1897ca4594fccc59846b (patch)
treee6548fee8cbd07ddce2ae40f6aee07d89b13720e
parent955cb98c8b6c47dddc4191011ec0c45f51d6da09 (diff)
Set sctlr_el2 to predefined state for all CPUs
Currently, sctlr_el2 is initialised only in the cold boot path, and even then we didn't set the RES1 bits. So we're lucky the cold boot path ever worked given most of the bits are UNKNOWN. Lack of initialisation in the hot boot path leads to kernel crash while CPU is hot-plugging and KVM is enabled: root@genericarmv8:~# echo 0 > /sys/devices/system/cpu/cpu1/online kvm: disabling virtualization on CPU1 CPU1: shutdown root@genericarmv8:~# echo 1 > /sys/devices/system/cpu/cpu1/online Kernel panic - not syncing: HYP panic: PS:000003c9 PC:0000000080002394 ESR:0000000086000005 FAR:0000000080002394 HPFAR: (null) PAR: (null) VCPU: (null) CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.16.0-rc1+ #162 Call trace: [<ffffffc0000880d8>] dump_backtrace+0x0/0x12c [<ffffffc000088214>] show_stack+0x10/0x1c [<ffffffc000472680>] dump_stack+0x74/0xc4 [<ffffffc00046f8ec>] panic+0xe4/0x21c [<ffffffc00046f804>] mmu_memory_cache_alloc.part.25+0x34/0x38 [<ffffffc00008a26c>] cpu_psci_cpu_die+0x20/0x40 [<ffffffc00008e95c>] cpu_die+0x40/0x70 [<ffffffc0000852e0>] arch_cpu_idle_dead+0x8/0x14 [<ffffffc0000dca4c>] cpu_startup_entry+0x144/0x14c [<ffffffc00008e7f0>] secondary_start_kernel+0x118/0x128 Initialise sctlr_el2 in the reset value just before dropping from EL3 for psci and spin-table boot protocols. Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
-rw-r--r--boot.S2
-rw-r--r--common.S6
-rw-r--r--psci.S3
-rw-r--r--spin.S2
4 files changed, 11 insertions, 2 deletions
diff --git a/boot.S b/boot.S
index 29ffb6f..c65590c 100644
--- a/boot.S
+++ b/boot.S
@@ -33,8 +33,6 @@ _start:
bl gic_secure_init
- msr sctlr_el2, xzr
-
b start_el3
.ltorg
diff --git a/common.S b/common.S
index 70ed17e..7ddfad0 100644
--- a/common.S
+++ b/common.S
@@ -11,6 +11,12 @@
#define CURRENTEL_EL3 (3 << 2)
+/*
+ * RES1 bits, little-endian, caches and MMU off, no alignment checking,
+ * no WXN.
+ */
+#define SCTLR_EL2_RESET (3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
+
#define SPSR_A (1 << 8) /* System Error masked */
#define SPSR_D (1 << 9) /* Debug masked */
#define SPSR_I (1 << 7) /* IRQ masked */
diff --git a/psci.S b/psci.S
index 5f59e2a..856095b 100644
--- a/psci.S
+++ b/psci.S
@@ -220,6 +220,9 @@ spin:
cmp x2, x3
b.eq 1b
+ ldr x0, =SCTLR_EL2_RESET
+ msr sctlr_el2, x0
+
mov x3, #SPSR_KERNEL
adr x4, el2_trampoline
mov x0, x2
diff --git a/spin.S b/spin.S
index 4ad3cf2..04101cc 100644
--- a/spin.S
+++ b/spin.S
@@ -18,6 +18,8 @@ start_el3:
/*
* Prepare the switch to the EL2_SP1 mode from EL3
*/
+ ldr x0, =SCTLR_EL2_RESET
+ msr sctlr_el2, x0
ldr x0, =start_no_el3 // Return after mode switch
mov x1, #SPSR_KERNEL
drop_el x1, x0