Commit 122733f3 authored by Marc Zyngier's avatar Marc Zyngier Committed by Junhao He
Browse files

KVM: arm64: Exclude host_fpsimd_state pointer from kvm_vcpu_arch

mainline inclusion
from mainline-v6.9-rc1
commit 51e09b5572d665645ce394f94f24a7d6ec32bda9
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8EC9K
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=51e09b5572d665645ce394f94f24a7d6ec32bda9



--------------------------------

As the name of the field indicates, host_fpsimd_state is strictly
a host piece of data, and we reset this pointer on each PID change.

So let's move it where it belongs, and set it at load-time. Although
this is slightly more often, it is a well defined life-cycle which
matches other pieces of data.

Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarJunhao He <hejunhao3@huawei.com>
parent c91def97
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -463,6 +463,7 @@ struct kvm_cpu_context {
 */
struct kvm_host_data {
	struct kvm_cpu_context host_ctxt;
	struct user_fpsimd_state *fpsimd_state;	/* hyp VA */

	/*
	 * host_debug_state contains the host registers which are
@@ -580,7 +581,6 @@ struct kvm_vcpu_arch {
	struct kvm_guest_debug_arch vcpu_debug_state;
	struct kvm_guest_debug_arch external_debug_state;

	struct user_fpsimd_state *host_fpsimd_state;	/* hyp VA */
	struct task_struct *parent_task;

	/* VGIC state */
+1 −2
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
	if (ret)
		return ret;

	vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd);

	/*
	 * We need to keep current's task_struct pinned until its data has been
	 * unshared with the hypervisor to make sure it is not re-used by the
@@ -87,6 +85,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
	 * FP_STATE_FREE if the flag set.
	 */
	vcpu->arch.fp_state = FP_STATE_HOST_OWNED;
	*host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);

	vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
+1 −1
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)

	/* Write out the host state if it's in the registers */
	if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED)
		__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
		__fpsimd_save_state(*host_data_ptr(fpsimd_state));

	/* Restore the guest state */
	if (sve_guest)
+0 −1
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
	hyp_vcpu->vcpu.arch.fp_state	= host_vcpu->arch.fp_state;

	hyp_vcpu->vcpu.arch.debug_ptr	= kern_hyp_va(host_vcpu->arch.debug_ptr);
	hyp_vcpu->vcpu.arch.host_fpsimd_state = host_vcpu->arch.host_fpsimd_state;

	hyp_vcpu->vcpu.arch.vsesr_el2	= host_vcpu->arch.vsesr_el2;