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.

Build An Accelerated KVM Guest Custom Kernel for WSL 2 - 2022 Edition

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"

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?