Hyper-V and hardware assisted virtualization
During one of my experiments with a virtual machine in Virtual Box running on Windows 8, I notice that the Acceleration tab of the System settings is grayed out:
A quick Google search reveals that this would only happen if the host machine processor does not support hardware-assisted virtualization. This is obviously not the case for me, since I am on a late-2012 Mac Mini with a Intel Core-i5 3210M CPU, which supports the VT-x instructions. However, I verified this using Intel Processor Identification Utility, CPU-Z 1.66 and SecurAble, with all returning the same disappointing result:
I rebooted my machine, which has been set up to triple boot Mac OS, Windows and Ubuntu Linux, to Mac OS and execute MacCPUID. Surprisingly, the tool reports the exact opposite – my CPU seems to support VT-x instructions:
So which tool is telling the truth? I know for one thing, my machine runs the Windows Phone 8 Emulator just fine. And since this emulator makes use of Hyper-V, which requires the CPU to support hardware virtualization (and possibly SLAT as well), my CPU must be fully virtualization capable.
In a last attempt at this issue, I turned off Hyper-V by executing the following and reboot:
bcdedit /set hypervisorlaunchtype off
Guess what, after a reboot, all tools now reported that my CPU is virtualization capable:
Turning Hyper-V on via the following command:
bcdedit /set hypervisorlaunchtype auto
and the CPU will appear not to support virtualization again! Something, possibly a driver loaded by Hyper-V has masked certain information and preventing these tools from detecting that the CPU is virtualization capable.
The Model Specific Register (MSR)
Some research reveals that virtualization support may be enabled or disabled by writing to the Model Specific Register (MSR) located at address 0x3A. This MSR contains the following three bits:
- Bit 0: lock bit
- Bit 1: activate VMXON in SMX mode
- Bit 2: activate VMXON outside of SMX mode
According to this website, the BIOS/EFI must set bits 1 and 2, or all three bits (including bit 0) so that VT-x support will be enabled. With Ubuntu 12.04 on my machine, installing the msr-tools package and executing the following command
rdmsr 0x3a
returns 5 indicating that virtualization is enabled. A value of 0 or 1 indicates that virtualization is disabled, in which case it can be enabled if it has not been locked (bit 0 is not set) by using the wrmsr command.
My guess is that a driver bundled with Hyper-V has written a value to this MSR to disable hardware virtualization. Since Hyper-V already knows that the machine supports virtualization, it proceeds to use the feature nevertheless. However, other tools simply read what the CPU reports and complains that virtualization is not supported. Some software such as VMware will automatically attempt to enable virtualization and makes use of it if the feature is not locked by the machine firmware and, for older versions of VMware, if the hv.enableIfUnlocked parameter in the .vmx file is set to TRUE.
Possible workarounds
Knowing the root cause of the problem, I proceeded to find tools to read/write MSR on Windows to change the value back to 5 and enable virtualization. Unfortunately such tools are hard to find since access to the MSR is limited to ring 0 (kernel-mode drivers) only on Windows. I found the following two applications – neither of which worked well:
- Performance Inspector: a package of several performance inspector tools. One of which is MSR which supports reading/writing to model-specific registers. Unfortunately this tool refuses to install on Windows 8. Attempting to set compatibility mode to Windows 7 allows the tool to be installed, but the driver perfdd-win7.sys fails to be loaded with error ‘The request is not supported‘. It could however be due to 32-bit/64-bit compatibility issues.
- RW-Everything: this tools appears to support reading/writing to the MSR. However, I could not locate the MSR register 0x3A to be edited among the list of MSR available:
Unless I could find another tool, the only possible way is to develop your own Windows tool to read/write the MSR. This would mean downloading the Windows Driver Kit and spend countless hours developing a kernel mode driver and an application to make use of the driver. The driver can then use the __readmsr and __writemsr methods to access the MSR values and setting the desired values. Obviously I am not going to attempt this – too much work to be done for too little value! Just disabling Hyper-V when there is a need for virtualization is sufficient for me.
Hardware virtualization on Mac systems
On a side note, the issue of hardware virtualization not being enabled by default seems to be a problem with earlier Mac Mini models. When this happens, you will need to use rEFIt to execute a custom EFI application that enables the feature. Before knowing that the problem was due to Hyper-V, I tried this on my Mac Mini and received an error “Image type IA32 is not supported by this X64 shell” because the EFI application was built for 32-bit Mac while my machine has 64-bit EFI, like most newer generation Macs.
On other Mac machines, hardware virtualization may be disabled by default, and can only be enabled by putting the machine to sleep for a few seconds and resuming it. On a multi-boot Mac system, if hardware virtualization appears to be enabled on Mac but not on Windows, try to start a Mac software that makes use of virtualization such as Parallels, and reboot the machine immediately to Windows without turning it off. According to this, the workaround will allow Windows to see that hardware virtualization is enabled and uses it. All these issues may be due to some bugs in the EFI booting process of the Mac that forgets to set the some required MSR bits.
Fortunately, my machine does not have these problems and hardware virtualization is always enabled natively, at least until Hyper-V is installed. I wonder why Hyper-V couldn’t just leave the virtualization features enabled and allow other applications to run peacefully? This question is for the engineers at Microsoft to answer…
Maybe too late, but… Intel apple systems boot with lock bit (bit 0) of 0x3a msr cleared. Hyper-v expects it set (and the bit 2 too) to declare a system hw-virt capable. You can try (cold) boot a linux usb key and execute:
wrmsr 0x3a 5
Reboot on windows and hyper-v will run without a hitch.
I am trying to develop a efi application to lock the bit before the windows bootloader but it hangs on the wrmsr instruction (rdmsr returns the current value flawlessly).
Hi,
Thanks for sharing. Actually the problem I encountered was that although my Mac Mini supports hardware virtualization (VT-X instructions) natively even on Windows without any need for modification and apps like VirtualBox or VMWare work without issues, these applications (and also sysinfo apps like CPU-Z etc) will report that hardware virtualization is not supported by the CPU if I install Hyper-V. Some driver conflict, I believe.
After writing this article I managed to find the option in RW-Everything to modify the 0x3a MSR register. Or so it seems. However, Windows shows a blue screen and hangs as soon as the changes are applied. My only resort now is to disable Hyper-V if I want to use VMWare or VirtualBox with virtualization support.
Let me know if you have any suggestions
Good news… I finished my patch to refind (a efi boot manager) and i will submit to its author. The modification adds a configuration option to enable and lock vmx before the execution of a bootloader. On my macbook air 2013 (windows 8.1 only), hyper-v works now even after a cold boot.
Hi,
That is good to hear Do let me know if there is a link to download your EFI application. Would love to see how it will work on my Macbook Air too. I have never tried Hyper-V on my macbook air due to limited space (it only has 128GB SSD dual booting both Windows 8 and Mac OS X).
My patch was accepted. Here is the link to the commit page: http://sourceforge.net/p/refind/code/ci/f27ce23381e3d1c3bc4f37d74fb6e70a3babc5dd/
You could get the source and compile yourself or could wait for Mr. Rod Smith release a new binary. I can email my patched refind.efi to you too, if you wish. You can contact me at emersonfxbx at gmail dot com.
Great, I will contact you via email. Thanks for sharing your work here – it will definitely help others
Hey, I found this website as a frustrated Windows user dealing with Hyper-V trapping wrmsr commands that I need for my application. If I am reading this correctly, you boot off an EFI application, and write to the registers prior to rebooting to Windows, and the registers stay intact and do not get overwritten on reboot?
Hi, it has been a while since I last tried it, but basically that’s the idea. You run the the EFI application (from a cold boot) to set the register values, which will remain intact when you reboot to Windows, and your hardware virtualization apps will work properly. The register values are only reset once you turn off computer.