|
@@ -846,6 +846,13 @@ struct nested_vmx {
|
|
|
|
|
|
bool change_vmcs01_virtual_apic_mode;
|
|
|
|
|
|
+ /*
|
|
|
+ * Enlightened VMCS has been enabled. It does not mean that L1 has to
|
|
|
+ * use it. However, VMX features available to L1 will be limited based
|
|
|
+ * on what the enlightened VMCS supports.
|
|
|
+ */
|
|
|
+ bool enlightened_vmcs_enabled;
|
|
|
+
|
|
|
/* L2 must run next, and mustn't decide to exit to L1. */
|
|
|
bool nested_run_pending;
|
|
|
|
|
@@ -1589,6 +1596,34 @@ static inline void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) {}
|
|
|
static inline void evmcs_touch_msr_bitmap(void) {}
|
|
|
#endif /* IS_ENABLED(CONFIG_HYPERV) */
|
|
|
|
|
|
+static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
|
|
|
+ uint16_t *vmcs_version)
|
|
|
+{
|
|
|
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
|
+
|
|
|
+ /* We don't support disabling the feature for simplicity. */
|
|
|
+ if (vmx->nested.enlightened_vmcs_enabled)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ vmx->nested.enlightened_vmcs_enabled = true;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * vmcs_version represents the range of supported Enlightened VMCS
|
|
|
+ * versions: lower 8 bits is the minimal version, higher 8 bits is the
|
|
|
+ * maximum supported version. KVM supports versions from 1 to
|
|
|
+ * KVM_EVMCS_VERSION.
|
|
|
+ */
|
|
|
+ *vmcs_version = (KVM_EVMCS_VERSION << 8) | 1;
|
|
|
+
|
|
|
+ vmx->nested.msrs.pinbased_ctls_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
|
|
|
+ vmx->nested.msrs.entry_ctls_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
|
|
|
+ vmx->nested.msrs.exit_ctls_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
|
|
|
+ vmx->nested.msrs.secondary_ctls_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC;
|
|
|
+ vmx->nested.msrs.vmfunc_controls &= ~EVMCS1_UNSUPPORTED_VMFUNC;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static inline bool is_exception_n(u32 intr_info, u8 vector)
|
|
|
{
|
|
|
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
|
|
@@ -14505,6 +14540,8 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
|
|
|
.pre_enter_smm = vmx_pre_enter_smm,
|
|
|
.pre_leave_smm = vmx_pre_leave_smm,
|
|
|
.enable_smi_window = enable_smi_window,
|
|
|
+
|
|
|
+ .nested_enable_evmcs = nested_enable_evmcs,
|
|
|
};
|
|
|
|
|
|
static void vmx_cleanup_l1d_flush(void)
|