Creating a Windows 10 Virtual Machine on Fedora 41 KDE Plasma

I am really struggling with this one and despite lots of reading feel quite out of my depth. I could do with some “next steps” to troubleshoot the problem issues encountered.

Reason:
I have a Plustek 8200i scanner that has no native Fedora (or any other) Linux drivers. I have a relatively fast PC (Core i7-7700K CPU @ 4.20GHz) plus 48Gb RAM and want to make use of this. I can use the Plustek scanner on an old Win 10 laptop but would like to use the linux box and hopefully, some shared (or access to) a common area of the SSD storage for completed scans - avoiding x-device transfers), I’m using latest Vuescan.

Checks:
I checked for VT-x. Processor is fine. In the BIOS I had to enable Virtualisation.

Installation:
I installed “Virtual Machine Manager” (VMM) as a flatpak (simply because it was there) and then installed libvirt:
$ sudo dnf install libvirt -y
It installed without error.
I could then create a connection for “QEMU/KVM” within VMM
I then tried to create a VM using a (Win10 ISO) within VMM
Errors were generated as below.

Errors:

Unable to complete install: 'internal error: Could not run '/usr/bin/swtpm_setup'. exitstatus: 1; Check error log '/var/log/swtpm/libvirt/qemu/win10-swtpm.log' for details.'

Traceback (most recent call last):
  File "/app/share/virt-manager/virtManager/asyncjob.py", line 71, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/share/virt-manager/virtManager/createvm.py", line 2008, in _do_async_install
    installer.start_install(guest, meter=meter)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "/app/share/virt-manager/virtinst/install/installer.py", line 726, in start_install
    domain = self._create_guest(
            guest, meter, initial_xml, final_xml,
            doboot, transient)
  File "/app/share/virt-manager/virtinst/install/installer.py", line 667, in _create_guest
    domain = self.conn.createXML(initial_xml or final_xml, 0)
  File "/app/lib64/python3.13/site-packages/libvirt.py", line 4545, in createXML
    raise libvirtError('virDomainCreateXML() failed')
libvirt.libvirtError: internal error: Could not run '/usr/bin/swtpm_setup'. exitstatus: 1; Check error log '/var/log/swtpm/libvirt/qemu/win10-swtpm.log' for details.

The file at /usr/bin/swtpm_setup exists.

The log file at ‘/var/log/swtpm/libvirt/qemu/win10-swtpm.log’ shows:
swtpm at /usr/bin/swtpm does not support TPM 2

I wonder if I missed a step… but not sure. This issue is also reported elsewhere but I don’t understand why TPM is an issue (Win 11 requires TPM also Secure Boot - but this is Win 10). I thought I’d seek advice before trying anything else. This bug report may be relevant but I just don’t see a resolution pathway:
https://bugzilla.redhat.com/show_bug.cgi?id=2278123

I’d appreciate any insights into what’s gone wrong, dependencies missed, misunderstandings, etc.
Thanks,
Ric

I don’t know what that swtpm_setup script is doing. Personally, I run qemu-system-x86_64 directly (well, via a small custom Bash script) and it starts Windows 10. FWIW, here is my script:

$ cat ~/bin/windows 
#!/usr/bin/bash

# The $PORT, $OVMF, $DISK, and $VTAP variables
# should be unique for each VM.
# You can make duplicate copies of this script
# to run each VM.
# Or you could rewrite this script to take the
# four values as parameters.

# spice port for graphics
PORT="5634"

OVMF="/opt/windows"
if ! [[ -e $OVMF ]]; then
	mkdir -p "$OVMF"
	for image in OVMF_{CODE,VARS}.fd; do
		cp "/usr/share/edk2/ovmf/$image" "$OVMF"
	done
fi

DISK="/dev/zd0"

VTAP="vtap0"
exec {fd}<>"/dev/tap$(</sys/class/net/$VTAP/ifindex)"

qemu-system-x86_64 \
	-name windows \
	-m 8g -cpu host -smp 4 \
	-machine type=q35,accel=kvm,vmport=off \
	-vga qxl \
	-display spice-app \
	-spice "disable-ticketing=on,addr=127.0.0.1,port=$PORT" \
	-chardev spicevmc,id=c1,name=vdagent \
	-netdev "tap,fd=$fd,id=$VTAP" \
	-device virtio-rng-pci \
	-device virtio-serial-pci \
	-device virtserialport,id=c1,chardev=c1,name=com.redhat.spice.0 \
	-device "virtio-net-pci,netdev=$VTAP,mac=$(</sys/class/net/$VTAP/address)" \
	-drive "if=pflash,format=raw,unit=0,file=$OVMF/OVMF_CODE.fd,readonly=on" \
	-drive "if=pflash,format=raw,unit=1,file=$OVMF/OVMF_VARS.fd" \
	-drive "file=$DISK,format=raw"

Additionally, I have two udev rules that grant my user access to the disk and network devices the Windows VM needs:

$ cat /etc/udev/rules.d/90-zvolume.rules
KERNEL=="zd[0-9]*", OWNER="glb", GROUP="disk", MODE="0660"
$ cat /etc/udev/rules.d/90-macvtap.rules 
SUBSYSTEM=="macvtap", OWNER="glb", GROUP="root", MODE="0660"

The network device (/dev/tap<N>) is created and managed by systemd-networkd:

$ cat /etc/systemd/network/00-vtap0.netdev 
[NetDev]
Name=vtap0
Kind=macvtap

[MACVTAP]
Mode=bridge
$ cat /etc/systemd/network/50-link0.network 
[Match]
PermanentMACAddress=70:b5:e8:21:c8:b3

[Link]
RequiredForOnline=carrier
ARP=off

[Network]
LinkLocalAddressing=false
MACVLAN=vlan0
MACVTAP=vtap0
$ cat /etc/systemd/network/90-vtap0.network
[Match]
Name=vtap0

[Link]
ActivationPolicy=always-up
RequiredForOnline=carrier

[Network]
LinkLocalAddressing=false
ConfigureWithoutCarrier=true
$ networkctl status vtap0
● 5: vtap0
                   Link File: /usr/lib/systemd/network/99-default.link
                Network File: /etc/systemd/network/90-vtap0.network
                       State: carrier (configured)
                Online state: online                                  
                        Type: ether
                        Kind: macvtap
                      Driver: macvlan
            Hardware Address: 32:72:45:8b:73:a7
                         MTU: 1500 (min: 68, max: 9000)
                       QDisc: fq_codel
IPv6 Address Generation Mode: none
                        Mode: bridge
    Number of Queues (Tx/Rx): 1/1
            Auto negotiation: yes
                       Speed: 1Gbps
                      Duplex: full
                        Port: tp
           Activation Policy: always-up
         Required For Online: yes
$ ls -al /dev/tap5
crw-rw----. 1 glb root 235, 1 Nov 27 16:54 /dev/tap5

The UEFI firmware is copied from /usr/share/edk2/ovmf (provided by the edk2-ovmf package):

$ ls -al /opt/windows
total 1482
drwxr-xr-x. 2 glb  glb        4 Aug 22 15:56 .
drwxr-xr-x. 8 root root       8 Sep 12 16:30 ..
-rw-r--r--. 1 glb  glb  1966080 Aug 22 15:56 OVMF_CODE.fd
-rw-r--r--. 1 glb  glb   131072 Jan  2 15:43 OVMF_VARS.fd
1 Like