arm64: entry: Free up another register on kpti's tramp_exit path

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>
This commit is contained in:
James Morse
2021-11-23 18:41:43 +00:00
committed by Greg Kroah-Hartman
parent 5242d6971e
commit d93b25a665

View File

@@ -357,14 +357,16 @@ alternative_else_nop_endif
ldp x24, x25, [sp, #16 * 12] ldp x24, x25, [sp, #16 * 12]
ldp x26, x27, [sp, #16 * 13] ldp x26, x27, [sp, #16 * 13]
ldp x28, x29, [sp, #16 * 14] ldp x28, x29, [sp, #16 * 14]
ldr lr, [sp, #S_LR]
add sp, sp, #S_FRAME_SIZE // restore sp
.if \el == 0 .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 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
bne 4f bne 4f
msr far_el1, x30 msr far_el1, x29
tramp_alias x30, tramp_exit_native tramp_alias x30, tramp_exit_native
br x30 br x30
4: 4:
@@ -372,6 +374,9 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
br x30 br x30
#endif #endif
.else .else
ldr lr, [sp, #S_LR]
add sp, sp, #S_FRAME_SIZE // restore sp
/* Ensure any device/NC reads complete */ /* Ensure any device/NC reads complete */
alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412 alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412
@@ -844,10 +849,12 @@ alternative_else_nop_endif
.macro tramp_exit, regsize = 64 .macro tramp_exit, regsize = 64
adr x30, tramp_vectors adr x30, tramp_vectors
msr vbar_el1, x30 msr vbar_el1, x30
tramp_unmap_kernel x30 ldr lr, [sp, #S_LR]
tramp_unmap_kernel x29
.if \regsize == 64 .if \regsize == 64
mrs x30, far_el1 mrs x29, far_el1
.endif .endif
add sp, sp, #S_FRAME_SIZE // restore sp
eret eret
sb sb
.endm .endm