]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
arm: kernel: sleep: restore HYP mode configuration in cpu_resume
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tue, 25 Feb 2014 17:11:03 +0000 (17:11 +0000)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Mon, 10 Mar 2014 15:39:48 +0000 (15:39 +0000)
On CPUs with virtualization extensions the kernel installs HYP mode
configuration on both primary and secondary cpus upon cold boot.

On platforms where CPUs are shutdown in idle paths (ie CPU core gating),
when a CPU resumes from low-power states it currently does not execute
code that reinstalls the HYP configuration, which means that the kernel
cannot run eg KVM properly on such machines.

This patch, mirroring cold-boot behaviour, executes position independent
code that reinstalls HYP configuration and drops to SVC mode safely on
warmboot, so that deep idle states can be enabled in kernel running as
hosts on platforms with power management HW.

Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Dave Martin <dave.martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Nicolas Pitre <nico@linaro.org>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
arch/arm/include/asm/assembler.h
arch/arm/kernel/sleep.S

index 5c228516057552b6eca4f6f5a54f2a3f9733fd09..1db31af5c96623cbe677cf4b5d16a53021cbf09d 100644 (file)
  * you cannot return to the original mode.
  */
 .macro safe_svcmode_maskall reg:req
-#if __LINUX_ARM_ARCH__ >= 6
+#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
        mrs     \reg , cpsr
        eor     \reg, \reg, #HYP_MODE
        tst     \reg, #MODE_MASK
index b907d9b790ab7234171c713c4e6c9aed957868ea..1b880db2a0338fc08cc1b7355ee71eee7d142172 100644 (file)
@@ -127,6 +127,10 @@ ENDPROC(cpu_resume_after_mmu)
        .align
 ENTRY(cpu_resume)
 ARM_BE8(setend be)                     @ ensure we are in BE mode
+#ifdef CONFIG_ARM_VIRT_EXT
+       bl      __hyp_stub_install_secondary
+#endif
+       safe_svcmode_maskall r1
        mov     r1, #0
        ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
        ALT_UP_B(1f)
@@ -144,7 +148,6 @@ ARM_BE8(setend be)                  @ ensure we are in BE mode
        ldr     r0, [r0, #SLEEP_SAVE_SP_PHYS]
        ldr     r0, [r0, r1, lsl #2]
 
-       setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1  @ set SVC, irqs off
        @ load phys pgd, stack, resume fn
   ARM( ldmia   r0!, {r1, sp, pc}       )
 THUMB( ldmia   r0!, {r1, r2, r3}       )