ARM: mm: switch to swapper_pg_dir early for vmap'ed stack
authorArd Biesheuvel <ardb@kernel.org>
Mon, 24 Jan 2022 18:51:58 +0000 (19:51 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Mon, 24 Jan 2022 19:37:55 +0000 (20:37 +0100)
When onlining a CPU, switch to swapper_pg_dir as soon as possible so
that it is guaranteed that the vmap'ed stack is mapped before it is
used.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/arm/Kconfig
arch/arm/kernel/head.S
arch/arm/kernel/sleep.S

index c32b794..359a3b8 100644 (file)
@@ -128,7 +128,7 @@ config ARM
        select RTC_LIB
        select SYS_SUPPORTS_APM_EMULATION
        select THREAD_INFO_IN_TASK
-       select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000) && !PM_SLEEP_SMP
+       select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000)
        select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
        # Above selects are sorted alphabetically; please add new ones
        # according to that.  Thanks.
index c04dd94..500612d 100644 (file)
@@ -424,6 +424,13 @@ ENDPROC(secondary_startup)
 ENDPROC(secondary_startup_arm)
 
 ENTRY(__secondary_switched)
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+       @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+       @ as the ID map does not cover the vmalloc region.
+       mrc     p15, 0, ip, c2, c0, 1   @ read TTBR1
+       mcr     p15, 0, ip, c2, c0, 0   @ set TTBR0
+       instr_sync
+#endif
        adr_l   r7, secondary_data + 12         @ get secondary_data.stack
        ldr     sp, [r7]
        ldr     r0, [r7, #4]                    @ get secondary_data.task
index f909baf..a86a1d4 100644 (file)
@@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
 ENDPROC(cpu_resume_mmu)
        .popsection
 cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+       @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+       @ as the ID map does not cover the vmalloc region.
+       mrc     p15, 0, ip, c2, c0, 1   @ read TTBR1
+       mcr     p15, 0, ip, c2, c0, 0   @ set TTBR0
+       instr_sync
+#endif
        bl      cpu_init                @ restore the und/abt/irq banked regs
        mov     r0, #0                  @ return zero on success
        ldmfd   sp!, {r4 - r11, pc}