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 <tabba@google.com>
This commit is contained in:
Fuad Tabba
2024-12-12 10:29:22 +00:00
committed by Treehugger Robot
parent 4e88458f66
commit 379bcf45df
+12 -21
View File
@@ -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,