]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
arm64: entry: Free up another register on kpti's tramp_exit path
authorJames Morse <james.morse@arm.com>
Fri, 18 Mar 2022 17:48:26 +0000 (17:48 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 23 Mar 2022 08:10:42 +0000 (09:10 +0100)
commit 03aff3a77a58b5b52a77e00537a42090ad57b80b upstream.

Kpti stashes x30 in far_el1 while it uses x30 for all its work.

Making the vectors a per-cpu data structure will require a second
register.

Allow tramp_exit two registers before it unmaps the kernel, by
leaving x30 on the stack, and stashing x29 in far_el1.

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm64/kernel/entry.S

index 96a0dda176c5e13b93ca2b0f4082f53f811e9dc2..16988a9d1d1985a6c2f670602cd8eb86fe68d1a1 100644 (file)
@@ -348,18 +348,20 @@ alternative_else_nop_endif
        ldp     x24, x25, [sp, #16 * 12]
        ldp     x26, x27, [sp, #16 * 13]
        ldp     x28, x29, [sp, #16 * 14]
-       ldr     lr, [sp, #S_LR]
-       add     sp, sp, #S_FRAME_SIZE           // restore sp
        /*
         * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization
         * when returning from IPI handler, and when returning to user-space.
         */
 
        .if     \el == 0
-alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
+alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
+       ldr     lr, [sp, #S_LR]
+       add     sp, sp, #S_FRAME_SIZE           // restore sp
+       eret
+alternative_else_nop_endif
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
        bne     4f
-       msr     far_el1, x30
+       msr     far_el1, x29
        tramp_alias     x30, tramp_exit_native
        br      x30
 4:
@@ -367,6 +369,8 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
        br      x30
 #endif
        .else
+       ldr     lr, [sp, #S_LR]
+       add     sp, sp, #S_FRAME_SIZE           // restore sp
        eret
        .endif
        .endm
@@ -996,10 +1000,12 @@ alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
        .macro tramp_exit, regsize = 64
        adr     x30, tramp_vectors
        msr     vbar_el1, x30
-       tramp_unmap_kernel      x30
+       ldr     lr, [sp, #S_LR]
+       tramp_unmap_kernel      x29
        .if     \regsize == 64
-       mrs     x30, far_el1
+       mrs     x29, far_el1
        .endif
+       add     sp, sp, #S_FRAME_SIZE           // restore sp
        eret
        .endm