
手上有一台跑着 ESXi 7.0 的主机机箱里插着一张 GeForce 显卡想整张丢给一台 Windows 虚拟机跑渲染、做本地推理或者偶尔打两把游戏——这个需求我这两年帮身边朋友配过不下十台。表面上看就是在设备列表里把显卡勾成直通、重启、开机三步实际动手你会发现 ESXi 7.0 在这个环节上跟 6.7 时代完全是两套逻辑6.7 里点一下 passthrough 重启主机十有八九就起来了同样的操作搬到 7.0等待你的可能是一串看不懂的 MMIO 分配失败提示或者虚拟机电源刚打开就卡死、主机管理界面直接失联。这篇内容就是把这套流程从头到尾拆一遍。我会从为什么 7.0 变了讲起接着是主板 BIOS 里那几个必须打开的开关、主机侧的设备认领与直通配置、虚拟机 vmx 文件里必须补的参数再到开机报错的逐条排查链路。适合两类人看一类是手里有闲置显卡和一台 ESXi 主机、想自己试直通的折腾党另一类是已经在做虚拟化、需要把物理 GPU 交付给某个业务的运维。全文踩坑点都是真机上下来的不是纸上推演。1. 为什么 ESXi 7.0 的 N 卡直通和 6.7 是两套逻辑1.1 卡住大多数人的那道门槛叫 MMIO先说清楚 7.0 到底变了什么。在 6.7 阶段一块 8GB 显存以内的消费级显卡很多情况下开箱就能直通成功原因是虚拟机的 32 位 MMIO 地址洞PCI Hole默认给的余量能兜住显卡 BAR 的尺寸。到了 7.0一方面是 PCI 资源分配策略收紧了另一方面是 30 系、40 系显卡的 BAR 尺寸动辄十几甚至几十 GB——尤其是主板 BIOS 里开了 Re-Size BAR 之后——32 位地址空间压根装不下。于是虚拟机开机时找不到地方映射显卡的寄存器空间直接报错退出。这个地方就是 MMIOMemory-Mapped I/O空间。你可以把它理解成给虚拟机划出的一块信箱号段显卡的显存、寄存器、控制块都要靠这个号段来映射号段不够长显卡就没法被挂进客户机的地址空间。7.0 里这个问题必须显式解决——打开 64 位 MMIO 开关并且手动指定一个足够大的尺寸。这两个参数写在虚拟机的 vmx 配置文件里后面我会给出可以直接照抄的取值算法。顺带说一句64 位 MMIO这个名字本身就说明了限制只有 64 位客户机操作系统才吃得到这套机制。如果你打算在虚拟机里装 32 位 Windows 再直通现代显卡这条路基本走不通别在这里浪费时间。1.2 直通、vGPU、SR-IOV 三条路怎么选在动手之前先确认一件事你要的到底是哪一种 GPU 交付方式。很多人把三个概念混着用结果配置到一半才发现方向就错了。方案本质授权适用场景主要限制PCIe 直通DirectPath I/O整张物理卡独占给一台虚拟机无需额外授权单机高性能渲染、本地推理、游戏一卡一机、不能热迁移、不能快照回滚NVIDIA vGPU一张卡切成多个虚拟 GPU 分给多台虚拟机需要 vGPU 授权桌面云、多租户图形工作站需服务端卡、授权成本高、版本矩阵严格SR-IOV硬件层面切出多个虚拟功能VF视卡而定特定网卡、少数专业卡消费级显卡基本不支持绝大多数个人和小团队场景走的是第一条路一卡一机独占使用。这条路不需要任何额外授权代价是灵活性差——显卡被哪台虚拟机占着其他虚拟机就碰不到。vGPU 是另一个量级的事涉及到授权服务和驱动版本矩阵消费级 GeForce 根本不在支持列表里。所以下面的内容全部围绕 PCIe 直通展开。2. 上机之前主板 BIOS 里那几个不能漏的开关2.1 VT-d、IOMMU 与 Above 4G Decoding 的真实作用直通这件事的底层依赖是 IOMMUIntel 平台叫 VT-d。没有它CPU 就无法把物理设备的内存访问翻译到指定虚拟机的地址空间hypervisor 也就没办法安全地把一张卡交给某台虚拟机独占。所以 BIOS 里第一件事是把虚拟化相关的开关全部打开Intel 平台找VT-d、VT-x部分主板写作Intel Virtualization Technology和Intel VT for Directed I/O。AMD 平台找SVM ModeCPU 虚拟化和IOMMU有的主板把 IOMMU 藏在NB Configuration或Advanced → AMD CBS下面。不管什么平台Above 4G Decoding必须打开。这个选项决定了系统能不能把 PCIe 设备的 BAR 映射到 4GB 以上的地址空间。它跟 Re-Size BAR 是两回事前者是允不允许用 4G 以上的地址后者是要不要把显卡的 BAR 窗口撑大。直通必须开前者后者建议保持默认或者先关掉等整套跑通之后再考虑打开。我踩过一次很典型的坑一台 AMD 平台的主机IOMMU在主 BIOS 页面里根本找不到藏在AMD CBS → NBIO Common Options里名字还叫IOMMU。找了半小时才翻出来打开之后直通一次成功。所以如果 BIOS 里翻不到去 CPU 相关的子菜单里再找一遍。2.2 插槽选择与 IOMMU 分组PCIe 拓扑决定成败IOMMU 分组IOMMU Group这个概念必须理解否则后面所有报错你都看不懂。CPU 的 IOMMU 把物理设备按必须一起隔离的原则分成若干组同一组内的设备共享一个地址翻译域。ESXi 只允许把整组设备一起直通给同一台虚拟机——如果你要的显卡和主板上的某个 SATA 控制器分在了一组那要么两个一起直通要么谁也直通不了。消费级主板上显卡插在不同槽位分组结果可能完全不同。直连 CPU 的 PCIe x16 槽通常是离 CPU 最近的那条或者标注为CPU_PCIE、PCIE_1的槽往往能拿到独立分组走芯片组PCH的槽位则很容易跟网卡、USB 控制器、SATA 控制器挤在一组里。我的建议是把要直通的显卡插在直连 CPU 的槽位上动手前先查一下主板手册里的 PCIe 拓扑图。如果你的主板实在分不开组还有一条软路子——ESXi 的/etc/vmware/passthru.map文件这个后面单独讲。它能解决一部分设备共用分组时的直通问题但不是万能的别指望它把整组设备都硬拆开。2.3 显卡本身的准备和几个常被误判的细节显卡这块有几件事要先确认。第一确认卡是好的、在别的系统上能正常亮机别把硬件问题当成配置问题去排查。第二注意显卡上除了显示功能VGA function之外通常还带一个 HDMI/DP 音频功能HD Audio function两个 function 在设备列表里会分别出现。直通的时候建议把音频 function 一起勾上交给同一台虚拟机否则客户机里会出现显示设备正常但音频设备冲突的怪现象。第三消费级 GeForce 在 ESXi 上官方是不背书的这不影响直通能不能成功但影响你在客户机里装驱动时可能遇到的报错——那部分我在第 5 章单独展开。第四如果你打算长期跑注意机箱散热显卡在直通模式下由客户机驱动接管主机的风扇曲线、机箱风道都不再由显卡自己的策略控制长时间满载时温度会比裸机高一些。3. 主机侧配置把设备从主机的变成虚拟机的3.1 用命令行先把设备底细摸清楚打开 ESXi 的 SSH主机客户端 → 管理 → 服务 → 启用 SSH登进去先做两件事。第一件事是看显卡的设备 IDlspci -v | grep -i -A 3 nvidia输出里你会拿到类似0000:01:00.0的地址和10de:xxxx这样的厂商 ID 与设备 ID。10de是 NVIDIA 的厂商 ID这个数字后面要写进 passthru.map记下来。第二件事是看这张卡在主机侧有没有被驱动认领esxcli hardware pci list -c 0x03000x0300是显示控制器的类别码。输出里关注Owner或者模块这一列。正常情况下 GeForce 会显示未认领Not claimed这正是我们想要的——主机不碰它才能干净地交给虚拟机。如果显示被某个 GPU 驱动占用了说明主机把它按虚拟 GPU 模式接管了需要在主机的高级设置里关掉相关开关或者干脆不安装那一套组件。第三件事是看 IOMMU 分组。ESXi 没有一个特别直观的命令直接把分组列出来通常的做法是翻/var/log/vmkernel.loggrep -i iommu\|group /var/log/vmkernel.log | head -50另一种更实用的做法是直接看/etc/vmware/esx.conf里有没有直通相关记录以及用主机客户端在管理 → 硬件 → PCI 设备里按属性看设备所在的组。3.2 passthru.map 里那行10de ffff d3d0 default到底在干什么网络上几乎所有关于 ESXi 显卡直通的教程都会让你执行这么一句echo 10de ffff d3d0 default /etc/vmware/passthru.map多数人照抄了但不知道它在干什么出了别的问题就完全失去判断力。这个文件的作用是告诉 ESXi 用什么方式去复位一个 PCIe 设备。格式是四个字段第一个字段是厂商 ID10de就是 NVIDIA。第二个字段是设备 ID写成ffff表示通配该厂商的所有设备。第三个字段是复位方式d3d0表示让设备走 D3 到 D0 的电源状态切换来完成复位也就是软复位这是对不完整实现 FLRFunction Level Reset的消费级显卡最温和的方式。第四个字段是链路复位策略default表示沿用默认策略。为什么需要它因为虚拟机每次关机再开机ESXi 都要把设备复位一遍确保上一个使用者留下的状态被清干净。消费级显卡的 FLR 实现经常不完整导致复位失败表现为虚拟机关机之后设备无法再被直通、或者主机在设备列表里状态异常。加上这行之后复位走 D3→D0 路径问题基本能压下去。需要提醒三点。第一改完这个文件必须重启主机才生效。第二ffff是省事写法如果你主机上同时插了 NVIDIA 和 AMD 的卡最好一行一行写清楚AMD 的厂商 ID 是1002对应写1002 ffff d3d0 default。第三这个文件在主机升级时可能被覆盖升级后要复查一遍。3.3 打开直通开关、重启主机以及重启后要复查的东西在主机客户端里进管理 → 硬件 → PCI 设备找到你的显卡勾选它通常显示显卡名称和地址还有它的音频 function。7.0 的不同小版本在这里的界面有差异早期版本是每台设备一个切换直通按钮7.0 Update 2 之后换成了配置直通对话框可以一次选多台设备还能看到 MMIO 相关的选项。不管界面长什么样操作完成后主机状态栏一定会提示需要重启。这一步不能跳过也不能用重新引导之外的任何方式绕过——直通配置是在主机启动早期由 VMkernel 读取并生效的。重启后回到 PCI 设备列表确认你勾的那几个设备状态变成了活动而不是仍然显示需要重新引导。复查清单显卡的显示 function 和音频 function 都处于活动直通状态。主机没有因为直通而丢失管理网络如果丢了看 5.3 节。/etc/vmware/passthru.map里的那行还在没被覆盖。3.4 显卡上的音频 function 和 USB 控制器别忽略一个高频的坑只直通了显卡的显示 function01:00.0把音频 function01:00.1留在了主机上。客户机里显卡驱动装上了但设备管理器里会多出一个带感叹号的音频设备而且显卡的 HD Audio 在客户机里拿不到正确的资源。稳妥做法是把同一张卡上的所有 function 一起勾上直通交给同一台虚拟机。另一个容易被忽略的是 USB 控制器。如果你打算在客户机里用直通显卡的同时接键鼠、用显卡做显示输出那么客户机需要输入设备。用 ESXi 的虚拟 USB 控制器在虚拟机设置里加 USB 控制器和 USB 设备最省事但延迟比直通一个物理 USB 控制器高。想要低延迟的话找一块独立的 PCIe USB 扩展卡直通给虚拟机比直通主板自带的 USB 控制器安全——主板自带的 USB 控制器经常和 SATA、网卡同组动它容易把整机搞失联。4. 虚拟机侧MMIO 大小、内存预留与 vmx 参数4.1 虚拟机固件、机型与内存预留创建虚拟机的时候有四件事必须做对做错任何一件都会在开机阶段报错。第一客户机操作系统必须选 64 位的对应版本这是 64 位 MMIO 的前提。第二固件建议选 UEFI机型保持默认的最新版本即可老式的 BIOS 固件不是不能跑但在大 BAR 显卡场景下更容易出问题。第三在虚拟机选项的高级 → 内存里勾选预留所有客户机内存全部锁定。直通设备需要直接访问客户机的物理内存如果内存被允许换页出去地址就不稳定了ESXi 会直接拒绝开机。第四把虚拟机的 vCPU 数量控制在物理核心数以内多了反而拖性能。还有一个小选择虚拟显卡SVGA要不要保留。保留的好处是你还能通过主机客户端看到客户机的控制台画面方便装系统、看蓝屏代价是客户机里会多一个显示适配器。我的习惯是装系统和驱动阶段保留等一切稳定之后如果追求极致可以用svga.present FALSE把它关掉让直通显卡当唯一显示适配器。但要注意关掉之后你就只能靠远程桌面或者接在显卡上的物理显示器来操作了。4.264bitMMIOSizeGB填多少一个能直接照抄的算法这是全文最关键的一个数值。经验公式是64bitMMIOSizeGB ≥ 所有直通设备的 BAR 尺寸之和 × 2然后向上取到 16、32、64、128 这类常用档位。实际落地时用显存大小做近似估算就够用了直通显卡显存总量建议64bitMMIOSizeGB单卡 4GB 及以下16单卡 8GB16 到 32单卡 12GB 到 16GB32单卡 24GB64双卡 24GB128为什么要有 2 倍这个余量因为显卡的地址空间不只包含显存还有寄存器块、命令缓冲区、影子 ROM 等零碎区域再加上 hypervisor 自己需要的一小块映射空间。按显存直接取值在开了 Re-Size BAR 的卡上很容易差一点然后你就要花半小时去查为什么差那一点。记住一个原则这个值宁大勿小。大一点只是多占虚拟机的地址空间不等于等量消耗物理内存小一点就是直接开不了机。但也不要无脑填个 256过大的虚拟地址空间在一些老版本上会引起内存映射效率下降。如果主机客户端 7.0 Update 2 之后的配置直通对话框里提供了 MMIO 尺寸选项优先用界面填没有的话回到 vmx 里写两种方式效果一样。4.3 vmx 里必须补的参数清单关闭虚拟机用 SSH 进到虚拟机的存储目录先备份再编辑cd /vmfs/volumes/你的数据存储/虚拟机目录 cp 虚拟机名.vmx 虚拟机名.vmx.bak vi 虚拟机名.vmx然后把下面这些参数补进去已有的不要重复写参数建议值作用pciPassthru.use64bitMMIOTRUE打开 64 位 MMIO 映射7.0 上大 BAR 显卡的必选项pciPassthru.64bitMMIOSizeGB按上表取值预留的 64 位地址空间大小hypervisor.cpuid.v0FALSE向客户机隐藏 hypervisor 存在位smbios.reflectHostTRUE让客户机的 SMBIOS 信息反射主机pciPassthru0.msiEnabledTRUE打开设备的 MSI 中断降低中断开销可选svga.presentFALSE关闭虚拟显卡让直通卡当主显示可选其中hypervisor.cpuid.v0 FALSE是解决客户机里显卡报错码 43 的标准动作。它的原理是把 CPUID 里标识当前运行在虚拟化环境的那一位藏起来让客户机驱动以为自己跑在物理机上。smbios.reflectHost思路类似让客户机的 BIOS 信息跟主机一致。编辑完之后要重新加载虚拟机配置才生效vim-cmd vmsvc/getallvms vim-cmd vmsvc/reload vmidvmid是上一条命令列出来的虚拟机 ID。如果你是从主机客户端里直接关机再开机配置也会自动重读但养成手动 reload 的习惯没坏处——改错了能立刻在vmware.log里看到。4.4 客户机驱动安装顺序与验证方法开机顺序上有个讲究先让客户机正常起来不进系统就蓝屏的话先别急着装显卡驱动再确认设备管理器里能看到直通的显卡最后装驱动。这个顺序能帮你把直通失败和驱动问题两类故障分开不然你会在两个维度之间反复横跳。Windows 客户机里装 NVIDIA 官方驱动即可。装完打开命令行跑nvidia-smi看到显卡型号、显存、驱动版本和温度说明整条链路打通了。Linux 客户机里记得先屏蔽开源驱动再装官方驱动echo -e blacklist nouveau\noptions nouveau modeset0 /etc/modprobe.d/blacklist-nouveau.conf update-initramfs -u重启之后再装官方驱动同样用nvidia-smi验证。验证完之后建议跑一个实际负载渲染一张图、跑一个推理小模型、或者跑一遍 3DMark确认不是能识别但一跑就掉的假成功。5. 开机报错逐条排查从 MMIO 不足到 Code 435.1 报错一开机提示内存或 MMIO 资源分配失败这是 7.0 上最常见的一条。虚拟机的vmware.log里会出现类似无法为该设备分配内存或者MMIO 地址空间不足的字样。排查链路是这样的先确认虚拟机的预留所有客户机内存勾了没有——没勾的话报错信息会更偏向内存而不是 MMIO但两者经常混在一起出现。勾了之后看pciPassthru.use64bitMMIO是不是确实写进去了、pciPassthru.64bitMMIOSizeGB的值是不是够。这时最常见的错误是值写太小比如 24GB 的卡只给了 32。再看主机 BIOS 里的Above 4G Decoding有没有打开。这个开关关着的时候有时候虚拟机内部怎么调都不对。改完 BIOS 记得重新确认主机的直通状态需不需要重新开关一次。最后检查显卡上是不是还挂着别的大 BAR 设备比如直通了一块大容量 PCIe 存储卡如果有MMIO 值要按所有设备的总和来算而不是只看显卡。5.2 报错二设备管理器里显卡带黄色感叹号客户机里能认出显卡但设备状态是该设备无法启动代码 43。这基本可以判定是驱动层面的问题而不是直通层面的问题——直通本身已经很成功地把设备交给了客户机。处理顺序先确认hypervisor.cpuid.v0 FALSE写没写、写对了没有大小写和引号都算。然后确认客户机是不是跑在嵌套虚拟化的Hyper-V 组件下——Windows 客户机里如果启用了某些基于虚拟化的安全功能或者 WSL2它会占用一层虚拟化和显卡驱动打架。在客户机里关掉这些组件通常能解决。还有一个经验不同版本的 GeForce 驱动对这个检查的宽松程度不一样。如果某个版本死活报 43换一个较新的版本再试很多时候换了就好。这不是玄学是驱动内部检测逻辑在不同版本之间确实有变化。5.3 报错三直通之后主机管理界面失联这是最让人心慌的一种通常出现在你把显卡插在了走芯片组的槽位上而那个槽恰好和板载网卡分在同一个 IOMMU 组。开启直通并重启后网卡被一起拉走主机网络直接没了管理界面自然进不去。遇到这种情况的处理顺序是接上物理显示器和键盘或者在开机时进带外管理界面到 DCUI黄色控制台里检查网络配置看管理网卡是否还在、IP 是否正常。如果 DCUI 都进不去说明问题更靠底层一般只能从引导层面回退或者重装主机。所以我在第 2 章反复强调插槽选择就是因为它直接决定你后面会不会遇到这条。动手前一定先确认带外管理如果有能用或者至少在物理层面能接触到这台机器。远程开直通然后失联是很痛苦的体验。5.4 报错四能认卡但不稳、跑分远低于物理机排查完上面三类还有一种看起来成功了的状态nvidia-smi正常跑分却只有物理机的七成或者跑一会儿就掉驱动。这时候要往这几个方向看。一是 CPU 亲和性。虚拟机的 vCPU 如果没有绑到物理核心、或者跨了 NUMA 节点显卡通过 PCIe 往内存里搬数据时延迟会明显上去。用主机客户端把虚拟机的 CPU 亲和性绑定到同 NUMA 节点内的物理核心上。二是中断开销。确认pciPassthru0.msiEnabled TRUE让设备用 MSI 中断而不是传统的 INTx在高负载下差别不小。三是客户机内部。Windows 要装 VMware Tools显卡驱动的电源管理模式设成最高性能优先关闭客户机的屏幕保护、关闭快速启动。这几个都是低成本高收益的调整。四是有没有插错槽。显卡如果插在 PCIe x4 的物理槽位上或者主板把 x16 槽拆成了两个 x8带宽减半是硬件层面的软件调不回来。6. 从能跑到好用直通后的性能与运维细节6.1 NUMA、CPU 亲和与大页内存的取舍单路平台不用太操心 NUMA双路平台就要认真对待了。原则很简单虚拟机的所有 vCPU 加上它的内存都落在同一个 NUMA 节点上。跨节点的内存访问延迟在显卡这种高带宽场景下会被放大。具体做法是在虚拟机设置里配置 CPU 亲和性把 vCPU 绑到同一颗 CPU 的物理核心上同时把虚拟机的内存大小设置得能装进单节点的可用内存里。如果做不到那就接受一定程度的性能损失别为了凑数把 vCPU 塞满。大页内存这块ESXi 会自动为直通虚拟机启用大页不需要手动配置。但要注意一点开启了内存预留之后虚拟机的内存是全程锁定的主机上可用内存会实实在在少掉那么多规划容量的时候要把这部分算进去别到时候主机因为内存不足没法开其他虚拟机。6.2 备份、快照、迁移这些操作在直通虚拟机上的真实限制这几点必须提前知道否则会在运维流程里翻车不能做内存快照。带直通设备的虚拟机无法保存内存状态所以挂起这类操作是不支持的。快照能力受限。磁盘快照在部分场景下可以但因为设备状态无法回滚快照回滚之后显卡的直通状态经常对不上客户机里需要重新装一次驱动。所以对直通虚拟机我的建议是老老实实走客户机内部的备份工具文件级备份别依赖虚拟化层的快照。不能在线迁移。直通设备绑定在特定主机上vMotion 之类的操作直接不支持。也就是说直通虚拟机的可用性上限就是那台物理主机的可用性做业务规划时要把这一点算进去。不能 DRS 自动调度。同理集群的自动负载均衡对它是失效的需要给虚拟机配一条应该运行在指定主机的规则。如果你需要的是高可用、能迁移的图形能力那就该走 vGPU 这条路而不是硬扛直通——这是架构层面的选择不是配置技巧能弥补的。6.3 多卡、多虚拟机的分配与预留策略一台主机插两张卡、分给两台虚拟机是很常见的做法。配置上有两个点要注意。第一MMIO 尺寸的计算变成所有设备的累加。两张 24GB 的卡给同一台虚拟机64bitMMIOSizeGB至少要 128分给两台虚拟机则每台各自按单卡算互不影响。第二PCIe 带宽分配。如果两张卡都插在直连 CPU 的槽上带宽是各自独立的问题不大如果主板做了槽位拆分x16 拆成 x8 x8两张卡共享同一路 PCIe 通道跑满的时候会互相抢带宽。做密集型渲染或多卡推理的场景优先选通道数够多的平台。第三主机上如果还有一张卡留着给主机自己用比如做主机控制台输出记得别把它也勾成直通不然主机启动之后就真的没有任何显示输出了虽然不影响管理但现场调试会很不方便。7. 几个只有真跑过才会知道的细节最后聊几条经验都是文档里不会写、但实际会遇到的。pciPassthru.64bitMMIOSizeGB这个值我现在的习惯是直接按显卡显存的 4 倍给只要主机地址空间允许。多给的代价几乎为零少给的代价是反复开机失败加排查半小时这笔账怎么算都划算。同理passthru.map里的那行我从来不删主机固件升级、ESXi 打补丁之后第一件事就是回去cat一下确认它还在。关于显卡驱动版本我的经验是客户机里装驱动之前先记下当前版本号装完跑一遍负载测试稳定了就别再动。显卡驱动在直通环境里是动一次就要重新验证一次的东西自动更新关掉省下的是自己的时间。再有就是整套流程跑通之后把虚拟机的 vmx 文件、主机的passthru.map、BIOS 的关键开关截图整理成一份自己的配置记录。我见过太多人半年后重装主机把这些参数忘得一干二净又从头踩一遍当年踩过的坑。这东西不复杂但确实琐碎留一份记录比什么都实在。