Add opt-in cmpunlocker unlock step with post-unlock Gen2 x16 acceptance

Insert a "cmpunlocker unlock (install)" step after unlock verification:
y/N confirmation (default n) or --unlock runs install.sh from the
harness clone (main branch, ff-only pull first) with live terminal
output and full log to cards/<serial>/install_unlocker.log. On success
the Vulkan stress is skipped until after the cold reboot.

Score now enforces the post-unlock invariant: when verify reports
unlocked-ok, any final link other than Gen2 x16 fails with a red
[ERROR] and exit 1. README safety section and AGENTS.md harness
cloning invariant updated to match.
This commit is contained in:
2026-09-28 15:39:10 +02:00
parent a84aa494d0
commit 7f3cfcf058
4 changed files with 220 additions and 27 deletions
+18 -9
View File
@@ -1,16 +1,16 @@
# cmp170hx_check
Single-card checker for **NVIDIA CMP 170HX** cards (PCI IDs `10de:20c2` / `10de:2082`) — run it **one card at a time**: it waits for the card, verifies the PCIe capacitor mod, records PCIe bus health, backs up VBIOS, runs the cmpunlocker verification, and optionally stresses VRAM. Each card gets its own folder + JSON report named by serial, so the folders accumulate as you go through your batch (e.g. 23 cards).
Single-card checker for **NVIDIA CMP 170HX** cards (PCI IDs `10de:20c2` / `10de:2082`) — run it **one card at a time**: it waits for the card, verifies the PCIe capacitor mod, records PCIe bus health, backs up VBIOS, runs the cmpunlocker verification, offers the **opt-in** cmpunlocker unlock install (then a cold reboot and a re-run for the final PCIe check), and optionally stresses VRAM. Each card gets its own folder + JSON report named by serial, so the folders accumulate as you go through your batch (e.g. 23 cards).
Reference harness (auto-cloned into `harness/` by preflight):
- [170th-Street](https://github.com/amoghmunikote/170th-Street) — community docs, incl. `modifications/pcie-capacitor-mod.md` (the pass criteria: `LnkSta Width x16` after the mod, `x4` when missing)
- [cmpunlocker](https://github.com/amoghmunikote/cmpunlocker) — `verify.sh` is executed **read-only** per card (nothing is installed or patched by this tool)
- [cmpunlocker](https://github.com/amoghmunikote/cmpunlocker) — `verify.sh` is executed **read-only** per card; `install.sh` is only run from the separate, opt-in unlock step (see [Safety](#safety))
## Requirements
- Linux x86-64 (tested target: **Ubuntu 26.04**), Python 3.8+
- **sudo privileges** — precondition for `--preflight` package installation and for privileged checks (PCI rescan, link retrain, sysfs ROM, `dmesg`, `verify.sh`)
- **sudo privileges** — precondition for `--preflight` package installation, for privileged checks (PCI rescan, link retrain, sysfs ROM, `dmesg`, `verify.sh`), and for the opt-in unlock install
- `pciutils` (`lspci`, `setpci`), `git` — installed automatically by preflight
- NVIDIA driver with `nvidia-smi` (nvidia-open 610.xx+, see cmpunlocker) for unlock verification — preflight can install it for you (asks first)
- `nvflash` — **bundled in this repo** (`nvflash_5.867_linux/x64/nvflash`), used directly by the script; no system install needed (see [nvflash](#nvflash-bundled-in-this-repo))
@@ -75,6 +75,7 @@ the files (keep the executable bit: `chmod +x`).
python3 check_cards.py # check the connected card
python3 check_cards.py --preflight # setup: tools, packages, harness clone
python3 check_cards.py --demo # self-test with fake hardware (no GPU needed)
python3 check_cards.py --unlock # check + run the cmpunlocker install without asking
python3 check_cards.py --help # all flags
```
@@ -87,8 +88,10 @@ Flow of a normal run:
5. Link retrain test + full bus rescan test (device must survive both)
6. Kernel log scrape (`dmesg`/`journalctl`) for this BDF: Xid / AER / NVRM lines
7. `nvidia-smi` snapshot + `harness/cmpunlocker/verify.sh` (read-only)
8. **Last step, optional**: `Run 5-min Vulkan VRAM stress test now? (y/N)` — refused by default, `--vulkan always|never` to override
9. Result printed + `report.json` written into the card's folder
8. **Opt-in unlock**: `cmpunlocker unlock (install)` — skipped with a note when memory is already unlocked, otherwise asks `Run cmpunlocker install.sh now? (y/N)` (default **n**; `--unlock` runs it without asking). On yes: `git pull --ff-only` on the harness clone, then `install.sh` runs from `harness/cmpunlocker/` with **live terminal output** (full log → `cards/<serial>/install_unlocker.log`; the kernel-module build takes 5–15 min)
9. **After a successful install**: the VRAM stress is skipped — **cold reboot the host** (`sudo shutdown -h now`, then power it back on) and **re-run the same command** for the final PCIe check, which must report **Gen2 x16**
10. **Last step, optional**: `Run 5-min Vulkan VRAM stress test now? (y/N)` — refused by default, `--vulkan always|never` to override
11. Result printed + `report.json` written into the card's folder
Remove the card, plug the next one, repeat — no queue, no indices, folders just pile up in `cards/`.
@@ -96,8 +99,8 @@ Remove the card, plug the next one, repeat — no queue, no indices, folders jus
| Result | Criteria |
|--------|----------|
| **FAIL** | no device detected, link down/untrained, device lost after rescan, link failed retrain, active uncorrectable AER errors |
| **WARN** | link width ≠ `x16` (capacitor mod missing/incomplete), Gen1 only (Gen2 unlock patch not active), correctable AER errors, kernel errors / Xid, VBIOS backup failed, cmpunlocker verify not `unlocked-ok`, errors during VRAM stress |
| **FAIL** | no device detected, link down/untrained, device lost after rescan, link failed retrain, active uncorrectable AER errors, **final post-unlock link other than Gen2 x16** (`[ERROR] final PCIe link after unlock is <speed> <width> - expected Gen2 x16`) |
| **WARN** | link width ≠ `x16` (capacitor mod missing/incomplete, pre-unlock runs only), Gen1 only (Gen2 unlock patch not active, pre-unlock runs only), correctable AER errors, kernel errors / Xid, VBIOS backup failed, cmpunlocker verify not `unlocked-ok`, cmpunlocker install failed, errors during VRAM stress |
| **PASS** | everything clean |
Exit codes: `0` PASS/WARN · `1` FAIL · `2` no card found · `3` preflight blocking failure.
@@ -114,7 +117,9 @@ cards/
├── lspci_after.txt # lspci -vvv (after retrain/rescan)
├── config_space.hex # lspci -nnvvxxxx full hex dump
├── dmesg.log # kernel lines related to this card
└── verify_unlocker.log # cmpunlocker verify.sh output
├── verify_unlocker.log # cmpunlocker verify.sh output
└── install_unlocker.log # full install.sh output (only if the opt-in
# unlock step ran)
```
## Flags
@@ -126,10 +131,14 @@ cards/
| `--nvflash PATH` | explicit nvflash binary |
| `--serial XYZ` | override serial (skips nvflash auto-read) |
| `--vulkan ask\|always\|never` | VRAM test policy (default: ask, last step) |
| `--unlock` | run the cmpunlocker `install.sh` step without prompting (default: ask y/N) |
| `--skip-bios` | skip VBIOS backup |
| `--no-install` | never install packages (skips the sudo precondition) |
| `--no-clone` | don't clone the harness repos |
## Safety
This tool only **reads** card state: `verify.sh` is run without installing anything, no modules are patched, no firmware is flashed. The only writes are local files, PCI link retrain/rescan sysfs triggers, package installation during `--preflight` (explicitly gated behind the sudo precondition), and your own reports.
This tool **reads** card state by default. The one step that changes the card is **opt-in**:
- **Unlock install (opt-in, explicit confirmation)** — runs only if you answer `y` to `Run cmpunlocker install.sh now? (y/N)` (default `n`) or pass `--unlock`. It executes `install.sh` **from the harness clone** (`harness/cmpunlocker/`, refreshed first with `git pull --ff-only`, no extra installer flags), needs root (sudo credentials are cached first), streams its output live, and saves the full log to `cards/<serial>/install_unlocker.log`. It is skipped entirely when memory is already unlocked, when the harness is not cloned, and in `--demo` mode. A successful install replaces kernel modules — the step then skips VRAM stress and asks you to cold reboot and re-run.
- **Everything else remains read-only**: `verify.sh` runs without installing anything, no modules are patched and no firmware is flashed (nvflash is only ever used with `--save`). The only other writes are local files (reports, logs), PCI link retrain/rescan sysfs triggers, and package installation during `--preflight` (explicitly gated behind the sudo precondition).