}
/*
- * Initialize trap register values in protected mode.
+ * Check that cpu features that are neither trapped nor supported are not
+ * enabled for protected VMs.
*/
-static void pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
{
- struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
-
- vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
- vcpu->arch.mdcr_el2 = 0;
-
- pkvm_vcpu_reset_hcr(vcpu);
-
- if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
- return;
-
/*
* PAuth is allowed if supported by the system and the vcpu.
* Properly checking for PAuth requires checking various fields in
BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_AdvSIMD),
PVM_ID_AA64PFR0_ALLOW));
+ return 0;
+}
+
+/*
+ * Initialize trap register values in protected mode.
+ */
+static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
+{
+ struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
+ int ret;
+
+ vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
+ vcpu->arch.mdcr_el2 = 0;
+
+ pkvm_vcpu_reset_hcr(vcpu);
+
+ if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu)))
+ return 0;
+
+ ret = pkvm_check_pvm_cpu_features(vcpu);
+ if (ret)
+ return ret;
+
pvm_init_traps_hcr(vcpu);
pvm_init_traps_cptr(vcpu);
pvm_init_traps_mdcr(vcpu);
+
+ return 0;
}
/*
hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
+ ret = pkvm_vcpu_init_traps(hyp_vcpu);
+ if (ret)
+ goto done;
+
pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
pkvm_vcpu_init_ptrauth(hyp_vcpu);
- pkvm_vcpu_init_traps(hyp_vcpu);
done:
if (ret)
unpin_host_vcpu(host_vcpu);