Commit beed0906 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: Trap host SVE accesses when the FPSIMD state is dirty



ZCR_EL2 controls the upper bound for ZCR_EL1, and is set to
a potentially lower limit when the guest uses SVE. In order
to restore the SVE state on the EL1 host, we must first
reset ZCR_EL2 to its original value.

To make it as lazy as possible on the EL1 host side, set
the SVE trapping in place when exiting from the guest.
On the first EL1 access to SVE, ZCR_EL2 will be restored
to its full glory.

Suggested-by: default avatarAndrew Scull <ascull@google.com>
Acked-by: default avatarWill Deacon <will@kernel.org>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent b145a843
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -177,6 +177,10 @@ void handle_trap(struct kvm_cpu_context *host_ctxt)
	case ESR_ELx_EC_SMC64:
		handle_host_smc(host_ctxt);
		break;
	case ESR_ELx_EC_SVE:
		sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2);
		sysreg_clear_set(cptr_el2, CPTR_EL2_TZ, 0);
		break;
	default:
		hyp_panic();
	}
+7 −2
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
static void __deactivate_traps(struct kvm_vcpu *vcpu)
{
	extern char __kvm_hyp_host_vector[];
	u64 mdcr_el2;
	u64 mdcr_el2, cptr;

	___deactivate_traps(vcpu);

@@ -101,7 +101,12 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
		write_sysreg(HCR_HOST_NVHE_PROTECTED_FLAGS, hcr_el2);
	else
		write_sysreg(HCR_HOST_NVHE_FLAGS, hcr_el2);
	write_sysreg(CPTR_EL2_DEFAULT, cptr_el2);

	cptr = CPTR_EL2_DEFAULT;
	if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED))
		cptr |= CPTR_EL2_TZ;

	write_sysreg(cptr, cptr_el2);
	write_sysreg(__kvm_hyp_host_vector, vbar_el2);
}