| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Tue, 3 Apr 2018 10:39:04 -0700 |
| Subject: FROMLIST: arm64: kvm: stop treating register x18 as caller save |
| |
| In preparation of reserving x18, stop treating it as caller save in |
| the KVM guest entry/exit code. Currently, the code assumes there is |
| no need to preserve it for the host, given that it would have been |
| assumed clobbered anyway by the function call to __guest_enter(). |
| Instead, preserve its value and restore it upon return. |
| |
| Bug: 145210207 |
| Change-Id: I341bcb10b615999a59a8413a6b98cb2ce1c62e02 |
| (am from https://lore.kernel.org/patchwork/patch/1149065/) |
| Link: https://patchwork.kernel.org/patch/9836891/ |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Reviewed-by: Kees Cook <keescook@chromium.org> |
| Reviewed-by: Marc Zyngier <maz@kernel.org> |
| Reviewed-by: Mark Rutland <mark.rutland@arm.com> |
| [Sami: updated commit message, switched from x18 to x29 for the guest context] |
| Signed-off-by: Sami Tolvanen <samitolvanen@google.com> |
| --- |
| arch/arm64/kvm/hyp/entry.S | 45 ++++++++++++++++++++------------------ |
| 1 file changed, 24 insertions(+), 21 deletions(-) |
| |
| diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S |
| index e5cc8d66bf53..0c6832ec52b1 100644 |
| --- a/arch/arm64/kvm/hyp/entry.S |
| +++ b/arch/arm64/kvm/hyp/entry.S |
| @@ -22,7 +22,12 @@ |
| .text |
| .pushsection .hyp.text, "ax" |
| |
| +/* |
| + * We treat x18 as callee-saved as the host may use it as a platform |
| + * register (e.g. for shadow call stack). |
| + */ |
| .macro save_callee_saved_regs ctxt |
| + str x18, [\ctxt, #CPU_XREG_OFFSET(18)] |
| stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] |
| stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] |
| stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] |
| @@ -32,6 +37,8 @@ |
| .endm |
| |
| .macro restore_callee_saved_regs ctxt |
| + // We require \ctxt is not x18-x28 |
| + ldr x18, [\ctxt, #CPU_XREG_OFFSET(18)] |
| ldp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] |
| ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] |
| ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] |
| @@ -48,7 +55,7 @@ ENTRY(__guest_enter) |
| // x0: vcpu |
| // x1: host context |
| // x2-x17: clobbered by macros |
| - // x18: guest context |
| + // x29: guest context |
| |
| // Store the host regs |
| save_callee_saved_regs x1 |
| @@ -67,31 +74,28 @@ alternative_else_nop_endif |
| ret |
| |
| 1: |
| - add x18, x0, #VCPU_CONTEXT |
| + add x29, x0, #VCPU_CONTEXT |
| |
| // Macro ptrauth_switch_to_guest format: |
| // ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3) |
| // The below macro to restore guest keys is not implemented in C code |
| // as it may cause Pointer Authentication key signing mismatch errors |
| // when this feature is enabled for kernel code. |
| - ptrauth_switch_to_guest x18, x0, x1, x2 |
| + ptrauth_switch_to_guest x29, x0, x1, x2 |
| |
| // Restore guest regs x0-x17 |
| - ldp x0, x1, [x18, #CPU_XREG_OFFSET(0)] |
| - ldp x2, x3, [x18, #CPU_XREG_OFFSET(2)] |
| - ldp x4, x5, [x18, #CPU_XREG_OFFSET(4)] |
| - ldp x6, x7, [x18, #CPU_XREG_OFFSET(6)] |
| - ldp x8, x9, [x18, #CPU_XREG_OFFSET(8)] |
| - ldp x10, x11, [x18, #CPU_XREG_OFFSET(10)] |
| - ldp x12, x13, [x18, #CPU_XREG_OFFSET(12)] |
| - ldp x14, x15, [x18, #CPU_XREG_OFFSET(14)] |
| - ldp x16, x17, [x18, #CPU_XREG_OFFSET(16)] |
| - |
| - // Restore guest regs x19-x29, lr |
| - restore_callee_saved_regs x18 |
| - |
| - // Restore guest reg x18 |
| - ldr x18, [x18, #CPU_XREG_OFFSET(18)] |
| + ldp x0, x1, [x29, #CPU_XREG_OFFSET(0)] |
| + ldp x2, x3, [x29, #CPU_XREG_OFFSET(2)] |
| + ldp x4, x5, [x29, #CPU_XREG_OFFSET(4)] |
| + ldp x6, x7, [x29, #CPU_XREG_OFFSET(6)] |
| + ldp x8, x9, [x29, #CPU_XREG_OFFSET(8)] |
| + ldp x10, x11, [x29, #CPU_XREG_OFFSET(10)] |
| + ldp x12, x13, [x29, #CPU_XREG_OFFSET(12)] |
| + ldp x14, x15, [x29, #CPU_XREG_OFFSET(14)] |
| + ldp x16, x17, [x29, #CPU_XREG_OFFSET(16)] |
| + |
| + // Restore guest regs x18-x29, lr |
| + restore_callee_saved_regs x29 |
| |
| // Do not touch any register after this! |
| eret |
| @@ -114,7 +118,7 @@ ENTRY(__guest_exit) |
| // Retrieve the guest regs x0-x1 from the stack |
| ldp x2, x3, [sp], #16 // x0, x1 |
| |
| - // Store the guest regs x0-x1 and x4-x18 |
| + // Store the guest regs x0-x1 and x4-x17 |
| stp x2, x3, [x1, #CPU_XREG_OFFSET(0)] |
| stp x4, x5, [x1, #CPU_XREG_OFFSET(4)] |
| stp x6, x7, [x1, #CPU_XREG_OFFSET(6)] |
| @@ -123,9 +127,8 @@ ENTRY(__guest_exit) |
| stp x12, x13, [x1, #CPU_XREG_OFFSET(12)] |
| stp x14, x15, [x1, #CPU_XREG_OFFSET(14)] |
| stp x16, x17, [x1, #CPU_XREG_OFFSET(16)] |
| - str x18, [x1, #CPU_XREG_OFFSET(18)] |
| |
| - // Store the guest regs x19-x29, lr |
| + // Store the guest regs x18-x29, lr |
| save_callee_saved_regs x1 |
| |
| get_host_ctxt x2, x3 |