<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://cmp.wiki/w/index.php?action=history&amp;feed=atom&amp;title=BAR1_64_GB_on_ESXi</id>
	<title>BAR1 64 GB on ESXi - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://cmp.wiki/w/index.php?action=history&amp;feed=atom&amp;title=BAR1_64_GB_on_ESXi"/>
	<link rel="alternate" type="text/html" href="https://cmp.wiki/w/index.php?title=BAR1_64_GB_on_ESXi&amp;action=history"/>
	<updated>2026-10-31T06:36:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://cmp.wiki/w/index.php?title=BAR1_64_GB_on_ESXi&amp;diff=343&amp;oldid=prev</id>
		<title>ImportBot: Import: 64 GiB BAR1 for CMP 170HX cards passed through by ESXi 8 (pre-boot UEFI writer, VM settings, guest repair hook, results, risks), from @darkmaniac7 lab notes and the darkmaniac7/cmp170hx-esxi repo</title>
		<link rel="alternate" type="text/html" href="https://cmp.wiki/w/index.php?title=BAR1_64_GB_on_ESXi&amp;diff=343&amp;oldid=prev"/>
		<updated>2026-10-30T08:42:59Z</updated>

		<summary type="html">&lt;p&gt;Import: 64 GiB BAR1 for CMP 170HX cards passed through by ESXi 8 (pre-boot UEFI writer, VM settings, guest repair hook, results, risks), from @darkmaniac7 lab notes and the darkmaniac7/cmp170hx-esxi repo&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Status|Reported}} {{Cards|8 GB}}&lt;br /&gt;
&lt;br /&gt;
How to give CMP 170HX cards that VMware ESXi passes through to a Linux guest a real 64 GB BAR1. ESXi does not do it by itself. It takes two parts: a small UEFI program that resizes BAR1 on the host before ESXi boots, and a guest-side hook that restores the card&amp;#039;s override after every VM power-on. Everything here was measured on one host in October 2026; the code, the build files and the full write-up are in [https://github.com/darkmaniac7/cmp170hx-esxi darkmaniac7/cmp170hx-esxi]. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
For passthrough in general (Proxmox, the in-guest unlock, Gen2, P2P) see [[Virtual machines and passthrough]]. For BAR1 on bare metal see [[Resizable BAR and BAR1 64 GB]] and [[Server BIOS setup]].&lt;br /&gt;
&lt;br /&gt;
== Do you need it? ==&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;The 64 GB VRAM unlock does not need a big BAR1.&amp;#039;&amp;#039;&amp;#039; The VRAM unlock, the Gen2 retrain and serving all work with the 64 MB BAR1 ESXi gives a passthrough card: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;memory.total&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; stays 65536 MiB and the link stays Gen2. {{Status|Proven}} {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;BAR1 size matters only for P2P and static BAR1 mappings.&amp;#039;&amp;#039;&amp;#039; P2P between CMPs inside an ESXi guest does not work yet, even with 64 GB BAR1s: static BAR1 P2P fails init or wedges UVM, while the same cards pass 12/12 directed pairs on bare metal. So today the large BAR1 under ESXi is groundwork for P2P experiments, not a speed-up. See [[Virtual machines and passthrough#P2P inside the VM: not working]]. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Tested on ==&lt;br /&gt;
* VMware ESXi 8.0.3, four 8 GB cards (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;10de:20c2&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, Hynix HBM, VBIOS 92.00.67.00.01) passed through into one Ubuntu 24.04 guest (kernel 6.8.0-146-generic) next to other, newer NVIDIA GPUs.&lt;br /&gt;
* A single-socket EPYC server with the slots bifurcated x8/x8, so every card sits behind its own root port; two cards on one PCIe root complex, two on another.&lt;br /&gt;
* Guest driver: NVIDIA 580.178.04 open modules with the cmpunlocker v0.5 core ported onto them (in the repo&amp;#039;s &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;driver/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). The writer and the guest hook do not depend on that driver.&lt;br /&gt;
* The 10 GB card (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;10de:2082&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;) is coded in the guest hook but untested.&lt;br /&gt;
{{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== The problem ==&lt;br /&gt;
=== On the host: ESXi keeps whatever firmware assigned ===&lt;br /&gt;
At every host power-on the card&amp;#039;s Resizable BAR capability advertises only 64 MB: ReBAR CAP at config offset &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xbbc&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; reads &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x400&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (only the 64 MB size bit) and CTRL at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xbc0&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; reads &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x601&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Firmware sizes BAR1 to 64 MB, ESXi enumerates what firmware assigned, and ESXi never writes the card&amp;#039;s vendor override. Broadcom&amp;#039;s VMDirectPath notes say Resizable BAR is unsupported for passthrough and that devices are reset at VM power-on. Raising &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pciPassthru.64bitMMIOSizeGB&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; only reserves guest address space; it cannot grow the physical BAR. The cmpunlocker &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;bar1-resize-unlock.patch&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; resizes from a Linux host; inside a VM the BAR is fixed before the driver exists. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== In the guest: 256 MB even when the host has 64 GB ===&lt;br /&gt;
With the host BAR1 at 64 GB, the first VM boot showed &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resource1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; = 64 GiB in sysfs but NVML reported BAR1 Total 256 MiB. Every VM power-on resets the card&amp;#039;s internal override while the host allocation survives: guest config space and the config mirror at BAR0 + &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x88000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; read CAP &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x400&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CTRL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x801&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (size code 8 = 256 MB, which CAP does not even advertise), CYA &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x26&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CFG &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x80000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. {{Status|Proven}} {{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
The driver takes the BAR1 size from GSP, and GSP reads the card&amp;#039;s ReBAR block, not Linux&amp;#039;s reservation; so Linux showing 64 GiB proves nothing about what the card decodes. The same cards on native Linux report 64 GB BAR1 on all four, so there is no general 256 MB driver limit. {{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
Two card registers open the large sizes: CYA &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x724 = 0x30&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, then CFG &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xdcc = 0x8000000a&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. After them ReBAR CAP reads &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1ffc00&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (64 MB to 64 GB offered) and BAR1 can be programmed to 64 GB (CTRL size code 16, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1001&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). On bare metal the patched Linux driver does this and asks the kernel to resize. Under ESXi it has to happen twice:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;On the host, before ESXi boots&amp;#039;&amp;#039;&amp;#039;, with the BAR1 and BAR3 addresses and the parent bridge window programmed by hand, because ESXi will not resize later.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;In the guest, before the NVIDIA driver loads&amp;#039;&amp;#039;&amp;#039;, because each VM power-on resets the two override registers. Guest config-space writes are virtualised by VMware and never reach the device, so the guest repair writes through the BAR0 config mirror page instead.&lt;br /&gt;
{{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Part 1: the pre-boot UEFI writer (host) ==&lt;br /&gt;
A small UEFI application (gnu-efi, x86_64) that runs after firmware PCI enumeration and before the ESXi loader, then chain-loads the unchanged loader with its original load options, with no firmware reset. Source: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writer/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in the repo, in a two-card and a four-card variant. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== What it does, per card ===&lt;br /&gt;
Before the first store it reserves, for each card, a 64 GB + 32 MB span (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1002000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; bytes) at 64 GB alignment in the firmware memory map (GCD), inside the root bridge aperture taken from the ACPI DSDT &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;_CRS&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; windows. Then, through &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EFI_PCI_IO_PROTOCOL&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with every store read back before the next:&lt;br /&gt;
# COMMAND cleared (memory decode and bus mastering off) on the card and on its parent root port.&lt;br /&gt;
# CYA &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x724 = 0x30&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# CFG &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xdcc = 0x8000000a&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. CAP &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xbbc&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; now reads &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1ffc00&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# ReBAR CTRL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xbc0&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; set to size code 16 (64 GB): &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1001&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# BAR1 address low/high, then BAR3 low/high (BAR3 is 32 MB at BAR1 + 64 GB).&lt;br /&gt;
# The parent port&amp;#039;s prefetchable window (base, limit and upper 32 bits) set to enclose the reservation.&lt;br /&gt;
# The parent port&amp;#039;s COMMAND restored. The card itself is left with decode off for the OS to enable.&lt;br /&gt;
{{Status|Proven}} {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Placement rule:&amp;#039;&amp;#039;&amp;#039; BAR1 at the lowest 64 GB-aligned base at or above the root bridge&amp;#039;s declared aperture start, BAR3 at the next 64 GB boundary, one reservation that is also the parent port&amp;#039;s prefetchable window, and a 128 GB stride to the next card. On the test host this gave BAR1s at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x64000000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x66000000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on one root complex and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x48000000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x4a000000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on the other. The repo&amp;#039;s &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writer/placement.py&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; computes a proposal only; the writer re-checks every interval live. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== Gates: it refuses before writing unless everything matches ===&lt;br /&gt;
The writer refuses before any store unless all of these hold: the SMBIOS system UUID matches the pinned host; the current boot entry and its variable match; the ESXi loader file on the boot partition matches the pinned size and SHA256; each card&amp;#039;s cold BAR0/BAR1/BAR3 and its parent bridge windows equal the recorded cold values; the ReBAR capability offers the 64 GB size; the root bus descriptors and apertures match; and every reservation misses every recorded memory, bridge and firmware interval. All pins (host UUID, boot partition and boot entry, loader hash and size, the BAR plan and the apertures) are per host: the published build ships placeholders and must be regenerated for your host, and the source refuses to build an executing image unless &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;WRITER_POLICY_BOUND=1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;WRITER_EXECUTE=1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; are set. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Four-card variant (fail-open):&amp;#039;&amp;#039;&amp;#039; a refusal before the first store prints &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;HANDOFF_FALLBACK reason=... pci_mutation=0 resize_applied=0&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and boots ESXi normally with 64 MB BARs. This branch has not yet run on real firmware.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Two-card variant (no fallback):&amp;#039;&amp;#039;&amp;#039; any refusal parks the host.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;After a possible store has begun&amp;#039;&amp;#039;&amp;#039; any failure is terminal: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;HANDOFF_REFUSED ... cold_recovery_required=1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, the host stays parked in the firmware. There is no rollback, retry or NVRAM write inside the app.&lt;br /&gt;
{{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== Build ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
make GNUEFI=/path/to/gnu-efi/usr four-card     # or two-card; output in build/&amp;lt;variant&amp;gt;/BOOTX64.EFI&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Regenerate the host pins and the BAR plan first (see &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writer/four-card/README.md&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, section &amp;quot;Per-host values to regenerate&amp;quot;). {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== Steps for one supervised run ===&lt;br /&gt;
The repo&amp;#039;s &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writer/window/two_card_window.py&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; drives these steps with a guard on each; every step can be dry-run first. The order:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Preflight:&amp;#039;&amp;#039;&amp;#039; record which VMs run, check the BMC, the IP-KVM and that the guest hook (Part 3) is installed and passes &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;--check&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Media:&amp;#039;&amp;#039;&amp;#039; put &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BOOTX64.EFI&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;\EFI\BOOT\BOOTX64.EFI&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on a 64 MB FAT image, upload it to the IP-KVM mass-storage drive, read it back and compare the SHA256, and present it read-only (not as a CD-ROM).&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Quiesce:&amp;#039;&amp;#039;&amp;#039; stop the GPU workloads in the guest, shut down every VM, put the host in maintenance mode.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Boot override:&amp;#039;&amp;#039;&amp;#039; attach the media and set the BMC (Redfish) boot override to Once, UEFI, USB; read it back.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Record the console&amp;#039;&amp;#039;&amp;#039; (the writer prints its progress on the firmware console).&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Reboot the host once.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Wait for ESXi&amp;#039;&amp;#039;&amp;#039; and check every BAR on the host (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;vsish&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; BARInfo per card: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Size:68719476736&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Detach&amp;#039;&amp;#039;&amp;#039; the media and clear the boot override, exit maintenance mode, start the guest and check it (Part 3), then start the services and the other VMs.&lt;br /&gt;
A good run on the console reads &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;WRITER_RUN ... target_count&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for the number of cards, one &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;WRITER_REBAR_TRANSITION&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; line per card (cap &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x400&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1ffc00&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, ctrl &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x601&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1001&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;WRITER_STATE ... status=4&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;START_IMAGE ... pci_mutation=1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, then the VMware loader banner. {{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
=== Running it on every host boot ===&lt;br /&gt;
Firmware re-enumerates every card cold on each host power-on and reboot, so the writer has to run on every boot; it refuses an already enlarged layout, so there is no resume. What runs on the test host: leave the writer image attached read-only on the IP-KVM, and set the BMC boot override to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Continuous&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; / USB / UEFI through Redfish (check that &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Continuous&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is among the allowed values first; otherwise put the UEFI USB class first in the BIOS boot priorities). With no USB target the firmware falls through to the normal boot order. Each host boot takes about 3.5 to 4 minutes longer. Add a post-boot check that alerts when any BAR1 is not 64 GB, because a fallback otherwise looks like a normal boot. Copying the writer onto the ESXi boot partition with its own boot entry is written up in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writer/four-card/docs/BOOT_PERSISTENCE.md&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; but not rehearsed. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Part 2: VM settings ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pciPassthru.use64bitMMIO = &amp;quot;TRUE&amp;quot;&lt;br /&gt;
pciPassthru.64bitMMIOSizeGB = &amp;quot;1024&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
384 was not enough even for one 64 GB card (the guest EFI refused the MMIO; the arithmetic fit, the placement did not). Four 64 GB cards plus two other GPUs with 128 GB BAR1s need about 544 GB of 64-bit BAR space, so 512 cannot work either; 1024 is the next power of two. Size it for every passthrough GPU in the VM. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Part 3: the guest repair hook ==&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cmp-bar1-repair&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (in the repo&amp;#039;s &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;guest/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, Python 3 standard library only) restores the two override registers before the NVIDIA module loads. It is wired in as a modprobe install command:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# /etc/modprobe.d/zz-cmp-bar1-repair.conf&lt;br /&gt;
install nvidia /usr/local/sbin/cmp-bar1-repair; /sbin/modprobe --ignore-install nvidia $CMDLINE_OPTS&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
For each &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;10de:20c2&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;10de:2082&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function it reads 15 words of the config mirror page (BAR0 + &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x88000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, one 4 KB page mapped from &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resource0&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;) and repairs only when all of this holds: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resource1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is exactly 64 GiB; no driver is bound and the nvidia module is not loaded; the card shows exactly the reset profile (CAP &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x400&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CTRL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x601&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x801&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CYA &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x26&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CFG &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x80000000&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;); the device ID and ReBAR structure words match; the card&amp;#039;s physical BAR1 is a 64-bit prefetchable BAR on a 64 GB-aligned base; memory decode on, bus mastering off, no error bits. The repair is two stores, each re-read: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x724 = 0x30&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xdcc = 0x8000000a&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, ending at CAP &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1ffc00&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CTRL &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x1001&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CYA &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x30&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, CFG &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0x8000000a&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Anything else is refused with no writes. It always exits 0 so the driver still loads, keeps one JSON journal per run and logs to journald under the tag &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cmp-bar1-repair&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. {{Status|Proven}} {{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
Expected log on a VM boot: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;REPAIRED CAP=0x1ffc00 CTRL=0x1001 CYA=0x30 CFG=0x8000000a after 2 writes; all other words unchanged&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; once per card, then NVML shows 65536 MiB BAR1. {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
Three rules learned the hard way:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Enable decode first on a cold VM boot.&amp;#039;&amp;#039;&amp;#039; A driverless function comes up with memory decode off, so every mirror read returns &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;0xffffffff&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (on one cold boot all four cards read all-ones and the driver came up at 256 MB). The hook writes 1 to the sysfs &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;enable&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; attribute (memory decode only, never bus master) and re-checks before mapping.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Lock against udev.&amp;#039;&amp;#039;&amp;#039; udev coldplug runs the install command once per NVIDIA function, concurrently (five times within two seconds). The hook holds an exclusive lock for its whole run; a 60 s timeout is a refusal, never a race.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Never retry.&amp;#039;&amp;#039;&amp;#039; A wrong read-back after store 1 stops before store 2; any failure means a VM power cycle, not a second attempt.&lt;br /&gt;
{{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
Keep &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;nvidia.ko&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; out of the initramfs, and never &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;insmod&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modprobe --ignore-install&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; by hand: both bypass the hook. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
Check and remove:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cmp-bar1-repair --check                 # read-only report, fine with the driver bound&lt;br /&gt;
cmp-bar1-repair --check --strict        # exit 1 unless every CMP is OK or SKIP (for monitoring)&lt;br /&gt;
modprobe --show-depends nvidia          # first line must be the install command&lt;br /&gt;
journalctl -t cmp-bar1-repair           # every run&lt;br /&gt;
rm /etc/modprobe.d/zz-cmp-bar1-repair.conf   # removes the hook; the next nvidia load is a plain modprobe&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The post-boot check catches a wrong card count, a non-64 GiB &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resource1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or a missing repair line, but not a refusal that leaves NVML at 256 MB, so also check NVML BAR1 after every VM boot. If a guest shows 256 MB on a card the host gave 64 GB: stop everything using the GPUs, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, run &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cmp-bar1-repair&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modprobe nvidia&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and check again. {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Result on the passthrough host ==&lt;br /&gt;
* 2026-10-18: two cards (one root complex) at 64 GB; 2026-10-19: all four (both root complexes).&lt;br /&gt;
* On the host, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;vsish&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; BARInfo reports &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Size:68719476736&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for each card (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;67108864&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; when the writer did not run), and the VM log shows &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PCIPassthru: ... barIndex 1 ... size 68719476736&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* In the guest, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resource1&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is 64 GiB and NVML reports 65536 MiB BAR1 on all four; 60 GiB write/verify tests with two address-dependent patterns pass on every card.&lt;br /&gt;
* Since 2026-10-19 every VM boot logs four repairs and NVML shows 65536 MiB on all four.&lt;br /&gt;
{{Status|Proven}} {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Risks ==&lt;br /&gt;
* {{Status|Warning}} &amp;#039;&amp;#039;&amp;#039;A failure after the writer&amp;#039;s first store parks the whole host.&amp;#039;&amp;#039;&amp;#039; The ESXi host and every VM on it stay down until a cold power cycle; there is no rollback or retry in the app. Cold recovery: detach and disable the media, clear the boot override, power the host off, confirm it stays off for at least 10 seconds, power it on, and check that every card shows its small cold BARs before starting any VM. Never run the writer again on a card that may have been written. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* {{Status|Warning}} &amp;#039;&amp;#039;&amp;#039;ESXi updates park the host.&amp;#039;&amp;#039;&amp;#039; A patch that rewrites the ESXi loader or the boot entry makes the writer refuse at the next boot and leave the host in the firmware. Before patching ESXi, detach the media and set the boot override to Disabled; re-check the loader and boot-entry pins before re-arming. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* {{Status|Warning}} &amp;#039;&amp;#039;&amp;#039;The writer reprograms bridge windows on a root complex that may also carry the ESXi boot drive, console and USB&amp;#039;&amp;#039;&amp;#039; (it did on the test host). Run the first boots in a maintenance window with a remote console and a way to power-cycle the host. {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* {{Status|Warning}} &amp;#039;&amp;#039;&amp;#039;The fail-open branch has never run on real firmware.&amp;#039;&amp;#039;&amp;#039; Treat any refusal as a parked host until proven otherwise. {{Source|handle=darkmaniac7|date=2026-10-19|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;A normal host reboot throws the allocation away.&amp;#039;&amp;#039;&amp;#039; Never follow a successful 64 GB host boot with a plain reboot to check something; the cards come back at 64 MB and the whole window has to be run again. If only the guest fails to start afterwards, read the VM log and do not reboot the host. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;The pins are per host.&amp;#039;&amp;#039;&amp;#039; A build with another host&amp;#039;s pins refuses by design. Moving a card, adding a device or a firmware update that changes the ACPI tables or the memory map makes the writer refuse (or fall back), so expect to regenerate the plan after hardware changes. {{Source|handle=darkmaniac7|date=2026-10-21|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;In the guest,&amp;#039;&amp;#039;&amp;#039; a failed repair leaves the card at 256 MB and needs a VM power cycle; nothing persistent is written to the card. {{Source|handle=darkmaniac7|date=2026-10-18|repo=https://github.com/darkmaniac7/cmp170hx-esxi|note=lab notes}}&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
[[Virtual machines and passthrough]], [[Resizable BAR and BAR1 64 GB]], [[Server BIOS setup]], [[P2P]], [[Platforms]], [[Card not detected or BAR allocation fails]].&lt;br /&gt;
&lt;br /&gt;
Repository: [https://github.com/darkmaniac7/cmp170hx-esxi darkmaniac7/cmp170hx-esxi] (writer, guest hook, probes, and the 580.178.04 driver patches). The unlock itself is [https://github.com/amoghmunikote/cmpunlocker amoghmunikote/cmpunlocker].&lt;br /&gt;
&lt;br /&gt;
{{ImportFooter}}&lt;br /&gt;
[[Category:Platforms]]&lt;br /&gt;
[[Category:8 GB]]&lt;/div&gt;</summary>
		<author><name>ImportBot</name></author>
	</entry>
</feed>