Commit af123768 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Will Deacon

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.

Link: https://patchwork.kernel.org/patch/9836891/Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
[Sami: updated commit message, switched from x18 to x29 for the guest context]
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 7f153ccb
...@@ -22,7 +22,12 @@ ...@@ -22,7 +22,12 @@
.text .text
.pushsection .hyp.text, "ax" .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 .macro save_callee_saved_regs ctxt
str x18, [\ctxt, #CPU_XREG_OFFSET(18)]
stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
...@@ -32,6 +37,8 @@ ...@@ -32,6 +37,8 @@
.endm .endm
.macro restore_callee_saved_regs ctxt .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 x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
...@@ -48,7 +55,7 @@ ENTRY(__guest_enter) ...@@ -48,7 +55,7 @@ ENTRY(__guest_enter)
// x0: vcpu // x0: vcpu
// x1: host context // x1: host context
// x2-x17: clobbered by macros // x2-x17: clobbered by macros
// x18: guest context // x29: guest context
// Store the host regs // Store the host regs
save_callee_saved_regs x1 save_callee_saved_regs x1
...@@ -67,31 +74,28 @@ alternative_else_nop_endif ...@@ -67,31 +74,28 @@ alternative_else_nop_endif
ret ret
1: 1:
add x18, x0, #VCPU_CONTEXT add x29, x0, #VCPU_CONTEXT
// Macro ptrauth_switch_to_guest format: // Macro ptrauth_switch_to_guest format:
// ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3) // ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3)
// The below macro to restore guest keys is not implemented in C code // The below macro to restore guest keys is not implemented in C code
// as it may cause Pointer Authentication key signing mismatch errors // as it may cause Pointer Authentication key signing mismatch errors
// when this feature is enabled for kernel code. // 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 // Restore guest regs x0-x17
ldp x0, x1, [x18, #CPU_XREG_OFFSET(0)] ldp x0, x1, [x29, #CPU_XREG_OFFSET(0)]
ldp x2, x3, [x18, #CPU_XREG_OFFSET(2)] ldp x2, x3, [x29, #CPU_XREG_OFFSET(2)]
ldp x4, x5, [x18, #CPU_XREG_OFFSET(4)] ldp x4, x5, [x29, #CPU_XREG_OFFSET(4)]
ldp x6, x7, [x18, #CPU_XREG_OFFSET(6)] ldp x6, x7, [x29, #CPU_XREG_OFFSET(6)]
ldp x8, x9, [x18, #CPU_XREG_OFFSET(8)] ldp x8, x9, [x29, #CPU_XREG_OFFSET(8)]
ldp x10, x11, [x18, #CPU_XREG_OFFSET(10)] ldp x10, x11, [x29, #CPU_XREG_OFFSET(10)]
ldp x12, x13, [x18, #CPU_XREG_OFFSET(12)] ldp x12, x13, [x29, #CPU_XREG_OFFSET(12)]
ldp x14, x15, [x18, #CPU_XREG_OFFSET(14)] ldp x14, x15, [x29, #CPU_XREG_OFFSET(14)]
ldp x16, x17, [x18, #CPU_XREG_OFFSET(16)] ldp x16, x17, [x29, #CPU_XREG_OFFSET(16)]
// Restore guest regs x19-x29, lr // Restore guest regs x18-x29, lr
restore_callee_saved_regs x18 restore_callee_saved_regs x29
// Restore guest reg x18
ldr x18, [x18, #CPU_XREG_OFFSET(18)]
// Do not touch any register after this! // Do not touch any register after this!
eret eret
...@@ -114,7 +118,7 @@ ENTRY(__guest_exit) ...@@ -114,7 +118,7 @@ ENTRY(__guest_exit)
// Retrieve the guest regs x0-x1 from the stack // Retrieve the guest regs x0-x1 from the stack
ldp x2, x3, [sp], #16 // x0, x1 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 x2, x3, [x1, #CPU_XREG_OFFSET(0)]
stp x4, x5, [x1, #CPU_XREG_OFFSET(4)] stp x4, x5, [x1, #CPU_XREG_OFFSET(4)]
stp x6, x7, [x1, #CPU_XREG_OFFSET(6)] stp x6, x7, [x1, #CPU_XREG_OFFSET(6)]
...@@ -123,9 +127,8 @@ ENTRY(__guest_exit) ...@@ -123,9 +127,8 @@ ENTRY(__guest_exit)
stp x12, x13, [x1, #CPU_XREG_OFFSET(12)] stp x12, x13, [x1, #CPU_XREG_OFFSET(12)]
stp x14, x15, [x1, #CPU_XREG_OFFSET(14)] stp x14, x15, [x1, #CPU_XREG_OFFSET(14)]
stp x16, x17, [x1, #CPU_XREG_OFFSET(16)] 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 save_callee_saved_regs x1
get_host_ctxt x2, x3 get_host_ctxt x2, x3
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment