cmpunlocker #
Unlock tool for the NVIDIA CMP 170HX (GA100). Restores full SM compute, unlocked HBM2e memory geometry, PCIe Gen2 and GPU-to-GPU P2P — all clamped in firmware on the stock card.
Join our Discord community for support and discussions.
Proof of Concept #
Below are memory and performance results after applying the unlock:
Unlock Results #
Requirements #
- Linux (x86-64 or aarch64)
- Root access
- NVIDIA CMP 170HX (8GB or 10GB)
- nvidia-open 610.57.04, 610.43.03 or 610.43.02 already installed (libs + firmware)
- Kernel headers matching the running kernel (
linux-headers-$(uname -r)/kernel-devel) - Secure Boot disabled (patched modules are unsigned)
- Network access on first install (downloads matching stock
open-gpu-kernel-modulessources)
Install #
sudo ./install.sh
Then perform a cold reboot (full power off, then boot). The correct memory geometry is selected automatically from the PCI device ID (0x20C2 = 8GB -> 64GB, 0x2082 = 10GB -> 40GB).
HBM Memory overclock #
HBM Memory overclock
--mclk-ndiv=N sets the FBPA PLL multiplier; the resulting clock is N * 27 MHz. Any VBIOS works, on both 0x20C2 (8GB) and 0x2082 (10GB).
sudo ./install.sh --mclk-ndiv=70 # 1890 MHz
| NDIV | Frequency | Notes |
|---|---|---|
| 45 | 1215 MHz | Stock 10gb |
| 60 | 1620 MHz | Works on ~60% of 10gb cards |
| 54 | 1458 MHz | Stock 8gb 250w vbios |
| 64 | 1728 MHz | Stock 8gb 300w vbios |
| 70 | 1890 MHz | Works on ~60% of 8gb cards |
| 73 | 1971 MHz | Usually only on lucky 8gb cards |
Values below stock downclock the card, which is the way to stabilise a card that fails at stock.
Without the flag the overclock is compiled out entirely. The multiplier is compiled into the modules, so changing it means re-running install.sh. In a mixed 8GB+10GB system the same multiplier lands on every card.
If a value turns out to be unstable - reinstall without --mclk-ndiv (or run ./remove.sh) from a working state.
IOMMU #
IOMMU
The installer adds `iommu=pt` (passthrough) to the kernel command line by default — it has negligible overhead and is required for VM passthrough. IOMMU must also be enabled in BIOS (VT-d on Intel, AMD-Vi / SVM on AMD).To skip IOMMU configuration:
sudo ./install.sh --no-iommu
Surviving Kernel Updates (Anti-rollback) #
Surviving Kernel Updates
The patched modules are built against one specific kernel. Without help, the first kernel update leaves the card on the stock driver — reporting 8GB instead of 64GB — or on nouveau. The installer wires the rebuild into the kernel update path by default, so this does not happen.
A new kernel triggers a rebuild through the package manager hook for your distro, before you reboot:
| Distro | Hook |
|---|---|
| Fedora, RHEL, openSUSE | /etc/kernel/install.d/95-cmpunlocker.install |
| Debian, Ubuntu, HiveOS | /etc/kernel/postinst.d/cmpunlocker |
| Arch | /etc/pacman.d/hooks/95-cmpunlocker.hook |
cmpunlocker-rebuild.service is the safety net for what hooks cannot see — a hand-built kernel, a restored snapshot, or a hook that ran before the kernel headers were unpacked. It holds the boot until the patched modules exist, because a rig that silently comes up at 8GB is worse than one slow boot. It gives up after three consecutive failures rather than delaying every boot forever.
Two more things keep the stock driver from winning:
/etc/depmod.d/cmpunlocker.confmakes the patched modules outrank the stock ones. The distro driver is rebuilt on every kernel update too, intoextra/(akmod) orupdates/dkms/(dkms), right next to ours.nvidia-fallback.serviceis masked and nouveau is blacklisted, so a driver that fails to load does not hand the card to nouveau.
The NVIDIA packages are pinned to their installed version. A driver upgrade past the versions in driver/VERSION makes every later rebuild fail, which is the rollback this is meant to prevent. This covers the GSP firmware the driver actually loads, from /lib/firmware/nvidia/<driver-version>/, which ships in the driver package itself.
GPU firmware packages (nvidia-gpu-firmware and friends) are deliberately left unpinned — they belong to linux-firmware, and holding them back can wedge system upgrades on a dependency conflict. They are also no longer able to affect the unlock: the optional Booter payload override is read from /var/lib/cmpunlocker/dmem.bin rather than from /lib/firmware/nvidia/ga100/gsp/, a directory that firmware updates add files to and that no amount of pinning could safely protect.
sudo ./install.sh --no-pin # allow driver upgrades, accept the risk
sudo ./install.sh --no-persist # manage rebuilds yourself
Checking on it:
systemctl status cmpunlocker-rebuild
sudo /usr/lib/cmpunlocker/pin-packages.sh status
cat /var/log/cmpunlocker/rebuild-$(uname -r).log
sudo /usr/lib/cmpunlocker/rebuild.sh # rebuild for the running kernel by hand
To take a pinned driver upgrade: sudo /usr/lib/cmpunlocker/pin-packages.sh unpin, upgrade, then re-run install.sh (which re-pins). If the new driver version is not in driver/VERSION, the build will refuse it.
Everything above is undone by ./remove.sh --yes.
Verify #
After install and cold reboot:
# Memory — 8GB card should show 65536 MiB, 10GB card 40960 MiB
nvidia-smi --query-gpu=index,memory.total,pci.bus_id --format=csv
# Unlock logs
sudo dmesg | grep CMPUNLOCK
# P2P read matrix (multi-GPU, only with --p2p) — should be OK, not GNS
nvidia-smi topo -p2p r
# Link topology (multi-GPU) — PIX / PHB / SYS depending on how the GPUs are wired
nvidia-smi topo -m
Benchmark #
SM count, memory size and bandwidth, PCIe link speed, tensor core throughput (TF32/BF16/INT8), SM clock, and hardware features (NVENC/NVDEC):
./benchmark/nvidia_bench # GPU 0, auto-sized iterations
./benchmark/nvidia_bench 1 # explicit GPU index
./benchmark/nvidia_bench 0 50 # explicit iteration count
./benchmark/nvidia_bench --csv # one header line + one data line
./benchmark/nvidia_bench --help # all options
A pre-built x86-64 binary is included. On aarch64 (or to rebuild), install the CUDA toolkit and build from source:
cd benchmark && nvcc -O3 -o nvidia_bench nvidia_bench.cu -lnvidia-ml -ldl \
-gencode arch=compute_80,code=sm_80 && strip nvidia_bench
What Gets Unlocked #
| Feature | Status |
|---|---|
| Full SM compute throughput (SS0/SS1) | ✅ |
| Memory geometry (64GB on 8GB cards, 40GB on 10GB cards) | ✅ |
| PCIe Gen 2 speeds | ✅ |
GPU-to-GPU P2P (cudaDeviceEnablePeerAccess) |
In progress |
| HBM2e memory overclock/downclock | ✅ |
| Persistence across kernel updates (auto-rebuild) (anti-rollback) | ✅ |
| BAR1 64mb->64gb (requires Above 4G Decoding in BIOS) | ✅ |
| PMA mem region fix | ✅ |
Documentation #
- Installation — requirements and install steps
- Architecture — how the unlock works
- Debugging — when something does not come up
- Contributing — making changes
Uninstall #
sudo ./remove.sh --yes
Then perform a cold reboot (full power off, then boot).
This removes the patched modules from disk, undoes the kernel-update hooks, releases the package pin, and rebuilds the initramfs. The driver already running in memory is left alone — the card comes up on the stock driver at the next boot, which is the safe order.
--reload swaps the running driver for the stock one immediately instead of waiting for the reboot. It is off by default because loading the stock nvidia-drm against a CMP 170HX can wedge the machine: the card has no usable display engine, and the kernel keeps answering pings while userspace stops making progress. There is no reason to take that risk during an uninstall you are going to reboot from anyway.
Credits #
| Who | Contribution |
|---|---|
| JP | BAR1 64mb --> 64gb |
| JP | Extra special thanks |
| Humvee55 | Extra special thanks |
| @bayley | GPU-to-GPU P2P over BAR1, PMA WPR overlap fix |
Community #
Join our Discord community to discuss with other users.