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)
- 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
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.
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…