summaryrefslogtreecommitdiff
path: root/arch/arm64/kvm/hyp/entry.S
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2015-10-26 11:34:09 +0300
committerMarc Zyngier <marc.zyngier@arm.com>2015-12-14 14:30:41 +0300
commitc13d1683df16db16c91372177ca10c31677b5ed5 (patch)
treec33ebab7d9dff4a45664c47edda215838ed5c5b7 /arch/arm64/kvm/hyp/entry.S
parentbe901e9b15cd2c8e48dc089b4655ea4a076e66fd (diff)
downloadlinux-c13d1683df16db16c91372177ca10c31677b5ed5.tar.xz
arm64: KVM: Implement fpsimd save/restore
Implement the fpsimd save restore, keeping the lazy part in assembler (as returning to C would be overkill). Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'arch/arm64/kvm/hyp/entry.S')
-rw-r--r--arch/arm64/kvm/hyp/entry.S32
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index ff196951e63b..90cbf0fee88a 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -27,6 +27,7 @@
#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x)
#define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
+#define CPU_SYSREG_OFFSET(x) (CPU_SYSREGS + 8*x)
.text
.pushsection .hyp.text, "ax"
@@ -127,4 +128,33 @@ ENTRY(__guest_exit)
ret
ENDPROC(__guest_exit)
- /* Insert fault handling here */
+ENTRY(__fpsimd_guest_restore)
+ stp x4, lr, [sp, #-16]!
+
+ mrs x2, cptr_el2
+ bic x2, x2, #CPTR_EL2_TFP
+ msr cptr_el2, x2
+ isb
+
+ mrs x3, tpidr_el2
+
+ ldr x0, [x3, #VCPU_HOST_CONTEXT]
+ kern_hyp_va x0
+ add x0, x0, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+ bl __fpsimd_save_state
+
+ add x2, x3, #VCPU_CONTEXT
+ add x0, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+ bl __fpsimd_restore_state
+
+ mrs x1, hcr_el2
+ tbnz x1, #HCR_RW_SHIFT, 1f
+ ldr x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
+ msr fpexc32_el2, x4
+1:
+ ldp x4, lr, [sp], #16
+ ldp x2, x3, [sp], #16
+ ldp x0, x1, [sp], #16
+
+ eret
+ENDPROC(__fpsimd_guest_restore)