From 379bcf45dffb96aa8452920092bc09b0d1f0bdd8 Mon Sep 17 00:00:00 2001 From: Fuad Tabba Date: Thu, 12 Dec 2024 10:29:22 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Do not clear the SVE feature bit on failure Since Linux 6.12, SVE is a VM feature and not a VCPU feature. Instead of clearning the per-VCPU SVE bits on failure, set them once SVE has been finalized for the VCPU. Bug: 357781595 Change-Id: Id8a57ce589cdcae20906e959134e77cac7219a1f Signed-off-by: Fuad Tabba --- arch/arm64/kvm/hyp/nvhe/pkvm.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index fe759a25767d..68c5c98a89d4 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -574,51 +574,42 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *h unsigned int sve_max_vl; size_t sve_state_size; void *sve_state; - int ret = 0; - if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) { - vcpu_clear_flag(vcpu, GUEST_HAS_SVE); - vcpu_clear_flag(vcpu, VCPU_SVE_FINALIZED); + if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) return 0; - } /* Limit guest vector length to the maximum supported by the host. */ sve_max_vl = min(READ_ONCE(host_vcpu->arch.sve_max_vl), kvm_host_sve_max_vl); sve_state_size = sve_state_size(sve_max_vl); sve_state = kern_hyp_va(READ_ONCE(host_vcpu->arch.sve_state)); - if (!sve_state && !pkvm_hyp_vcpu_is_protected(hyp_vcpu)) { - ret = -EINVAL; - goto err; - } + if (!sve_state && !pkvm_hyp_vcpu_is_protected(hyp_vcpu)) + return -EINVAL; - if (!sve_state_size || (sve_max_vl > kvm_sve_max_vl)) { - ret = -EINVAL; - goto err; - } + if (!sve_state_size || (sve_max_vl > kvm_sve_max_vl)) + return -EINVAL; if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) { struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu); sve_state = hyp_alloc_account(sve_state_size, hyp_vm->host_kvm); - if (!sve_state) { - ret = hyp_alloc_errno(); - goto err; - } + if (!sve_state) + return hyp_alloc_errno(); } else { + int ret; + ret = hyp_pin_shared_mem(sve_state, sve_state + sve_state_size); if (ret) - goto err; + return ret; } vcpu->arch.sve_state = sve_state; vcpu->arch.sve_max_vl = sve_max_vl; + vcpu_set_flag(vcpu, GUEST_HAS_SVE); + vcpu_set_flag(vcpu, VCPU_SVE_FINALIZED); return 0; -err: - clear_bit(KVM_ARM_VCPU_SVE, vcpu->kvm->arch.vcpu_features); - return ret; } static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,