|
@@ -21,6 +21,7 @@
|
|
|
|
|
|
#include <kvm/arm_psci.h>
|
|
#include <kvm/arm_psci.h>
|
|
|
|
|
|
|
|
+#include <asm/cpufeature.h>
|
|
#include <asm/kvm_asm.h>
|
|
#include <asm/kvm_asm.h>
|
|
#include <asm/kvm_emulate.h>
|
|
#include <asm/kvm_emulate.h>
|
|
#include <asm/kvm_host.h>
|
|
#include <asm/kvm_host.h>
|
|
@@ -28,6 +29,7 @@
|
|
#include <asm/kvm_mmu.h>
|
|
#include <asm/kvm_mmu.h>
|
|
#include <asm/fpsimd.h>
|
|
#include <asm/fpsimd.h>
|
|
#include <asm/debug-monitors.h>
|
|
#include <asm/debug-monitors.h>
|
|
|
|
+#include <asm/processor.h>
|
|
#include <asm/thread_info.h>
|
|
#include <asm/thread_info.h>
|
|
|
|
|
|
/* Check whether the FP regs were dirtied while in the host-side run loop: */
|
|
/* Check whether the FP regs were dirtied while in the host-side run loop: */
|
|
@@ -329,6 +331,8 @@ static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
|
|
void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
|
|
void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
|
|
struct kvm_vcpu *vcpu)
|
|
struct kvm_vcpu *vcpu)
|
|
{
|
|
{
|
|
|
|
+ struct user_fpsimd_state *host_fpsimd = vcpu->arch.host_fpsimd_state;
|
|
|
|
+
|
|
if (has_vhe())
|
|
if (has_vhe())
|
|
write_sysreg(read_sysreg(cpacr_el1) | CPACR_EL1_FPEN,
|
|
write_sysreg(read_sysreg(cpacr_el1) | CPACR_EL1_FPEN,
|
|
cpacr_el1);
|
|
cpacr_el1);
|
|
@@ -339,7 +343,21 @@ void __hyp_text __hyp_switch_fpsimd(u64 esr __always_unused,
|
|
isb();
|
|
isb();
|
|
|
|
|
|
if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
|
|
if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
|
|
- __fpsimd_save_state(vcpu->arch.host_fpsimd_state);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * In the SVE case, VHE is assumed: it is enforced by
|
|
|
|
+ * Kconfig and kvm_arch_init().
|
|
|
|
+ */
|
|
|
|
+ if (system_supports_sve() &&
|
|
|
|
+ (vcpu->arch.flags & KVM_ARM64_HOST_SVE_IN_USE)) {
|
|
|
|
+ struct thread_struct *thread = container_of(
|
|
|
|
+ host_fpsimd,
|
|
|
|
+ struct thread_struct, uw.fpsimd_state);
|
|
|
|
+
|
|
|
|
+ sve_save_state(sve_pffr(thread), &host_fpsimd->fpsr);
|
|
|
|
+ } else {
|
|
|
|
+ __fpsimd_save_state(host_fpsimd);
|
|
|
|
+ }
|
|
|
|
+
|
|
vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
|
|
vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
|
|
}
|
|
}
|
|
|
|
|