1

I have a Windows guest OS installed under QEMU kvm (host is Linux), the system works fine, but

Both task manager and systeminfo showed that Hyper-V is supported but disabled in firmware, how can I enable it?

How can I enable it, with OVMF UEFI setup or with QEMU commandline args, so I can have nested virtual environment (like the builtin sandbox powered by Hyper-V)?


I have kvm_intel nested=1 configured as said in https://superuser.com/a/1100299/1060857 and my host machine reports nested virtualization is supported:

$ cat /sys/module/kvm_intel/parameters/nested
Y

$ virt-host-validate 
  QEMU: Checking for hardware virtualization                                 : PASS
  QEMU: Checking if device /dev/kvm exists                                   : PASS
  QEMU: Checking if device /dev/kvm is accessible                            : PASS
  QEMU: Checking if device /dev/vhost-net exists                             : PASS
  QEMU: Checking if device /dev/net/tun exists                               : PASS
  QEMU: Checking for cgroup 'memory' controller support                      : PASS
  QEMU: Checking for cgroup 'memory' controller mount-point                  : PASS
  QEMU: Checking for cgroup 'cpu' controller support                         : PASS
  QEMU: Checking for cgroup 'cpu' controller mount-point                     : PASS
  ... (all PASS)

If i use same VM to boot a Ubuntu live cd, virtualization seems already enabled (in the guest):

(guest)$ lscpu | grep -i Virtualiz
Virtualization:                  VT-x

(guest)$ lscpu | grep vmx | grep lm
Flags:                           fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl cpuid pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 xsaves arat

(guest)$ cpu-checker
INFO: /dev/kvm exists
KVM acceleration can be used

Related configuration

virsh xml:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>Windows-Server-2022</name>
  <uuid>...</uuid>
  <memory unit='KiB'>12582912</memory>
  <currentMemory unit='KiB'>12582912</currentMemory>
  <vcpu placement='static'>6</vcpu>
  <os>
    <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
    <loader type='rom'>/usr/share/OVMF/OVMF_CODE.fd</loader>
    <nvram template='/usr/share/OVMF/OVMF_VARS.fd'/>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
    </hyperv>
    <kvm>
      <hidden state='on'/>
    </kvm>
  </features>
  <cpu mode='host-passthrough'>
    <topology sockets='1' cores='3' threads='2'/>
    <feature policy='require' name='kvm'/>
    <feature policy='require' name='vmx'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/kvm-spice</emulator>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/home/ken/Downloads/SERVER_EVAL_x64FRE_zh-cn.iso'/>
      <target dev='hdb' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/home/ken/Downloads/virtio-win-0.1.217.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' target='0' unit='0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/media/vm0/windows-server/windows-server.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='pci' index='1' model='pci-bridge'>
      <model name='pci-bridge'/>
      <target chassisNr='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </controller>
    <controller type='pci' index='2' model='pci-bridge'>
      <model name='pci-bridge'/>
      <target chassisNr='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </controller>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:9a:31:b7'/>
      <source network='nat_win10'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='spice' port='5910' autoport='no'>
      <image compression='off'/>
    </graphics>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x01' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x02' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x2'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x03' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x3'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x04' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
    </hostdev>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/>
    </memballoon>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-cpu'/>
    <qemu:arg value='host,hv_time,kvm=off,hv_vendor_id=1234567890ab,hv_vendor_id=null,-hypervisor,hypervisor=off'/>
  </qemu:commandline>
</domain>


Not a duplicate: Hyper-V Virtualisation Disabled in Firmware since what I'm aiming to is enable Hyper-V on a guest OS not on host machine.

imkzh
  • 121
  • 1
  • 6
  • Some older version of qemu might requires you to add something like `kvm=off` and/or `hypervisor=on` to `-cpu host`. But yesterday I checked with qemu 7.0.0 it works out of the box with just `-cpu host` (well I do have some of the `hv-` optimizations set as well but most likely they aren't relevant. – Tom Yan Apr 25 '22 at 06:37
  • @TomYan I have just updated my post adding some detail of my configurations, I do have `kvm=off` and `cpu=host`, but I have no `hypervisor=on`, is it the problem? – imkzh Apr 25 '22 at 06:41
  • TIAS. I only faintly remember that I used `hypervisor=on` for certain thing, but I am not sure whether it was nested virtualization. Also make sure you double check with `cat /sys/module/kvm_intel/parameters/nested` – Tom Yan Apr 25 '22 at 06:45
  • @TomYan Tried append `hypervisor=on` to `-cpu host`, and Hyper-V is still supported but not enabled. Double checked `nested` is `Y`. – imkzh Apr 25 '22 at 07:17

1 Answers1

1

According to the article Nested Virtualization - Hyper-V 2019 in qemu-kvm, this must be specified in the VMX configuration file:

 <features>
    <acpi/>
    <apic/>
    <pae/>
    <hyperv>
      <synic state='on'/>
    </hyperv>
  </features>
  <cpu mode='custom' match='exact' check='partial'>
    <model fallback='allow'>Skylake-Server-noTSX-IBRS</model>
    <feature policy='disable' name='hypervisor'/>
    <feature policy='require' name='vmx'/>
  </cpu>
  <clock offset='utc' />

You will find in the article explanations of why Synthetic Interrupt Controller (SynIC) is required, and why noTSX in the CPU model.

The article remarks that on some computers the tag <synic state='on'/> is not required, so you could try without it.

harrymc
  • 455,459
  • 31
  • 526
  • 924
  • @imkzh Sounds like it's `hypervisor=off` instead of `hypervisor=on` that is needed. – Tom Yan Apr 25 '22 at 10:04
  • Not so sure you want `offset='utc'` (but instead, `offset='localtime'`, maybe). – Tom Yan Apr 25 '22 at 10:06
  • libvirt don't allow me to set ``: `XML document failed to validate against schema: Unable to validate doc against /usr/share/libvirt/schemas/domain.rng` `Extra element features in interleave` `Element domain failed to validate content` – imkzh Apr 25 '22 at 12:00
  • @TomYan tried `hypervisor=off` still not working, should i remove `-hypervisor` (in `-cpu` options)? – imkzh Apr 25 '22 at 12:01
  • Thank you for your answer, tried `` not working. I updated the original post with full virsh xml. – imkzh Apr 25 '22 at 12:06
  • Finally installed WSL on a Windows 11 guest running on an Ubuntu 22.04, with this guide. – Alireza Ghasemi Nov 02 '22 at 11:00