arm64: entry: Free up another register on kpti's tramp_exit path
authorJames Morse <james.morse@arm.com>
Wed, 6 Apr 2022 16:45:30 +0000 (17:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Apr 2022 05:52:15 +0000 (07:52 +0200)
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 160a3131a190d7c63b5749af0a7217d3c2e6dd72..40647b5e279ec47360794036faf42461e47011e3 100644 (file)
@@ -244,14 +244,16 @@ 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
 
        .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:
@@ -259,6 +261,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
@@ -947,10 +951,12 @@ __ni_sys_trace:
        .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