Reproducer: https://gist.github.com/Lichtso/167b0589602f516197aef0383eb7e50c Platform is macOS 10.15.7 on a Retina MacBook Pro (End 2012), Intel Core i5. The reported capabilities are:
HV_VMX_CAP_PINBASED: 0000007F0000003F
HV_VMX_CAP_PROCBASED: FDF9FFFE9500697A
HV_VMX_CAP_PROCBASED2: 000008EF000000A2
HV_VMX_CAP_ENTRY: 000093FF000091FF
HV_VMX_CAP_EXIT: 00636FFF00236FFF
The linked code starts a VM in 32bit protected mode, with segmentation, paging and the physical address extension active. In other words it is in a state where a normal OS could easily switch over into 64bit long mode, if it had access to the EFER MSR. But hv_vcpu_enable_native_msr
of VMCS_GUEST_IA32_EFER
fails so it has to be configured from the outside instead.
According to the Intel manual one should set VMEXIT_HOST_IA32E
in VMCS_CTRL_VMEXIT_CONTROLS
and VMENTRY_GUEST_IA32E
in VMCS_CTRL_VMENTRY_CONTROLS
. And set LMA
as well as LME
in VMCS_GUEST_IA32_EFER
.
https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3c-part-3-manual.html
However, VMENTRY_GUEST_IA32E
can not be set as it is not in the capabilities (how?) so it exits with VMX_REASON_VMENTRY_GUEST
. And even worse, setting LMA
in VMCS_GUEST_IA32_EFER
causes hv_vcpu_run()
to return immediately without any meaningful error message.
So, how does one get a 64bit VM on macOS with Intel?