Build An Accelerated KVM Guest Custom Kernel for WSL 2 - 2022 Edition
Updated, simpler guide for building a custom Linux kernel for WSL 2 optimized for running nested KVM guests.
This guide walks you through the process of building a basic accelerated KVM custom kernel for WSL 2 that can be used with any WSL 2 distro you have installed.
This guide has been updated and simplified.
Requirements
Windows 11, build 22000+
WSL 2
OpenSUSE Tumbleweed
This guide works with Intel and AMD processors
Update openSUSE and install build dependencies
Run:
sudo zypper -n up
sudo bash -c "zypper in -y -t pattern devel_basis && zypper in -y bc openssl openssl-devel dwarves rpm-build libelf-devel aria2 jq"
Get the Microsoft WSL 2 kernel sources
Run:
curl -s https://api.github.com/repos/microsoft/WSL2-Linux-Kernel/releases/latest | jq -r '.name' | sed 's/$/.tar.gz/' | sed 's#^#https://github.com/microsoft/WSL2-Linux-Kernel/archive/refs/tags/#' | aria2c -i -
tar -xf *.tar.gz
Change to the kernel directory
Run:
cd "$(find -type d -name "WSL2-Linux-Kernel-linux-msft-wsl-*")"
Copy the default Microsoft kernel configuration
Run:
cp Microsoft/config-wsl .config
Tweak the default Microsoft kernel configuration for KVM guests
The following tweaks are based on kernel version 5.14.
Run:
sed -i 's/# CONFIG_KVM_GUEST is not set/CONFIG_KVM_GUEST=y/g' .config
sed -i 's/# CONFIG_ARCH_CPUIDLE_HALTPOLL is not set/CONFIG_ARCH_CPUIDLE_HALTPOLL=y/g' .config
sed -i 's/# CONFIG_HYPERV_IOMMU is not set/CONFIG_HYPERV_IOMMU=y/g' .config
sed -i '/^# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set/a CONFIG_PARAVIRT_CLOCK=y' .config
sed -i '/^# CONFIG_CPU_IDLE_GOV_TEO is not set/a CONFIG_CPU_IDLE_GOV_HALTPOLL=y' .config
sed -i '/^CONFIG_CPU_IDLE_GOV_HALTPOLL=y/a CONFIG_HALTPOLL_CPUIDLE=y' .config
sed -i 's/CONFIG_HAVE_ARCH_KCSAN=y/CONFIG_HAVE_ARCH_KCSAN=n/g' .config
sed -i '/^CONFIG_HAVE_ARCH_KCSAN=n/a CONFIG_KCSAN=n' .config
Build the kernel
Run:
make -j 8
Copy the built kernel to your Windows user's home folder
From WSL:
powershell.exe /C 'Copy-Item .\arch\x86\boot\bzImage $env:USERPROFILE'
Point to your custom kernel in .wslconfig
From WSL:
powershell.exe /C 'Write-Output [wsl2]`nkernel=$env:USERPROFILE\bzImage | % {$_.replace("\","\\")} | Out-File $env:USERPROFILE\.wslconfig -encoding ASCII'
Restart WSL
Open a PowerShell terminal and run:
wsl.exe --shutdown
Confirm you are booting your custom kernel
Confirm you are running your new kernel by checking the date, which should be very recent. Run:
wsl.exe uname -a
Congrats, your WSL 2 kernel is now optimized for KVM guests.
Now...what are you going to run with that?