| From foo@baz Sat Mar 19 01:51:18 PM CET 2022 |
| From: James Morse <james.morse@arm.com> |
| Date: Fri, 18 Mar 2022 17:48:26 +0000 |
| Subject: arm64: entry: Free up another register on kpti's tramp_exit path |
| To: stable@vger.kernel.org |
| Cc: linux-kernel@vger.kernel.org, james.morse@arm.com, catalin.marinas@arm.com |
| Message-ID: <20220318174842.2321061-7-james.morse@arm.com> |
| |
| From: James Morse <james.morse@arm.com> |
| |
| 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 | 18 ++++++++++++------ |
| 1 file changed, 12 insertions(+), 6 deletions(-) |
| |
| --- a/arch/arm64/kernel/entry.S |
| +++ b/arch/arm64/kernel/entry.S |
| @@ -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_ |
| 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_WORKARO |
| .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 |
| |