diff --git a/Changelog.md b/Changelog.md
index fc611cb7ddef0e93760a72196b69e7df7a64891b..f8a63d8e4186e47912329d71280dcde674b85765 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -13,6 +13,7 @@ OpenCore Changelog
- Added `ReconnectGraphicsOnConnect` option for enabling alternative UEFI graphics drivers
- Added BiosVideo.efi driver to use with `ReconnectGraphicsOnConnect`
- Changed `FadtEnableReset` to avoid unreliable keyboard controller reset
+- Added `EnableVmx` quirk to allow virtualization in other OS on some Macs
#### v0.7.5
- Revised OpenLinuxBoot documentation
diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex
index c50dd7bb8670a6fe2aafb6151b775cf26954eecc..4c98948df4b03aec5b3341106dcfec62c394342d 100755
--- a/Docs/Configuration.tex
+++ b/Docs/Configuration.tex
@@ -7623,6 +7623,16 @@ with the boot menu.
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Enable AVX vector acceleration of SHA-512 and SHA-384 hashing algorithms.
+ \item
+ \texttt{EnableVmx}\\
+ \textbf{Type}: \texttt{plist\ boolean}\\
+ \textbf{Failsafe}: \texttt{false}\\
+ \textbf{Description}: Enable Intel virtual machine extensions.
+
+ \emph{Note}: Required to allow virtualization in Windows on some Mac hardware. VMX
+ is enabled or disabled and locked by BIOS before OpenCore starts on most
+ firmware. Use BIOS to enable virtualization where possible.
+
\item
\texttt{DisableSecurityPolicy}\\
\textbf{Type}: \texttt{plist\ boolean}\\
diff --git a/Docs/Sample.plist b/Docs/Sample.plist
index a43ace5f522a0a972bc5e063074a46fac4afa06c..b9fe594f9122ffd7477dae3ee7e920f1008aeafe 100644
--- a/Docs/Sample.plist
+++ b/Docs/Sample.plist
@@ -1564,6 +1564,8 @@
EnableVectorAcceleration
+ EnableVmx
+
ExitBootServicesDelay
0
ForceOcWriteFlash
diff --git a/Docs/SampleCustom.plist b/Docs/SampleCustom.plist
index e4992f0489401d7154aeb8b7bf9147fc4b0d3903..e54967a2531214e149c6a8cb08572bdb56fa3cd7 100644
--- a/Docs/SampleCustom.plist
+++ b/Docs/SampleCustom.plist
@@ -1902,6 +1902,8 @@
EnableVectorAcceleration
+ EnableVmx
+
ExitBootServicesDelay
0
ForceOcWriteFlash
diff --git a/Include/Acidanthera/Library/OcConfigurationLib.h b/Include/Acidanthera/Library/OcConfigurationLib.h
index b36facb9fea22eab3c78c24c00547d00d89957cd..038a93da1028e81694d02df6090d71b47141a523 100644
--- a/Include/Acidanthera/Library/OcConfigurationLib.h
+++ b/Include/Acidanthera/Library/OcConfigurationLib.h
@@ -691,6 +691,7 @@ typedef enum {
_(BOOLEAN , ActivateHpetSupport , , FALSE , ()) \
_(BOOLEAN , DisableSecurityPolicy , , FALSE , ()) \
_(BOOLEAN , EnableVectorAcceleration , , FALSE , ()) \
+ _(BOOLEAN , EnableVmx , , FALSE , ()) \
_(BOOLEAN , ForgeUefiSupport , , FALSE , ()) \
_(BOOLEAN , IgnoreInvalidFlexRatio , , FALSE , ()) \
_(INT8 , ResizeGpuBars , , -1 , ()) \
diff --git a/Include/Acidanthera/Library/OcCpuLib.h b/Include/Acidanthera/Library/OcCpuLib.h
index 01370c26e28fe9471e7b4bbecfaac6f7d391b98c..7335f1c81bd5fa76545f46439eeb2e59a3bee7c2 100755
--- a/Include/Acidanthera/Library/OcCpuLib.h
+++ b/Include/Acidanthera/Library/OcCpuLib.h
@@ -289,6 +289,19 @@ OcCpuCorrectFlexRatio (
IN OC_CPU_INFO *Cpu
);
+/**
+ Enable VMX in FeatureControl MSR if supported and not already locked by BIOS.
+ Required to use virtualization in Windows on some Mac hardware.
+
+ REF: https://github.com/acidanthera/bugtracker/issues/1870
+ REF: https://www.thomas-krenn.com/en/wiki/Activating_the_Intel_VT_Virtualization_Feature (via rEFInd)
+ REF: 'Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3', p.1296 etc.
+**/
+EFI_STATUS
+OcCpuEnableVmx (
+ VOID
+ );
+
/**
Synchronise TSC on all cores (needed on server chipsets and some laptops).
This does not fully replace VoodooTscSync or TSCAdjustReset due to
diff --git a/Library/OcConfigurationLib/OcConfigurationLib.c b/Library/OcConfigurationLib/OcConfigurationLib.c
index 6a08a441a644bd64ab36aecfe215bd94181f3540..a59cb1ce5fe1763a292199ecccb91d1f4e5375eb 100644
--- a/Library/OcConfigurationLib/OcConfigurationLib.c
+++ b/Library/OcConfigurationLib/OcConfigurationLib.c
@@ -686,6 +686,7 @@ mUefiQuirksSchema[] = {
OC_SCHEMA_BOOLEAN_IN ("ActivateHpetSupport", OC_GLOBAL_CONFIG, Uefi.Quirks.ActivateHpetSupport),
OC_SCHEMA_BOOLEAN_IN ("DisableSecurityPolicy", OC_GLOBAL_CONFIG, Uefi.Quirks.DisableSecurityPolicy),
OC_SCHEMA_BOOLEAN_IN ("EnableVectorAcceleration", OC_GLOBAL_CONFIG, Uefi.Quirks.EnableVectorAcceleration),
+ OC_SCHEMA_BOOLEAN_IN ("EnableVmx", OC_GLOBAL_CONFIG, Uefi.Quirks.EnableVmx),
OC_SCHEMA_INTEGER_IN ("ExitBootServicesDelay", OC_GLOBAL_CONFIG, Uefi.Quirks.ExitBootServicesDelay),
OC_SCHEMA_BOOLEAN_IN ("ForceOcWriteFlash", OC_GLOBAL_CONFIG, Uefi.Quirks.ForceOcWriteFlash),
OC_SCHEMA_BOOLEAN_IN ("ForgeUefiSupport", OC_GLOBAL_CONFIG, Uefi.Quirks.ForgeUefiSupport),
diff --git a/Library/OcCpuLib/OcCpuLib.c b/Library/OcCpuLib/OcCpuLib.c
index 7592541ec5d4948004f58be6f21f1c3cbd4e9e32..1c624f74c151060776398b9f0999eb6309068042 100755
--- a/Library/OcCpuLib/OcCpuLib.c
+++ b/Library/OcCpuLib/OcCpuLib.c
@@ -1163,6 +1163,34 @@ OcCpuCorrectFlexRatio (
}
}
+EFI_STATUS
+OcCpuEnableVmx (
+ VOID
+ )
+{
+ CPUID_VERSION_INFO_ECX RegEcx;
+ MSR_IA32_FEATURE_CONTROL_REGISTER Msr;
+
+ AsmCpuid (1, 0, 0, &RegEcx.Uint32, 0);
+ if (RegEcx.Bits.VMX == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
+ if (Msr.Bits.Lock != 0) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ //
+ // Unclear if pre-existing valid bits should ever be present if register is unlocked.
+ //
+ Msr.Bits.Lock = 1;
+ Msr.Bits.EnableVmxOutsideSmx = 1;
+ AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, Msr.Uint64);
+
+ return EFI_SUCCESS;
+}
+
STATIC
VOID
EFIAPI
diff --git a/Library/OcMainLib/OpenCoreUefi.c b/Library/OcMainLib/OpenCoreUefi.c
index c1058e36554688f184358123aaff2a9e5676cbea..91d00a9b1570b2dd2bfeb3120ae6bf35911ceb2b 100644
--- a/Library/OcMainLib/OpenCoreUefi.c
+++ b/Library/OcMainLib/OpenCoreUefi.c
@@ -816,6 +816,7 @@ OcLoadUefiSupport (
IN UINT8 *Signature
)
{
+ EFI_STATUS Status;
EFI_HANDLE *DriversToConnect;
EFI_EVENT Event;
BOOLEAN AvxEnabled;
@@ -841,6 +842,11 @@ OcLoadUefiSupport (
OcCpuCorrectFlexRatio (CpuInfo);
}
+ if (Config->Uefi.Quirks.EnableVmx) {
+ Status = OcCpuEnableVmx ();
+ DEBUG ((EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_INFO, "OC: Enable VMX - %r\n", Status));
+ }
+
if (Config->Uefi.Quirks.TscSyncTimeout > 0) {
OcCpuCorrectTscSync (CpuInfo, Config->Uefi.Quirks.TscSyncTimeout);
}