I was able to run virtual machines on a WSL2 guest on Windows 10 via /dev/kvm in a nested configuration.

Environment

  • Windows 10 Pro Insider Program (Dev Channel, OS Build 20246.1) 1
  • Guest on WSL2
    • Ubuntu 20.04.1 LTS (Focal Fossa)
    • Linux 4.19.128-microsoft-standard
    • Kernel parameters initrd=\initrd.img panic=-1 nr_cpus=4 swiotlb=force pty.legacy_count=0
    • QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.7)
  • Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz

Procedure

By adding the following settings to the WSL2 (Windows Subsystem for Linux 2) global configuration C:\Users\username\.wslconfig, nested virtualization support is enabled.

[wsl2]
nestedVirtualization=true

The blog post I referenced 2 introduced a procedure to rebuild the WSL2 guest kernel, but that wasn’t necessary this time. Simply setting nestedVirtualization=true was enough.

Verification Part.1

Run a cirros image on QEMU/KVM.

# Allow non-root users to use KVM
$ sudo chmod a+rw /dev/kvm

$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

# Get cirros image with cloud-init disabled
$ wget https://github.com/eprasad/virt-cirros/raw/master/virt-cirros-0.3.4-x86_64-disk.img
$ qemu-system-x86_64 -enable-kvm -hda ./virt-cirros-0.3.4-x86_64-disk.img -nographic -serial mon:stdio

$ lsof -p $(pgrep qemu) | grep kvm
qemu-syst 22812 bobuhiro11  mem       REG   0,12           13766 anon_inode:kvm-vcpu:0 (stat: No such file or directory)
qemu-syst 22812 bobuhiro11    9u      CHR 10,232      0t0  13769 /dev/kvm
qemu-syst 22812 bobuhiro11   11u  a_inode   0,12        0  13766 kvm-vm
qemu-syst 22812 bobuhiro11   12u  a_inode   0,12        0  13766 kvm-vcpu:0

Verification Part.2

Let’s verify with something other than QEMU. As an example, I’ll also try running the rust-vmm reference implementation 3 that I’ve been interested in lately.

$ git clone https://github.com/rust-vmm/vmm-reference.git
$ cd vmm-reference
$ cargo build
$ ./resources/kernel/make_busybox.sh
$ pytest tests/test_run_reference_vmm.py
============================================================================================================ test session starts ============================================================================================================
platform linux -- Python 3.8.5, pytest-6.1.2, py-1.9.0, pluggy-0.13.1
rootdir: /home/bobuhiro11/vmm-reference
collected 1 item

tests/test_run_reference_vmm.py .                                                                                                                                                                                                     [100%]

============================================================================================================= 1 passed in 2.30s =============================================================================================================

$ ./target/debug/vmm-reference --kernel path=./resources/kernel/vmlinux-hello-busybox,cmdline="console=ttyS0 pci=off",himem_start=1024 --memory mem_size_mib=1024 --vcpus num_vcpus=1

$ lsof -p $(pgrep vmm-reference) | grep kvm
vmm-refer 23670 bobuhiro11  mem       REG   0,12           13766 anon_inode:kvm-vcpu:0 (stat: No such file or directory)
vmm-refer 23670 bobuhiro11    3u      CHR 10,232      0t0  13769 /dev/kvm
vmm-refer 23670 bobuhiro11    4u  a_inode   0,12        0  13766 kvm-vm
vmm-refer 23670 bobuhiro11    6u  a_inode   0,12        0  13766 kvm-vcpu:0

This is a tangent, but if linking fails when executing make_busybox.sh, you can skip building some busybox tools.

$ git diff
diff --git resources/kernel/busybox_static_config resources/kernel/busybox_static_config
index eceb67f..6b14ed5 100644
--- resources/kernel/busybox_static_config
+++ resources/kernel/busybox_static_config
@@ -196,10 +196,10 @@ CONFIG_COMM=y
 CONFIG_CP=y
 CONFIG_FEATURE_CP_LONG_OPTIONS=y
 CONFIG_CUT=y
-CONFIG_DATE=y
-CONFIG_FEATURE_DATE_ISOFMT=y
+CONFIG_DATE=n
+CONFIG_FEATURE_DATE_ISOFMT=n
 # CONFIG_FEATURE_DATE_NANO is not set
-CONFIG_FEATURE_DATE_COMPAT=y
+CONFIG_FEATURE_DATE_COMPAT=n
 CONFIG_DD=y
 CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
 CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
@@ -630,7 +630,7 @@ CONFIG_FEATURE_MOUNT_OTHERTAB=y
 CONFIG_NSENTER=y
 CONFIG_FEATURE_NSENTER_LONG_OPTS=y
 CONFIG_PIVOT_ROOT=y
-CONFIG_RDATE=y
+CONFIG_RDATE=n
 CONFIG_RDEV=y
 CONFIG_READPROFILE=y
 CONFIG_REV=y
@@ -873,7 +873,7 @@ CONFIG_NC_EXTRA=y
 CONFIG_NETSTAT=y
 CONFIG_FEATURE_NETSTAT_WIDE=y
 CONFIG_FEATURE_NETSTAT_PRG=y
-CONFIG_NSLOOKUP=y
+CONFIG_NSLOOKUP=n
 CONFIG_NTPD=y
 CONFIG_FEATURE_NTPD_SERVER=y
 CONFIG_FEATURE_NTPD_CONF=y