WSL2配置安装KVM

查看CPU是否支持硬件虚拟化

  使用命令:

egrep -c '(vmx|svm)' /proc/cpuinfo

  如果返回0则说明不支持,大于零则支持。支持可以直接进行下一步。
若不支持首先查看是否开启了硬件虚拟化,在任务管理器->性能中查看虚拟化是否已开启,如下图所示:
WSL2配置安装KVM_第1张图片

  若没有开启则需要重启进入BIOS将Intel® Virtualization Technology选为Enabled、Intel® VT-d Feature选为Enabled。
  当开启以上两个后,若WSL仍反映没有硬件虚拟化,则需要执行如下步骤,我们把这个步骤称为WinDbg步骤,请记住这个,因为这意味着,当你的WSL被shutdown后你每次都要执行该步骤以确保WSL下CPU硬件虚拟化的开启:
  在Microsoft shop下载这个:
WSL2配置安装KVM_第2张图片
  下载后将以下两个文件放在同一个目录下(这里感谢Steffengy):
run-start.bat

REM Ensure vmcompute.exe is running
wsl.exe -e true
REM Listen for and Intercept utility vm creation
start Windbgx.exe -pn vmcompute.exe -c "bp vmcompute!Marshal::JsonParser::JsonParser;g;.scriptrun %CD%\script.js;.scriptrun %CD%\script.js;.scriptrun %CD%\script.js;.detach;qq"
REM Ensure WSL Utility VM is not running (hopefully windb starts up fast enough...)
net stop LxssManager
net start LxssManager
echo "Press Enter if the debugger is running"
pause
REM Start WSL
start wsl.exe

script.js

"use strict";

function initializeScript()
{
    return [new host.apiVersionSupport(1, 3)];
}

function continueExecution() {
    var cmd = "g";
    host.diagnostics.debugLog(cmd);
    var lines = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmd)
    for (var line of lines) host.diagnostics.debugLog("  ", line, "\n");
}

function invokeScript()
{
    /* bp vmcompute!Marshal::JsonParser::JsonParser */

    var cmd;
    var lines;

    // 1. Check if WSL
    var magic = host.memory.readWideString(host.currentThread.Registers.User.rdx, 14);
    if (magic == '{"Owner":"WSL"') {
        host.diagnostics.debugLog("IS WSL\n");
    } else {
        host.diagnostics.debugLog("IS NOT WSL request\n");
        return continueExecution();
    }

    // dump length and read machine spec json
    var len = host.currentThread.Registers.User.r8;
    host.diagnostics.debugLog("String length: ", len, " dumping memory: ", host.currentThread.Registers.User.rdx, "\n");
    var jsonString = host.memory.readWideString(host.currentThread.Registers.User.rdx, len);
    host.diagnostics.debugLog("Before: ", jsonString, "\n");

    // parse and modify machine spec json
    var machineSpec = JSON.parse(jsonString);
    machineSpec.VirtualMachine.ComputeTopology.Processor.ExposeVirtualizationExtensions = true;
    // machineSpec.VirtualMachine.Chipset.LinuxKernelDirect.KernelFilePath = "D:\\temp\\vmlinux.bin";

    var machineSpecJson = JSON.stringify(machineSpec);
    host.diagnostics.debugLog("After:  ", JSON.stringify(machineSpec), "\n");
    var newLen = "0x" + machineSpecJson.length.toString(16);

    // allocate memory
    cmd = ".dvalloc 4096"
    lines = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmd)
    var addr = lines[0];
    var addrParts = addr.split(" ");
    var freeMem = addrParts[addrParts.length-1].replace("`", "");
    host.diagnostics.debugLog("Allocated ", freeMem, "\n");
    
    // write memory
    host.diagnostics.debugLog("Writing memory ", freeMem, " length: ", newLen, "\n");
    cmd = "eu " + freeMem + ' "' + machineSpecJson.split("\\").join("\\\\").split('"').join('\\"') + '"';
    lines = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmd)
    for (var line of lines) host.diagnostics.debugLog("  ", line, "\n");

    // patch rdx with new memory address
    var cmd = "r @rdx = " + freeMem;
    host.diagnostics.debugLog(cmd);
    var lines = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmd)
    for (var line of lines) host.diagnostics.debugLog("  ", line, "\n");

    // patch r8 with new memory size
    var cmd = "r @r8 = " + newLen;
    host.diagnostics.debugLog(cmd);
    var lines = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmd)
    for (var line of lines) host.diagnostics.debugLog("  ", line, "\n");

    return continueExecution();
}

  接着在这两个文件所在的目录下以管理员身份执行run-start.bat文件,此时会跳出WinDbg.exe执行,并且bat文件会出现按任意键继续的字样,此时按任意键,会弹出WSL执行。此时若输入命令查看,则WSL的硬件CPU虚拟化被开启,即使用egrep -c '(vmx|svm)' /proc/cpuinfo得到的值为正值,如下图所示:
在这里插入图片描述

将KVM加入内核模块

下载WSL内核

  由于直接从Microsoft Shop安装的WSL默认没有配置KVM模块,因此需要重新编译WSL的内核。
  首先去GitHub上下载最新的内核文件:链接:
WSL2配置安装KVM_第3张图片
  也可以直接使用如下命令下载:

cd ~
aria2c -x 10 https://github.com/microsoft/WSL2-Linux-Kernel/archive/4.19.128-microsoft-standard.tar.gz

  下载后解压进入该目录下:

tar zxf WSL2-Linux-Kernel-4.19.128-microsoft-standard.tar.gz
cd WSL2-Linux-Kernel-4.19.128-microsoft-standard

编译WSL内核

  进入WSL2-Linux-Kernel-4.19.128-microsoft-standard目录后执行如下命令:

cp Microsoft/config-wsl .config
make menuconfig

  此时会进入BIOS配置,进入Virtualization
WSL2配置安装KVM_第4张图片
  在KVM support上点击Y打开kvm支持,并在KVM for Intel上点击M将其添加至模块(如果你不需要调整该模块,可以直接将其存入内核中,而不是以模块形式进行编译,这样避免了每次使用sudo modprobe kvm_intel命令装载):
WSL2配置安装KVM_第5张图片
  返回上一级后进入Processor中:WSL2配置安装KVM_第6张图片
  然后进入Linux guest support
WSL2配置安装KVM_第7张图片
  然后将KVM Guest support打开:
WSL2配置安装KVM_第8张图片
  最后退出并保存即可。退出后正式进行编译:

make -j4

在这里插入图片描述

安装KVM模块

  如果你把KVM当作模块编译的话执行如下命令,若直接作为内核一部分则直接跳过:

sudo make modules_install

在这里插入图片描述

添加WSL在Windows下的配置文件

  将arch/x86/boot/bzImage移入C盘你的用户目录下:

cp arch/x86/boot/bzImage /mnt/c/Users/lyg/

  然后在/mnt/c/Users/lyg目录下创建配置文件.wslconfig如下:

[wsl2]
nestedVirtualization=true
kernel=C:\\Users\\lyg\\bzImage
pageReporting=true
kernelCommandLine=intel_iommu=on iommu=pt kvm.ignore_msrs=1 kvm-intel.nested=1 kvm-intel.ept=1 kvm-intel.emulate_invalid_guest_state=0 kvm-intel.enable_shadow_vmcs=1 kvm-intel.enable_apicv=1

  然后在CMD执行wsl --shutdown将WSL关闭后再打开,此时使用uname -r命令查看内核版本应该变为4.19.128
在这里插入图片描述

配置KVM-Intel

sudo vim /etc/modprobe.d/kvm-nested.conf

# 将如下配置信息放入上述文件即可
options kvm-intel nested=1
options kvm-intel enable_shadow_vmcs=1
options kvm-intel enable_apicv=1
options kvm-intel ept=1

加载内核模块

  如果你在执行make menuconfig过程中中KVM for Intel选择的是*而不是M,则忽略装载直接测试即可:

sudo modprobe kvm_intel

  为保证每次启动WSL都能自动装载该模块,请把它写入~/.bashrc中(但更好的方式时编译内核时直接将该模块固定在内核中),如下:

sudo modprobe kvm_intel
sudo chmod 666 /dev/kvm

测试

  如果你曾执行过WinDbg步骤,则在测试前请再次执行后用下述命令测试。如果你没有执行过,则直接使用如下命令测试:

kvm-ok

在这里插入图片描述
  然后执行如下命令应返回结果Y

cat /sys/module/kvm_intel/parameters/nested

在这里插入图片描述
  至此完成安装,当然你可以使用qemu虚拟机进行测试,具体测试不赘述。笔者用syzkaller测试得到如下结果:
WSL2配置安装KVM_第9张图片
  观察到成功运行qemu。

参考资料

[1]. https://boxofcables.dev/accelerated-kvm-guests-on-wsl-2/
[2]. https://sugeul.github.io/2020-06-21-MacOS-on-WSL2/

你可能感兴趣的:(环境搭建与配置,WSL,syzkaller)