ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QEMU折腾后WSL2虚拟化禁用?从Hyper-V到CUDA的完整排查修复指南

QEMU折腾后WSL2虚拟化禁用?从Hyper-V到CUDA的完整排查修复指南 先说我这边遇到的场景吧。前阵子为了在Windows上跑ARM64的OpenEuler和Alpine镜像我用了QEMU。当时照着一些老教程折腾为了让QEMU的TCG模拟不那么卡我在BIOS里关了虚拟化也跟着把Windows的“虚拟机平台”功能给勾掉了。结果等我想回WSL2里继续跑CUDA相关的东西时WSL2直接起不来了提示虚拟化已禁用。最麻烦的是本来在WSL2里配好的PyTorch和CUDA环境全部报废ComfyUI那类依赖torch.cuda的脚本在Windows侧跑也各种报错。这篇文章就是把当时一步步排查、恢复WSL2虚拟化、最后重新跑通CUDA的完整过程记录下来给同样被QEMU折腾完又卡在WSL2上的朋友一个参考。1. 事故现场WSL2 起不来torch.cuda 先报警1.1 症状清单不是“WSL 启动慢”而是虚拟化底座整个掉了当时的情况很有代表性。我先在Windows终端里执行了wsl --status输出显示默认版本是2但下面直接跟着一行“虚拟化已禁用”。再尝试启动Ubuntu-24.04窗口闪一下就没了有时候还会弹WSL 2 尚未准备就绪的错误框。这不是平时那种“WSL启动慢”或者“下载发行版超时”的问题而是WSL2赖以运行的Hypervisor层根本没加载。同一时间Windows侧的PyTorch也出现了奇怪的问题。在我常用的ComfyUI环境里Python路径是d:\comfyui_image\python\lib\site-packages\torch\cuda\__init__.py运行时出现了CUDA initialization的UserWarning。具体表现是torch.cuda.is_available()返回False或者报“NVIDIA driver too old”这类奇怪信息。我知道Windows侧驱动其实是正常的因为游戏和普通桌面应用都能用GPU问题出在WSL2里的Linux侧完全失去了GPU直通能力。如果你手头也有VMware或其他虚拟机软件症状会更明显。VMware Workstation会直接弹“此平台不支持虚拟化的AMD-V/RVI”或者报“模块tv启动失败”。另外VBox弹类似“硬件虚拟化已禁用”也常见。这些表面上看是VMware/QEMU的问题根子都在Windows虚拟化栈上。下面是当时我整理的快速症状对照表现象可能的直接原因最先排查的方向wsl --status显示虚拟化已禁用Hypervisor未随系统启动或虚拟机平台功能被关bcdedit /enum、Windows功能列表WSL2发行版启动闪退Hyper-V后端缺失或“虚拟机平台”可选功能未启用“启用或关闭Windows功能”勾选状态VMware报“AMD-V/RVI不支持”BIOS虚拟化被关或hypervisorlaunchtypeOffBIOS设置、bcdedit输出PyTorch报CUDA初始化失败/WarningWSL2 GPU直通链路断裂和Windows驱动无关WSL内ls /dev/dxg、nvidia-smi1.2 为什么 CUDA 用户最怕 WSL2 挂掉很多人不理解为什么WSL2挂了会牵连CUDA。WSL2的GPU方案和传统虚拟机不一样它不是把GPU设备整个直通给Linux而是Windows侧的NVIDIA驱动维护一个GPU paravirtualization接口Linux侧通过/dev/dxg访问这个接口。CUDA Toolkit在WSL-Ubuntu版本里会调用这个设备节点从而把计算请求转发到Windows驱动再落到物理显卡上。这个架构的优点很明确Linux侧不需要单独装NVIDIA Linux驱动只要Windows侧驱动版本够新WSL2里就能用CUDA。缺点也明显一旦WSL2虚拟机无法启动或者/dev/dxg不能正常暴露Linux侧所有CUDA程序瞬间瘫痪。对依赖Linux侧生态的人来说比如跑PyTorch、ComfyUI、深度学习训练脚本WSL2挂掉意味着整套本地实验环境都断了不是“重装个驱动”能解决的事。我自己的习惯是CPU多核重型编译放到Windows直接跑Python和GPU计算尽量在WSL2里做环境隔离干净不像在Windows原生Python里容易被各种路径问题搞乱。所以WSL2一旦起不来我的开发流就卡死了。2. 根因拆解QEMU 为什么能把 Windows 的虚拟化栈搞崩2.1 WSL2 和 Hyper-V 的依赖关系先把它理清楚WSL2本质上是一个轻量级虚拟机它跑在微软自己的Hypervisor上。Windows里有一个叫“虚拟机平台”的可选功能开启后系统会启用Hyper-V的虚拟化底座。与此同时还有一个更底层的开关叫hypervisorlaunchtype它决定Windows在引导时是否把Hypervisor加载起来。很多人以为只有安装了“Hyper-V管理器”才算开启了Hyper-V这是误解。就算你从来不用Hyper-V管理器界面只要WSL2能用说明Hypervisor已经以系统服务的形式在底层运行了。你看到的“Hyper-V”开关只是管理界面真正的Hypervisor是开机时通过引导配置加载的和界面完全无关。QEMU的问题就在这。QEMU在Windows上跑ARM64镜像时经常要跟这个Hypervisor打交道。很多教程会告诉你“关闭Hyper-V不然QEMU性能差”这个建议在某些远古版本的QEMU上确实没错因为旧版QEMU的WHPX后端还不成熟TCG纯软件模拟反而更稳定。但关掉Hyper-V的同时WSL2的命根子也没了。我当初就是照着这种教程把虚拟化相关的东西能关就关结果把自己坑了。2.2 QEMU 的两条运行路径TCG 和 WHPX分别踩了哪些雷QEMU在Windows下模拟ARM64有两种主要加速方式。第一种是TCG全称Tiny Code Generator。它不依赖硬件虚拟化通过动态二进制翻译来模拟CPU指令。这种方式兼容性最好哪怕CPU完全不支持虚拟化也能跑但速度感人尤其是在模拟ARM64这种跨架构场景下指令翻译开销极大。网上那些“为了QEMU性能关闭硬件虚拟化”的建议通常就是针对TCG模式说的。在Windows上跑ARM64系统如果不开WHPXTCG就是默认后端。问题是为了TCG跑得顺去把BIOS虚拟化关了、把虚拟机平台关了最终受影响的包括WSL2、Windows沙盒、甚至部分安全功能。这是第一类大坑。第二种是WHPX全称Windows Hypervisor Platform。它需要Windows的Hypervisor已经启动也就是说hypervisorlaunchtypeauto且“虚拟机平台”功能已开启。WHPX把QEMU的虚拟机执行请求转交给Hyper-V的Hypervisor处理性能比TCG好太多特别是CPU密集型的ARM64模拟能接近原生虚拟化的体验。但它依赖的正是WSL2也依赖的那套底座。如果这套底座本身坏了比如hypervisorlaunchtype被改成OffQEMU的WHPX后端同样会报错。所以真相是QEMU本身并不会“故意”弄坏WSL2真正的问题在于我们为了QEMU的某些模式手动把虚拟化相关的开关关掉了结果把WSL2的依赖一并拆掉。2.3 还有一个暗坑VBS 和内存完整性也会被误伤除了上面两条路线Windows 11还有一个容易被忽视的组件基于虚拟化的安全也就是VBS。Win11默认开启内核隔离里的内存完整性功能它依赖Hypervisor来保护内核。部分优化教程为了让QEMU或者老游戏跑得更顺会指导用户关闭“内存完整性”甚至通过注册表把VBS整个关掉。问题在于VBS和WSL2共享同一个Hypervisor基础。如果你把VBS关了系统里某些依赖虚拟化安全的组件会进入异常状态WSL2虽然不一定立刻崩但和VMware、QEMU共存时容易出现各种玄学问题比如VMware启动时报“模块hv启动失败”或者Windows沙盒打不开。更隐蔽的是注册表里的Device Guard设置它可以在界面完全看不出来的情况下影响Hypervisor的加载状态。这台机器当初为了QEMU折腾过一轮VBS状态已经不可控了。后来排查时发现Win32_DeviceGuard里的VirtualizationBasedSecurityStatus显示为0也就是VBS彻底关闭状态这基本就是注册表被改过或者内存完整性被关过的痕迹。3. 排查五步走从 BIOS 到事件日志逐层定位故障点3.1 第一步重启进 BIOS确认 VT-x/AMD-V 没被关排查的首要任务是先把最底层的硬件虚拟化开关确认一遍。按机器不同进BIOS的按键可能是Del、F2、F10或Esc。重点找这几项平台BIOS项名称需要的状态IntelIntel Virtualization Technology / VT-xEnabledAMDSVM ModeEnabledIntelVT-d可选Enabled和WSL2关系不大但影响DMA直通我见过不少案例是恢复BIOS默认设置后VT-x被恢复成Disabled而用户毫不知情。Windows里看起来“系统信息”显示虚拟化已启用但BIOS实际关了这种不一致最容易误导人。进入Windows后按CtrlShiftEsc打开任务管理器切到“性能”标签点CPU右下角能看到“虚拟化”状态。如果是“已启用”说明BIOS层面OK如果是“已禁用”先回去把BIOS打开再说。这一步不做好后面所有Windows层面的修复都白搭。3.2 第二步检查 Windows 可选功能勾选状态要三个一起看按WinR输入optionalfeatures打开“启用或关闭Windows功能”。重点关注以下几项虚拟机平台VirtualMachinePlatform适用于Linux的Windows子系统Microsoft-Windows-Subsystem-LinuxWindows虚拟机监控程序平台HypervisorPlatform也就是WHPX的接口Hyper-V包含管理工具和Hyper-V平台可选但建议装这里有个常见误区有人只勾了“适用于Linux的Windows子系统”漏了“虚拟机平台”结果WSL2要么跑不了要么从WSL1升级到WSL2时一直卡住。还有人只装了“Hyper-V”而没装“虚拟机平台”WSL2依然不正常。正确做法是“虚拟机平台”必勾“适用于Linux的Windows子系统”必勾“Windows虚拟机监控程序平台”建议勾因为它正是QEMU的WHPX后端需要的东西也能让虚拟机软件更好地和Hyper-V共存。勾选完成后会提示重启但先别急后面还要用命令行确认一遍因为图形界面的勾选有时候不会完整生效。3.3 第三步用 msinfo32 看 Hyper-V 底座的最终状态这是很多人忽略的一步。按WinR输入msinfo32打开系统信息拉到最下面的“Hyper-V要求”一栏。正常情况下会显示三行固件中已启用虚拟化是虚拟化已启用是Hyper-V检测到Hyper-V。此计算机上运行的虚拟机监控程序可保护虚拟机管理器的安全。如果第三行显示的是“出现错误”或者“未检测到Hyper-V”说明Hypervisor没有正确加载。这个信息比WSL2自己的报错更底层因为它直接涉及Windows引导加载的Hypervisor状态。我当时看到的就是第三行那里出现了错误。这也解释了为什么WSL2和VMware同时报“虚拟化不可用”之类的问题因为Windows层面的Hypervisor根本没起来。3.4 第四步用 bcdedit 和 wsl --status 做双保险确认打开管理员权限的命令提示符或PowerShell依次执行bcdedit /enum {current}在输出里找到hypervisorlaunchtype这一项。正常值是Auto如果显示Off那基本就是问题根源。执行下面的命令查看WSL状态wsl --status如果WSL2可用会显示“默认版本2”以及内核版本等信息如果显示“虚拟化已禁用”那就是Hypervisor没加载。另外建议看一眼事件查看器。打开事件查看器展开“Windows日志”-“系统”筛选来源为Hyper-V或Hyper-V-High Availability的错误时间点对应WSL2开始出问题的时间可以帮助确认是不是有组件在启动时失败。这一步走完就能确定故障层是BIOS关了、Windows功能没勾、还是hypervisorlaunchtype被改成了Off。绝大多数因为QEMU折腾过机器的案例都栽在最后一个。4. 修复方案一条 bcdedit 命令加上 Windows 功能重开4.1 最直接的修复hypervisorlaunchtype 改成 auto既然问题出在Hypervisor没随系统启动那最核心的一步就是把引导配置改回来。在管理员命令提示符里执行bcdedit /set hypervisorlaunchtype auto然后重启电脑。这一步的意义是告诉Windows引导加载器开机时要把Hypervisor装载起来。只有Hypervisor跑起来了WSL2、Windows沙盒、VMware的Hyper-V共存模式才能正常工作。重启后再次确认bcdedit /enum {current}看到hypervisorlaunchtype的值是Auto就没问题了。同时msinfo32里Hyper-V那一项应该也能看到“检测到Hyper-V”而不是“出现错误”。有些极端情况是hypervisorlaunchtype这一项根本不存在此时可先执行bcdedit /set hypervisorlaunchtype auto正常情况下它会自动创建该项并设为Auto。4.2 用 DISM 把可选功能重新装配好比手动勾选更靠谱光改引导配置还不够Windows功能里的“虚拟机平台”也得确保开启。推荐用DISM命令而不是图形界面因为DISM能明确显示每个功能的启用状态还能避免漏项。管理员PowerShell里依次执行dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart dism /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism /online /enable-feature /featurename:HypervisorPlatform /all /norestart如果想把Hyper-V管理工具也一并装回来dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /all /norestart执行完后再重启一次。重启后打开optionalfeatures确认三项都已勾选。如果之前某个功能是被手动卸载过的这种DISM方式能把它们完整装回来比图形界面更可靠。另外建议顺手更新一下WSL内核wsl --update这个命令会把WSL2内核更新到最新版本有时候旧内核和新Hypervisor之间也有兼容问题。4.3 如果 QEMU 动过 VBS/Device Guard把虚拟化安全找回来如果你像我一样曾经为了让QEMU更流畅而关过VBS那还需要把虚拟化安全相关设置恢复。在管理员PowerShell里检查当前状态Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard | Select-Object VirtualizationBasedSecurityStatusVirtualizationBasedSecurityStatus的值值含义0VBS已关闭1VBS已启用但未运行2VBS已启用且正在运行如果显示0说明VBS被关了。最简单的恢复方式是打开“Windows安全中心”-“设备安全性”-“内核隔离”开启“内存完整性”然后重启。如果界面开关是灰的或者提示设备不支持可以检查注册表HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard在右侧新建或修改DWORD值EnableVirtualizationBasedSecurity为1。同时检查HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity把Enabled的值设为1。注意开启内存完整性后部分老驱动可能不兼容如果有驱动签名问题需要先更新驱动再开启。VBS本身不是WSL2的绝对依赖但关闭它会导致和QEMU、VMware共存时出现各种莫名冲突所以我个人建议能开就开。4.4 清理 QEMU 相关的残留影响如果你的QEMU是安装版或者手动添加过环境变量、系统服务建议检查一下有没有自带开机启动项、虚拟网卡或驱动残留。这些不一定会直接影响WSL2但有概率干扰Hyper-V的某些组件。检查方式按WinR输入services.msc看有没有QEMU相关的服务。打开设备管理器查看网络适配器中有没有QEMU虚拟网卡如果有且不再使用右键卸载。检查环境变量Path里是否还有QEMU的路径留着没问题但确认没有多个QEMU版本混用。真正要注意的是如果当初为了QEMU安装过WinPcap之类的抓包组件它和WSL2的虚拟交换机偶尔会有DNS或网络层面的冲突。不需要的时候可以卸载但这跟虚拟化启停没有直接关系。5. 验证闭环WSL2 活了CUDA 也得验一遍5.1 WSL 侧检查内核和 GPU 设备节点修复完成后先打开WSL2终端确认虚拟化底座和WSL2内核都正常uname -r能看到类似5.15.x.x-microsoft-standard-WSL2的输出就说明WSL2内核跑起来了。再检查GPU直通设备ls /dev/dxg如果存在/dev/dxg说明WSL2的GPU paravirtualization接口已经暴露给Linux侧。接着运行nvidia-smi正常情况下能看到显卡型号和驱动版本。这里显示的驱动版本号是Windows侧驱动的版本因为WSL2里不装Linux驱动全靠Windows驱动转发。如果nvidia-smi不存在说明CUDA Toolkit还没装好或者PATH里没有NVIDIA的bin目录。5.2 Windows 侧 NVIDIA 驱动需要配合 WSL2别装反了WSL2的CUDA方案有个容易踩的坑在WSL2里安装NVIDIA的Linux版驱动。这是完全错误且没必要的操作。WSL2里的GPU不是通过PCIe直通访问的而是通过微软的GPU虚拟化接口转给Windows驱动所以Linux侧只需要CUDA Toolkit绝对不要安装NVIDIA-Linux-x86_64.run这种驱动包。一旦装了反而可能把/dev/dxg链路弄乱导致nvidia-smi识别异常。Windows侧则必须安装支持WSL2的NVIDIA驱动。现在的主流Game Ready和Studio驱动都支持WSL2关键是版本不能太旧。建议直接去NVIDIA官网下载最新驱动安装时选择“自定义安装”勾选“执行清洁安装”。装完重启再回WSL2里跑一次nvidia-smi。5.3 用一个小矩阵跑通 CUDA 和 PyTorch验证CUDA最稳的方法是编译运行NVIDIA官方的deviceQuery示例或者直接用Python调一下PyTorch。先装CUDA Toolkit推荐用WSL-Ubuntu对应的runfile版本。这里以CUDA 12.8为例从NVIDIA官网下载cuda_12.8.x_linux.run后执行wget https://developer.download.nvidia.com/compute/cuda/12.8.0/local_installers/cuda_12.8.0_550.54.15_linux.run sudo sh cuda_12.8.0_550.54.15_linux.run --toolkit --silent注意加--toolkit只装Toolkit不装驱动。装完后配置环境变量echo export PATH/usr/local/cuda/bin:$PATH ~/.bashrc echo export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH ~/.bashrc source ~/.bashrc然后验证nvcc -V能输出版本信息说明Toolkit装好了。再去编译官方示例cd /usr/local/cuda/samples/1_Utilities/deviceQuery sudo make ./deviceQuery如果看到Result PASS说明CUDA链路完全打通。要是你主要跑PyTorch直接在WSL里装对应版本的torch即可pip install torch --index-url https://download.pytorch.org/whl/cu124装完后执行python -c import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))输出类似2.x.x True NVIDIA GeForce RTX 4060 Ti就代表WSL2里的CUDA环境彻底恢复了。如果输出False多半是Windows侧驱动版本和PyTorch要求的CUDA版本不匹配先升级Windows驱动。6. 防再炸经验QEMU、WSL2、VMware 共存的三个底线6.1 永远先确认 hypervisorlaunchtype再谈第三方虚拟化这台机器折腾完以后我的经验教训就一条既然主力开发环境是WSL2那Windows的Hypervisor决不能关。任何第三方虚拟化软件包括QEMU、VMware、VirtualBox都要在Hypervisor已启动的前提下使用而不是试图关闭Hypervisor来绕过兼容性问题。QEMU在Windows上跑ARM64镜像时优先使用WHPX后端命令大致是qemu-system-aarch64 -machine virt -cpu cortex-a76 -accel whpx ...这样QEMU和WSL2共用同一个Hypervisor互不干扰。虽然WHPX模式在QEMU上对某些版本可能有小问题但比TCG快太多也安全太多。至于VMware新版Workstation在Windows 10/11上可以使用Windows Hypervisor Platform实现共存不需要关闭Hyper-V。旧版本确实和Hyper-V冲突那种情况就该弃用旧版而不是关Hyper-V。6.2 动“Windows功能”和BIOS之前先备份 bcd修改引导配置前务必做个备份。一条命令的事bcdedit /export C:\bcd_backup需要恢复时执行bcdedit /import C:\bcd_backup另外改BIOS设置前用手机拍张照记录原设置改Windows功能勾选项前也一样。我这次排查浪费了不少时间就是因为不记得当初到底关了哪些东西只能全凭猜。如果你按本文的顺序操作完WSL2能正常启动但某天又突然出现“虚拟化已禁用”或者VMware报“模块hv启动失败”先别急着重装系统按下面这个顺序查一遍检查项命令/位置正常值BIOS虚拟化开机进BIOS或任务管理器CPU页已启用hypervisorlaunchtypebcdedit /enum {current}Auto虚拟机平台功能optionalfeatures已勾选VBS状态PowerShell查Win32_DeviceGuard2WSL内核wsl --update最新6.3 遇到“此平台不支持虚拟化”不再慌一份快速自查清单最后分享一个快速自查的顺序这基本上是我遇到所有虚拟化相关报错都会走一遍的路径先看任务管理器CPU页的“虚拟化”是否“已启用”。运行msinfo32看“Hyper-V要求”第三行。管理员命令行里跑bcdedit /enum {current}确认hypervisorlaunchtype。打开optionalfeatures确认“虚拟机平台”和“适用于Linux的Windows子系统”都勾着。管理员PowerShell里确认VBS状态。这套走下来90%的“此平台不支持虚拟化”“模块hv启动失败”“虚拟化已禁用”问题都能定位到具体是哪一层断了。我自己后来在Windows上跑ARM64镜像只走QEMU加WHPX这条路GPU计算全部交给WSL2两边相安无事。这套组合稳定跑了大半年再没出过虚拟化方面的幺蛾子。如果看完这篇文章的你也正好卡在同一个坑里按上面的顺序走一遍大概率不用重装系统就能救回来。
返回列表