提交 64330073 编写于 作者: M Marc Zyngier

Merge branch kvm-arm64/fpsimd-doc into kvmarm-master/next

* kvm-arm64/fpsimd-doc:
  : .
  : FPSIMD documentation update, courtesy of Mark Brown
  : .
  arm64/fpsimd: Clarify the purpose of using last in fpsimd_save()
  KVM: arm64: Add some more comments in kvm_hyp_handle_fpsimd()
  KVM: arm64: Add comments for context flush and sync callbacks
Signed-off-by: NMarc Zyngier <maz@kernel.org>
...@@ -348,7 +348,13 @@ static void task_fpsimd_load(void) ...@@ -348,7 +348,13 @@ static void task_fpsimd_load(void)
/* /*
* Ensure FPSIMD/SVE storage in memory for the loaded context is up to * Ensure FPSIMD/SVE storage in memory for the loaded context is up to
* date with respect to the CPU registers. * date with respect to the CPU registers. Note carefully that the
* current context is the context last bound to the CPU stored in
* last, if KVM is involved this may be the guest VM context rather
* than the host thread for the VM pointed to by current. This means
* that we must always reference the state storage via last rather
* than via current, other than the TIF_ flags which KVM will
* carefully maintain for us.
*/ */
static void fpsimd_save(void) static void fpsimd_save(void)
{ {
......
...@@ -84,6 +84,11 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu) ...@@ -84,6 +84,11 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED; vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
} }
/*
* Called just before entering the guest once we are no longer
* preemptable. Syncs the host's TIF_FOREIGN_FPSTATE with the KVM
* mirror of the flag used by the hypervisor.
*/
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
{ {
if (test_thread_flag(TIF_FOREIGN_FPSTATE)) if (test_thread_flag(TIF_FOREIGN_FPSTATE))
...@@ -93,10 +98,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu) ...@@ -93,10 +98,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
} }
/* /*
* If the guest FPSIMD state was loaded, update the host's context * Called just after exiting the guest. If the guest FPSIMD state
* tracking data mark the CPU FPSIMD regs as dirty and belonging to vcpu * was loaded, update the host's context tracking data mark the CPU
* so that they will be written back if the kernel clobbers them due to * FPSIMD regs as dirty and belonging to vcpu so that they will be
* kernel-mode NEON before re-entry into the guest. * written back if the kernel clobbers them due to kernel-mode NEON
* before re-entry into the guest.
*/ */
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
{ {
......
...@@ -173,6 +173,8 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code) ...@@ -173,6 +173,8 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
return false; return false;
/* Valid trap. Switch the context: */ /* Valid trap. Switch the context: */
/* First disable enough traps to allow us to update the registers */
if (has_vhe()) { if (has_vhe()) {
reg = CPACR_EL1_FPEN; reg = CPACR_EL1_FPEN;
if (sve_guest) if (sve_guest)
...@@ -188,11 +190,13 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code) ...@@ -188,11 +190,13 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
} }
isb(); isb();
/* Write out the host state if it's in the registers */
if (vcpu->arch.flags & KVM_ARM64_FP_HOST) { if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
__fpsimd_save_state(vcpu->arch.host_fpsimd_state); __fpsimd_save_state(vcpu->arch.host_fpsimd_state);
vcpu->arch.flags &= ~KVM_ARM64_FP_HOST; vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
} }
/* Restore the guest state */
if (sve_guest) if (sve_guest)
__hyp_sve_restore_guest(vcpu); __hyp_sve_restore_guest(vcpu);
else else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册