Implement kvm/qemu Windows 11 virtual machine on a dual boot computer

Hello Everyone,

I have an Asus ProArt 16 laptop with two 2 TB nvme SSDs and 32 GiB ram set up to dual boot into Fedora 42 and Windows 11. Windows lives on the SSD that originally came with the computer and Fedora runs from an SSD I added later. Dual booting works well. Grub2 got installed on the Fedora SSD, which has first boot priority in the UEFI firmware settings, and both Fedora and Windows boot and run without a problem. I’m trying to set up a Windows qemu/kvm virtual machine using the Windows SSD as a raw disk, but I cannot get the virtual machine to boot. I’d greatly appreciate some help finding out what’s wrong.

In creating the virtual machine on Virtual Machine Manager, I choose “manual install,” specifying /dev/disk/by-id/ as the source for the Windows boot disk device. I did this because I had read that this was the correct way to pass the physical disk block device to the VM for its use. When I tried this, the VM displayed the grub2> command line prompt. I believe this was because I had installed Fedora on the same SSD as Windows shortly after I got the computer, so Grub2 got installed on the Windows SSD’s ESP partition and a Grub2 bootloader remained there after I installed the second SSD and installed Fedora and Grub2 there. I then entered on the Grub2 command line the series of commands loading modules and ending with “boot” invoked when the Windows Grub menu item gets selected in the hope that would get Windows to boot. No luck. Nothing happened after I entered “boot” on the Grub2 command line.

I then tried to remove everything Grub2 had put into the ESP partition of the Windows SSD, hoping that this would cause the VM to avoid Grub2 and boot straight into Windows. I removed everything from the EFI directory except the Boot and Microsoft directories. When I then started the VM, it opened with a black screen, briefly displayed the TianoCore logo, then displayed a blue window with the message “Press any key to stop system reset” in the center with a 5 second countdown timer in the lower left corner. When the timer expired, the black screen and TianoCore logo reappeared followed by the same blue window, “Press any key” message, and countdown timer. Pressing a key to stop the reset presented a blue window entitled “Boot Option Restored” with a menu of three choices: Reset System, Continue boot, and Always continue boot. Continuing the boot resulted in the same “Press any key to stop reset” message. I feared that I might have damaged the Windows boot setup, but Windows booted normally from the Grub2 menu.

As a sanity check, I gave the Windows SSD boot priority in the UEFI firmware settings and the computer booted straight into Windows. I then tried Windows’ recovery and startup repair tools, but they reported that they could not repair the startup files (presumably because they weren’t broken).

I’ve also tried identifying the Windows SSD in alternative ways, using additional ids provided in the /dev/disk/by-id directory and also by using the nvme1n1 identifier assigned to it at that time, but that also failed in the same way. I also tried giving the VM the path to the ESP partition only on the Windows SSD, but that also failed in the same manner.

Obviously, the VM I’m trying to set up is simply not finding the Windows OS. I can’t think of anything else to try, so I hope someone reading this will have some suggestions. Thanks to all of you who’ve taken the time to read this far!

Darron

Hey,
Is there any chance you are missing some virtual devices? Windows is somewhat picky and so far I only managed to install it into a VM after changed a couple registry keys.

Don’t know if it helps but for reference here’s libvirt xml of a machine where windows boots for me:

<domain type='kvm'>
  <name>Windows</name>
  <uuid>fce42ad1-3592-466a-80ea-ce63c2e900bc</uuid>
  <title>Windows</title>
  <memory unit='KiB'>31250000</memory>
  <currentMemory unit='KiB'>31250000</currentMemory>
  <memoryBacking>
    <source type='memfd'/>
    <access mode='shared'/>
  </memoryBacking>
  <vcpu placement='static'>12</vcpu>
  <iothreads>1</iothreads>
  <cputune>
    <vcpupin vcpu='0' cpuset='1'/>
    <vcpupin vcpu='1' cpuset='2'/>
    <vcpupin vcpu='2' cpuset='3'/>
    <vcpupin vcpu='3' cpuset='4'/>
    <vcpupin vcpu='4' cpuset='5'/>
    <vcpupin vcpu='5' cpuset='6'/>
    <vcpupin vcpu='6' cpuset='7'/>
    <vcpupin vcpu='7' cpuset='9'/>
    <vcpupin vcpu='8' cpuset='10'/>
    <vcpupin vcpu='9' cpuset='11'/>
    <emulatorpin cpuset='0,8'/>
    <iothreadpin iothread='1' cpuset='0,8'/>
  </cputune>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-q35-9.1'>hvm</type>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv mode='custom'>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
      <vpindex state='on'/>
      <runtime state='on'/>
      <synic state='on'/>
      <stimer state='on'/>
      <frequencies state='on'/>
      <tlbflush state='on'/>
      <ipi state='on'/>
    </hyperv>
    <vmport state='off'/>
    <ioapic driver='kvm'/>
  </features>
  <cpu mode='host-passthrough' check='full' migratable='on'>
    <topology sockets='1' dies='1' clusters='1' cores='6' threads='2'/>
  </cpu>
  <clock offset='localtime'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <timer name='hypervclock' present='yes'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <on_lockfailure>ignore</on_lockfailure>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='volume' device='disk' snapshot='internal'>
      <driver name='qemu' type='qcow2'/>
      <source pool='default' volume='windows'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </disk>
    <disk type='volume' device='cdrom' snapshot='internal'>
      <driver name='qemu' type='raw'/>
      <source pool='default' volume='virtio-win-0.1.271.iso'/>
      <backingStore/>
      <target dev='sdb' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x8'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-to-pci-bridge'>
      <model name='pcie-pci-bridge'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x9'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0xa'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <controller type='pci' index='5' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='5' port='0xb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
    </controller>
    <controller type='pci' index='6' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='6' port='0xc'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x4'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </controller>
    <controller type='scsi' index='0' model='lsilogic'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0'/>
    </controller>
    <controller type='usb' index='0' model='qemu-xhci'>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:d5:af:52'/>
      <source network='default'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='2'/>
    </channel>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <input type='tablet' bus='virtio'>
      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
    </input>
    <tpm model='tpm-crb'>
      <backend type='emulator' version='2.0'>
        <profile name='default-v1'/>
      </backend>
    </tpm>
    <graphics type='spice'>
      <listen type='socket'/>
      <image compression='quic'/>
      <jpeg compression='always'/>
      <zlib compression='always'/>
      <playback compression='on'/>
      <streaming mode='filter'/>
      <mouse mode='server'/>
      <clipboard copypaste='yes'/>
      <filetransfer enable='yes'/>
      <gl enable='yes' rendernode='/dev/dri/renderD128'/>
    </graphics>
    <sound model='ich9'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    <audio id='1' type='spice'/>
    <video>
      <model type='virtio' vram='2097152' heads='1' primary='yes'>
        <acceleration accel3d='yes'/>
      </model>
      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
    </video>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='2.1'/>
    </redirdev>
    <redirdev bus='usb' type='spicevmc'>
      <address type='usb' bus='0' port='2.2'/>
    </redirdev>
    <hub type='usb'>
      <address type='usb' bus='0' port='2'/>
    </hub>
    <watchdog model='itco' action='reset'/>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
    </memballoon>
    <rng model='virtio'>
      <backend model='random'>/dev/urandom</backend>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </rng>
  </devices>
  <seclabel type='dynamic' model='selinux' relabel='yes'/>
  <seclabel type='dynamic' model='dac' relabel='yes'/>
</domain>

I don’t have a second disk to try but I’d expect that replacing the main disk here with a host device that also carries a <boot order='1'/> should work.

Btw: As you maybe noticed there’s a second disk attached with a virtio-win.iso, which provide the necessary drivers for it to work, maybe you could try installing those first before trying to boot it as a VM. You can find them here.

Thanks for the suggestions! I’ll give them a try and see what happens. Missing drivers are a very likely suspect. I appreciate you taking the time to read through my post and giving it your attention.

Darron