Tuesday, December 24, 2019

Nested Virtualization: Hyper-V guest on Linux KVM host

Posting this because I couldn't find anything in one place detailing how to do this configuration.

If you are running a Windows 10 guest on a Linux KVM virtualization host, you'll find that nested virtualization with Hyper-V is disabled by Windows. This is despite the nested flag for your kvm_intel or kvm_amd module being set to Y.

The reason for this? Windows disables its own virtualization support if it sees that it's running on a CPU which has the hypervisor flag set.

Assuming you're using libvirt, i.e. you manage your guests with virsh or virt-manager, the way you configure this on a per-guest basis is by disabling the hypervisor feature flag. Run:

virsh edit GUEST

which will allow you to edit the guest config as an XML file. Modify the CPU section as follows:

  <cpu mode='host-model' check='partial'>
    <model fallback='allow'/>
    <feature policy='disable' name='hypervisor'/>
  </cpu>

By setting the disable policy for the hypervisor flag, the CPU will no longer advertise that it's a guest running in a hypervisor environment. Assuming you already have nested virtualization enabled globally (set to Y in /sys/module/kvm_intel/parameters/nested) this will allow Windows 10 to at least try to enable Hyper-V.

There are still plenty of ways that the guest can determine it's being virtualized (e.g. looking for paravirtualized devices, or vendor strings on devices such as the emulated disks). However, this flag is what Hyper-V looks for to determine whether it should try to run, if all other hardware requirements are met.