PCI hotplug resource assignment: hpmmiosize, realloc and BAR placement

PCI hotplug resource assignment: hpmmiosize, realloc and BAR placement

How Linux assigns bridge windows and BARs to a Thunderbolt-attached GPU — BIOS-built tunnels versus kernel re-enumeration, pci=realloc and the hpmmio sizes, why thunderbolt.host_reset makes the card re-enter as a hot-added device with a 256 MB BAR, why a rebuilt bridge path can keep memory decoding off, and how to verify each step.


name: linux-pcie-hotplug-bar-allocation title: Linux PCIe resource allocation for Thunderbolt/USB4 eGPUs — firmware tunnels vs kernel re-enumeration, bridge windows, BARs, COMMAND bits, ReBAR description: >- Expert reference for why a Thunderbolt/USB4-attached GPU comes up with an unusable BAR (0xffffffff MMIO reads, 256 MB BAR instead of 16 GB, bridges with Mem-/BusMaster-) after Linux re-enumerates a firmware-built PCIe tunnel, and what each kernel parameter (pci=realloc/realloc=off, hpmmiosize, hpmmioprefsize, hpiosize, hpbussize, assign-busses, nocrs, hpmemsize, pcie_ports=native/compat, pcie_port_pm, pcie_aspm, iommu=pt, thunderbolt.host_reset, thunderbolt.clx) actually does, with kernel-source citations. TRIGGER: eGPU BAR/bridge-window failures, “failed to assign”, “no space”, “can’t claim”, Mem decode off after hotplug, ReBAR over Thunderbolt, host_reset regressions, kernel 6.x-7.x resource-fitting changes. SKIP: GPU driver bugs unrelated to enumeration; desktop-slot ReBAR with no Thunderbolt; Windows/macOS. verified-as-of: 2026-09-24

Linux PCIe resource allocation for Thunderbolt/USB4-attached GPUs

Verified-as-of: 2026-09-24. Web-research only; nothing on the reference machine was probed for this document. Every claim is tagged [SOURCED <url>] (text or code seen at that URL) or [INFERRED] (reasoning from sourced facts; not independently verified). Kernel code quoted from torvalds/linux master as fetched on 2026-09-24.

Anchor case (worked example)

NUC 15 Pro (Arrow Lake-P), Ubuntu 26.04.1, kernel 7.0.0-34, RTX 5080 in Razer Core X V2 over TB4. Enclosure switch reports Intel 8086:5786, which is the JHL9586 “Barlow Ridge Hub 80G” (Thunderbolt 5 / USB4 v2 hub) [SOURCED https://ratatoskr.run/linux-usb/2026/07/17208566/t (search-result summary of the JHL9580 RFC thread; the ID→name mapping was not re-read from the thread body — treat as probable)].

Failing configuration: pci=realloc,hpmmioprefsize=32G,hpmmiosize=512M with default thunderbolt.host_reset=1. Observed (as reported on this box): kernel rebuilt the tunnel ~1.4 s into boot; afterwards the enclosure bridges had Mem decode OFF; GPU BAR0 read 0xffffffff although config space answered; BAR1 came up 256 MB despite 16 GB ReBAR support; bridge 03:00.0 prefetch window ~16.7 GB, non-prefetch 65 MB.

Working configuration: thunderbolt.host_reset=0 pci=realloc=off pcie_ports=native pcie_port_pm=off pcie_aspm=off thunderbolt.clx=0 iommu=pt plus a post-bolt service doing setpci -s <each bridge> COMMAND=0x0006:0x0006 before modprobe nvidia.

The rest of this document explains why each of those knobs matters, what is load-bearing, and what is cargo.


Core Concepts

1. Two enumerators: firmware at POST vs. the kernel at hotplug time

2. How hotplug bridge windows are sized (drivers/pci/setup-bus.c)

3. Why a hot-added GPU ends up with a 256 MB BAR

4. BAR0 reading 0xffffffff while config space works

5. Bus numbers are pre-reserved too


Kernel Parameter Reference

Exact semantics from Documentation/admin-guide/kernel-parameters.txt and the source. “Effect here” = relevance to the anchor symptom set; those judgements are [INFERRED] unless tagged otherwise.

Parameter Exact semantics (source) Side effects / caveats Effect on the anchor case
pci=realloc / pci=realloc=on “Enable/disable reallocating PCI bridge resources if allocations done by BIOS are too small to accommodate resources required by all child devices. off: Turn realloc off; on: Turn realloc on” [SOURCED wording reproduced in https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/9.2_release_notes/kernel_parameters_changes and https://www.kernel.org/doc/html/v4.16/admin-guide/kernel-parameters.html; canonical file https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt]. Internally pci_realloc_enable states: “-1: undefined, will auto detect later / 0: disabled by user / 1: disabled by auto detect / 2: enabled by user / 3: enabled by auto detect”; auto-enables when unassigned SR-IOV resources exist [SOURCED setup-bus.c]. Releases BIOS bridge windows and re-runs the fitting loop (leaf first, then whole subtree). Can shrink or move windows the BIOS sized generously. Maintainer note: “Risks: May worsen resource fit or exhaust iomem space” [SOURCED https://ratatoskr.run/linux-pci/2026/03/14618943/t]. Harmful when the goal is to keep BIOS-built ReBAR allocations: realloc lets the kernel undo the BIOS windows. Reports: “pci=realloc=on alone — no effect on populated bridge” [SOURCED LF forum]; “pci=realloc — no effect on pre-populated bridges” [SOURCED Sept-2026 thread].
pci=realloc=off “Do not reconfigure PCI device resources” / “off: Turn realloc off” [SOURCED same]. Sets pci_realloc_enable = 0 (disabled by user). Kernel keeps BIOS/firmware bridge windows and BARs for boot-present devices; hot-added devices are still assigned by the normal hotplug path. Load-bearing with host_reset=0: keeps the POST-time (ReBAR-exercised) allocation intact.
pci=hpmmioprefsize=nn[KMG] “The fixed amount of bus space which is reserved for hotplug bridge’s MMIO_PREF window. Default size is 2 megabytes.” Parsed as pci_hotplug_mmio_pref_size = memparse(...) [SOURCED https://lkml.iu.edu/hypermail/linux/kernel/1910.2/07833.html]. Applied to every hotplug bridge, including empty TB hub ports, so a big value multiplies: 32 G × 4 ports on one hub. Can cause the parent to fail to fit: “pci=hpmmioprefsize=32G — worsened situation; GPU disappeared entirely” [SOURCED https://ratatoskr.run/linux-pci/2026/09/17551273/t]; “cannot fit 0x1000000000 required for 0000:94:01.0 bridging” [SOURCED https://ratatoskr.run/linux-pci/2026/04/8893590/t]. Does not make a hot-added GPU’s BAR bigger (hot-add never resizes BARs, §1). Only useful if you later resize via sysfs/driver and need headroom — and even then siblings pin windows (§3).
pci=hpmmiosize=nn[KMG] “The fixed amount of bus space which is reserved for hotplug bridge’s MMIO window. Default size is 2 megabytes.” [SOURCED same]. Non-prefetchable 32-bit window; must fit below 4 GB with everything else. Irrelevant to VRAM BARs (64-bit pref). A 512 M value is harmless but pointless for this symptom.
pci=hpmemsize=nn[KMG] “reserved for hotplug bridge’s MMIO and MMIO_PREF window. Default size is 2 megabytes.” Sets both pci_hotplug_mmio_size and pci_hotplug_mmio_pref_size [SOURCED same]. Legacy knob kept “to prevent disruptions to existing users”. Prefer the two specific knobs.
pci=hpiosize=nn[KMG] “The fixed amount of bus space which is reserved for hotplug bridge’s IO window. Default size is 256 bytes.” [SOURCED same]. I/O port space is 64 KB total; large values exhaust it. GPUs need at most a small legacy VGA I/O BAR; not relevant to BAR0/BAR1.
pci=hpbussize=nn “The minimum amount of additional bus numbers reserved for buses below a hotplug bridge. Default is 1” [SOURCED same]. Too small → pci_hp_add_bridge() “No bus number available for hot-added bridge” [SOURCED https://bbs.archlinux.org/viewtopic.php?id=253050 title; lobste.rs commentary]. Too large → bus numbers (max 256/segment) run out for other root ports. Relevant for deep TB5 hub + enclosure + GPU-internal-switch topologies; a working Ubuntu 26.04 config used hpbussize=0x33 [SOURCED https://discourse.ubuntu.com/t/external-gpu-rtx-6000-pro-on-ubuntu-25-10-26-04/77130].
pci=assign-busses “Assign all PCI bus numbers ourselves, overriding whatever the firmware provided” [SOURCED https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html]. Discards firmware bus numbering; reported “counterproductive” for a TB eGPU [SOURCED https://ratatoskr.run/linux-usb/2026/08/17378667/t]. Anti-pattern here.
pci=nocrs “[X86] Ignore PCI host bridge windows from ACPI” (_CRS) [SOURCED RH/kernel.org v4.16 wording above]. Kernel invents host-bridge windows instead of using ACPI; can overlap platform reserved ranges. Reported: “system failed to boot; NVMe probe returned -ENOMEM” [SOURCED https://ratatoskr.run/linux-pci/2026/09/17551273/t]; “sometimes broke booting entirely” [SOURCED Ubuntu discourse]. Anti-pattern; last resort only when _CRS is provably wrong.
pcie_ports=native “Use native PCIe services for PME, AER, and DPC, even if the platform doesn’t give the OS permission to use them. This may cause conflicts if the platform also tries to use these services.” compat: “Disable native PCIe services (PME, AER, DPC, PCIe hotplug).” dpc-native: “Use native PCIe service for DPC only.” [SOURCED https://www.spinics.net/lists/linux-pci/msg88329.html (doc diff)]; code: pcie_ports_native = true “use the PCIe services regardless of whether the platform has given us permission” [SOURCED https://raw.githubusercontent.com/torvalds/linux/master/drivers/pci/pcie/portdrv.c]. Forces Linux ownership of hotplug/AER/DPC when _OSC withholds it; may fight SMM/firmware-first handling. Relevant only if pciehp was not getting native control (check `dmesg
pcie_port_pm=off “PCIe port power management handling: off — Disable power management of all PCIe ports, force — Forcibly enable power management of all PCIe ports”. Default allows D3 for ports on systems with BIOS date ≥ 2015 (pci_bridge_d3_possible()) [SOURCED https://github.com/torvalds/linux/commit/9d26d3a8f1b0c442339a235f9508bdad8af91043]. Keeps the TB root port / tunnel bridges in D0; avoids runtime-suspend/D3cold transitions of the bridges over the GPU. Stability aid (link drops, Xid 79) rather than a BAR fix [INFERRED].
pcie_aspm=off Current doc: “off — Don’t touch ASPM configuration at all. Leave any configuration done by firmware unchanged.” The older text “Disable ASPM” was “wrong” [SOURCED https://patchew.org/linux/[email protected]/]. It does not disable ASPM; it stops Linux from managing it. To actually force links out of L0s/L1 use pcie_aspm.policy=performance (used in working Ubuntu 26.04 configs) [SOURCED Ubuntu discourse; Titan Ridge thread: “pcie_aspm.policy=performance … necessary to avoid losing hotplug support”]. Likely inert for BAR assignment; may leave firmware ASPM on. If ASPM-induced link errors are suspected, pcie_aspm.policy=performance is the effective knob [INFERRED].
iommu=pt “pt: Use passthrough mode by default (Equivalent to iommu.passthrough=1)”; nopt the reverse [SOURCED https://raw.githubusercontent.com/torvalds/linux/master/Documentation/admin-guide/kernel-parameters.txt]. Identity-maps DMA for trusted devices. Thunderbolt-attached devices are marked untrusted and Intel IOMMU keeps them in a translated DMA domain even under pt (the driver refuses identity mapping for untrusted devices) [INFERRED — from memory of device_def_domain_type() in drivers/iommu/intel/iommu.c; verify before relying]. Kernel DMA protection is exposed at /sys/bus/thunderbolt/devices/domainX/iommu_dma_protection [SOURCED thunderbolt.rst]. Probably no effect on the eGPU’s mappings or BARs; harmless.
thunderbolt.host_reset=0 static bool host_reset = true; module_param(host_reset, bool, 0444); MODULE_PARM_DESC(host_reset, "reset USB4 host router (default: true)"); Passed as tb_domain_add(tb, host_reset) → tb->cm_ops->start(tb, reset) [SOURCED https://raw.githubusercontent.com/torvalds/linux/master/drivers/thunderbolt/nhi.c, …/domain.c]. See next section. Keeps firmware-built tunnels (and their BIOS-assigned windows/BARs) alive across driver probe. Works for cold-plug only: “if the eGPU is power-cycled at runtime, the new tunnel gets the 256 MB default” [SOURCED https://ratatoskr.run/linux-pci/2026/03/14618943/t]. The load-bearing fix.
thunderbolt.clx=0 module_param_named(clx, clx_enabled, bool, 0444); MODULE_PARM_DESC(clx, "allow low power states on the high-speed lanes (default: true)"); — CL0s/CL1/CL2 link states; not enabled on pre-Alder-Lake Intel USB4; skipped for inter-domain and unbonded links [SOURCED https://raw.githubusercontent.com/torvalds/linux/master/drivers/thunderbolt/clx.c]. Keeps the USB4 link in CL0 (no lane low-power). Stability/latency aid only; unrelated to PCI resource assignment [INFERRED].
thunderbolt.dyndbg=+p Standard dynamic-debug enable for the module (used with host_reset=false in field reports) [SOURCED https://lkml.iu.edu/hypermail/linux/kernel/2405.0/03998.html (search summary)]. Verbose tunnel/CM logging. Diagnostic only.

Thunderbolt host_reset and tunnel rebuild

What the driver does at probe

  1. nhi_probe() calls nhi_reset(nhi): “Reset only v2 and later routers” (REG_CAPS_VERSION >= 2); if !host_reset it logs “skipping host router reset”; on timeout it warns “timeout resetting host router” [SOURCED nhi.c]. Origin: “USB4 v2 added a bit that can be used to reset the host router so the kernel uses this to trigger reset when the driver probes. This resets the already connected topology as well but doing this simplifies things a lot if the link is already set to asymmetric, and a module parameter was added to prevent this in case of problems” (Thunderbolt maintainer, June 2023) [SOURCED https://patches.linaro.org/project/linux-usb/patch/[email protected]/ (search summary)].
  2. tb_domain_add(tb, host_reset) → software CM tb_start(tb, reset):
    if (reset && tb_switch_is_usb4(tb->root_switch)) {
        discover = false;
        if (usb4_switch_version(tb->root_switch) == 1)
            tb_switch_reset(tb->root_switch);
    }
    with the comment: “Boot firmware might have created tunnels of its own. Since we cannot be sure they are usable for us, tear them down and reset the ports to handle it as new hotplug for USB4 v1 routers (for USB4 v2 and beyond we already do host reset).” When not resetting, tb_discover_tunnels(tb) adopts the firmware tunnels and marks their routers sw->boot = true [SOURCED https://raw.githubusercontent.com/torvalds/linux/master/drivers/thunderbolt/tb.c].
  3. Origin of the v1 tear-down: commit 59a54c5f3dbd “thunderbolt: Reset topology created by the boot firmware” (the commit author): “Boot firmware (typically BIOS) might have created tunnels of its own. The tunnel configuration that it does might be sub-optimal … In addition there is an issue on some AMD based systems where the BIOS does not allocate enough PCIe resources for future topology extension. By resetting the USB4 topology the PCIe links will be reset as well allowing Linux to re-allocate. This aligns the behavior with Windows Connection Manager.” [SOURCED https://github.com/torvalds/linux/commit/59a54c5f3dbd]. Follow-up “thunderbolt: Reset only non-USB4 host routers in resume” (2024-01-31, Fixes: 59a54c5f3dbd) limits the resume reset to Apple/Intel non-USB4 hosts [SOURCED https://git.zx2c4.com/linux-rng/commit/drivers/thunderbolt?id=8cf9926c537ce8b0c7783afebe752e084765d553].

What the reset does to an existing PCIe tunnel


Bridge COMMAND registers (Mem decode / Bus Master)

How the kernel normally sets them

Why bridges can come up with Mem decode / Bus Master cleared

Ranked by plausibility for the anchor case; all [INFERRED] from the sourced mechanics above unless noted:

  1. Bridge window not claimed/assigned. After re-enumeration, if a bridge’s prefetch window could not be fitted (bridge window … cannot fit, can't claim; no compatible bridge window, no space), r->parent is NULL and pci_enable_resources() never sets PCI_COMMAND_MEMORY on that bridge — while the base/limit registers may still hold stale (BIOS or kernel-provisional) values. MMIO through it returns all-ones. The anchor case’s odd 16.7 GB prefetch window on 03:00.0 alongside a 256 MB GPU BAR is consistent with a partially failed fit.
  2. Bridge windows kept from BIOS but not claimable. With host_reset=0 realloc=off, BIOS windows are left in the registers; if pci_claim_resource() fails for one of them (parent window mismatch vs _CRS, or overlap), the kernel keeps the register values but refuses to enable decode. setpci COMMAND=0x0006:0x0006 then “works” because the hardware windows are in fact correct and only the software gate was missing. This is the most likely reason the post-bolt setpci service was still needed with the otherwise-correct configuration.
  3. Enable-count already positive. pci_enable_bridge() skips pci_enable_device() when pci_is_enabled(dev) is already true and only re-asserts Bus Master if !dev->is_busmaster. If something cleared COMMAND after portdrv enabled the port (a secondary-bus reset does not clear it, but a power-cycle of the enclosure or D3cold of a bridge without a restore path can), nothing re-writes the Memory bit for that bridge. pcie_port_pm=off reduces this class.
  4. Bolt authorization timing. With security level user/secure, “the connected device must be authorized by the user before PCIe tunnels are created (e.g the PCIe device appears)” [SOURCED thunderbolt.rst]; the tunnel — and the whole enumeration — happens when bolt authorizes, so a udev/systemd ordering after bolt is the right hook.

setpci mask syntax: each value is “either a hexadecimal number or an expression of type data:mask”; COMMAND is the “word-sized command register” at offset 4 [SOURCED https://man7.org/linux/man-pages/man8/setpci.8.html]. COMMAND=0x0006:0x0006 sets bit1 (Memory Space Enable) and bit2 (Bus Master Enable) and leaves the rest untouched. It is a symptomatic fix: it does not make an unassigned window valid; verify base/limit first (see Verification).


Resizable BAR


Changes in kernels 6.x-7.x that matter here

Version Change Source
5.5 pci=hpmmiosize / pci=hpmmioprefsize split out of hpmemsize (Nicholas Johnson) [SOURCED https://lkml.iu.edu/hypermail/linux/kernel/1910.2/07833.html]
6.6 (posted 2023-06) USB4 v2 NHI host-router reset at probe + thunderbolt.host_reset param (Thunderbolt maintainer) [SOURCED linaro patchwork summary]
6.9 / backported to 6.8.8 tb_start() tears down firmware tunnels on USB4 v1 hosts (59a54c5f3dbd) — the cause of the 6.8.7→6.8.8 eGPU regression reports; host_reset=0 is the documented workaround [SOURCED github commit; regression thread]
6.9 Resume-path reset limited to non-USB4 hosts (8cf9926c537c) [SOURCED zx2c4 mirror]
6.18 (series posted 2025-08) “PCI: Bridge window selection improvements” — unified pbus_select_window(), preserves window type flags, common pci_enable_resources() [SOURCED https://lwn.net/Articles/1034828/] — merge version [INFERRED]
6.18.20 / 7.0-rc5 Regression from “PCI: Stop over-estimating bridge window size” (3958bf16): amdgpu “Problem resizing BAR0 (-16)” over TB; fixed by “PCI: Prevent shrinking bridge window from its required size” (dc4b4d04) in 7.1-rc1 [SOURCED https://ratatoskr.run/linux-pci/2026/03/7140240/t]
7.1 (pull 2026-04-15) “Avoid shrinking bridge windows to fit in the initial Root Port window; fixes one problem with devices with large BARs connected via switches, e.g., Thunderbolt”; place small resources before large; pass full free extent to resource_alignf; alignment fix for windows >1 MB [SOURCED https://ratatoskr.run/lkml/2026/04/3515371/t]
7.3 (applied 2026-07-22) “PCI: Do not add hotplug reservation for intermediate bridges”: size = max(size + children_add_size, min_size) so nested TB topologies stop multiplying the hp* reservation at every tier [SOURCED https://ratatoskr.run/lkml/2026/07/17285367/t]
pending ReBAR-aware resource fitting (a PCI developer); “don’t assign bridge windows that have no real resources underneath” post-pass [SOURCED ReBAR thread]

Implication for the anchor box on 7.0.0-34: it has the 6.18-era window-selection rework but not the 7.1 “avoid shrinking” fix nor the 7.3 nested-reservation fix; both are directly about large BARs behind Thunderbolt switches. Re-testing on ≥7.1 (and ideally 7.3) before adding more workarounds is justified [INFERRED].


Verification checklist

Run as root. Replace BB:DD.F with the bridge/GPU BDF; lspci -t shows the chain root port → host-side TB bridge → hub upstream → hub downstream → enclosure switch → GPU.

  1. Topology and driver ownership
    • lspci -tv — “Show a tree-like diagram containing all buses, bridges, devices” [SOURCED lspci(8)].
    • dmesg | grep -iE 'thunderbolt|tb_|connection manager' — expect “using software connection manager” or “using firmware connection manager” (Titan-Ridge-class hosts use firmware CM: “it’s not the TB driver that creates the tunnels”) [SOURCED https://ratatoskr.run/linux-usb/2026/08/17378667/t]; with host_reset=0 expect “skipping host router reset” (v2 hosts) [SOURCED nhi.c].
    • cat /sys/bus/thunderbolt/devices/*/authorized and boltctl list — device must be authorized before the PCIe tunnel exists [SOURCED thunderbolt.rst].
    • cat /sys/bus/thunderbolt/devices/domain0/iommu_dma_protection [SOURCED thunderbolt.rst].
  2. Resource assignment
    • dmesg | grep -E "BAR [0-9]+|bridge window|can't (assign|claim)|no space|failed to assign|not claimed|cannot fit|was not released" Exact strings: %s %pR: assigned, can't assign; no space, can't assign; bogus alignment, failed to assign, can't claim; no address assigned, can't claim; no compatible bridge window, can't claim; address conflict with …, not assigned; can't enable device, not claimed; can't enable device, enabling device (0000 -> 0002) [SOURCED setup-res.c]; bridge window … cannot fit …, … was not released (still contains assigned resources) [SOURCED linux-pci threads].
    • cat /proc/iomem — “Memory map” of physical ranges; confirm the GPU’s BARs are nested inside every bridge window above them and the root port window [SOURCED https://www.kernel.org/doc/html/latest/filesystems/proc.html].
    • lspci -vvs <GPU> — Region 1: Memory at … (64-bit, prefetchable) [size=16G]; [virtual] or [disabled] markers indicate unassigned/undecoded regions [INFERRED — lspci output conventions, not quoted from the man page].
    • cat /sys/bus/pci/devices/0000:<GPU>/resource1_resize — bitmap of supported sizes [SOURCED sysfs-bus-pci].
  3. COMMAND registers
    • setpci -s BB:DD.F COMMAND for the GPU and each bridge; want bit1 (0x2 Memory) and bit2 (0x4 Bus Master) set. lspci -vvs BB:DD.F | grep -E 'Control:|Memory behind|Prefetchable memory behind' — Mem+ BusMaster+ and sane base/limit ranges [SOURCED setpci(8), lspci(8) for option semantics; field names INFERRED].
    • Before forcing bits: confirm Prefetchable memory behind bridge: on each bridge encloses the GPU BAR; if it is [disabled]/empty, forcing Mem+ will not help.
  4. Link health — lspci -vvs <GPU> | grep -E 'LnkSta|LnkCap'; USB4 v1 caps at 16 GT/s x4 (~3.8 GB/s observed) [SOURCED Sept-2026 thread; Ubuntu discourse]; AER storms at boot are a host-reset side effect on some platforms [SOURCED MS-02-Ultra issue].

Decision guide for this symptom set

Symptoms: eGPU enumerates; BAR reads 0xffffffff; bridges Mem-; BAR1 256 MB; possibly large odd prefetch window.

  1. Does firmware build a PCIe tunnel at POST? (host_reset=0 boot → is the GPU present in lspci before bolt authorizes anything, with a large BAR?)
    • Yes → use thunderbolt.host_reset=0 pci=realloc=off. Do not add hpmmioprefsize/realloc: they only apply to kernel-built windows and can make the fit worse. Accept that runtime replug will fall back to 256 MB (that is the documented limitation) [SOURCED ReBAR thread].
    • No (no tunnel/BARs until the kernel builds them) → host_reset=0 is inert; you are in the hot-add path. Options: (a) resize via sysfs after removing empty sibling ports, then rescan [SOURCED Ilpo]; (b) modest hpmmioprefsize (e.g. 2-4× the target BAR, not 32 G) plus hpbussize sized to the topology; (c) upgrade to ≥7.1 / 7.3 for the window-fitting fixes [SOURCED 7.1 pull; 7.3 patch].
  2. Bridges Mem- although windows look right → check dmesg for can't claim / not claimed on those bridges. If the base/limit values enclose the GPU BAR, setpci -s <bridge> COMMAND=0x0006:0x0006 after bolt authorization and before modprobe nvidia is a legitimate stop-gap; file the can't claim line upstream (linux-pci) because it is a fitting bug, not a hardware fault [INFERRED].
  3. Bridges Mem- and windows [disabled]/absent → the fit failed; setpci on COMMAND cannot help. Go back to step 1 or remove sibling ports and rescan.
  4. Stability knobs (pcie_port_pm=off, thunderbolt.clx=0, pcie_aspm.policy=performance, Link Control 2 “auto speed disable” setpci -s <TB bridge> CAP_EXP+30.w=0020:0020) address link drops/Xid 79 after the GPU works; they are not part of the BAR fix [SOURCED Ubuntu discourse for the LnkCtl2 trick; rest INFERRED].
  5. Keep pcie_ports=native only if dmesg shows _OSC denying native hotplug/AER control and hotplug events were being missed; otherwise drop it to avoid firmware conflicts [SOURCED kernel-parameters wording].

Minimal recommended command line for the anchor box, derived from the above: thunderbolt.host_reset=0 pci=realloc=off (+ pcie_port_pm=off if link drops recur) — then prove or disprove the need for each extra knob one at a time.


Anti-patterns


Sources

Primary (kernel tree / kernel.org)

LKML / linux-pci / linux-usb (2019-2026)

Community / vendor