|
@@ -612,7 +612,13 @@ struct vcpu_vmx {
|
|
|
u32 guest_pkru;
|
|
|
u32 host_pkru;
|
|
|
|
|
|
+ /*
|
|
|
+ * Only bits masked by msr_ia32_feature_control_valid_bits can be set in
|
|
|
+ * msr_ia32_feature_control. FEATURE_CONTROL_LOCKED is always included
|
|
|
+ * in msr_ia32_feature_control_valid_bits.
|
|
|
+ */
|
|
|
u64 msr_ia32_feature_control;
|
|
|
+ u64 msr_ia32_feature_control_valid_bits;
|
|
|
};
|
|
|
|
|
|
enum segment_cache_field {
|
|
@@ -2929,6 +2935,14 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
|
|
|
+ uint64_t val)
|
|
|
+{
|
|
|
+ uint64_t valid_bits = to_vmx(vcpu)->msr_ia32_feature_control_valid_bits;
|
|
|
+
|
|
|
+ return !(val & ~valid_bits);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Reads an msr value (of 'msr_index') into 'pdata'.
|
|
|
* Returns 0 on success, non-0 otherwise.
|
|
@@ -3062,7 +3076,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
|
|
ret = kvm_set_msr_common(vcpu, msr_info);
|
|
|
break;
|
|
|
case MSR_IA32_FEATURE_CONTROL:
|
|
|
- if (!nested_vmx_allowed(vcpu) ||
|
|
|
+ if (!vmx_feature_control_msr_valid(vcpu, data) ||
|
|
|
(to_vmx(vcpu)->msr_ia32_feature_control &
|
|
|
FEATURE_CONTROL_LOCKED && !msr_info->host_initiated))
|
|
|
return 1;
|
|
@@ -9055,6 +9069,8 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
|
|
goto free_vmcs;
|
|
|
}
|
|
|
|
|
|
+ vmx->msr_ia32_feature_control_valid_bits = FEATURE_CONTROL_LOCKED;
|
|
|
+
|
|
|
return &vmx->vcpu;
|
|
|
|
|
|
free_vmcs:
|
|
@@ -9202,6 +9218,13 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
|
|
vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
|
~SECONDARY_EXEC_PCOMMIT;
|
|
|
}
|
|
|
+
|
|
|
+ if (nested_vmx_allowed(vcpu))
|
|
|
+ to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
|
|
|
+ FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
|
|
+ else
|
|
|
+ to_vmx(vcpu)->msr_ia32_feature_control_valid_bits &=
|
|
|
+ ~FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
|
|
}
|
|
|
|
|
|
static void vmx_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
|