# DF-3900 — i915 MMIO register mapping (and shim bus resource) leaked on every driver detach

**File:** `sys/dev/drm/i915/i915_drv.c`
**Class:** resource leak / teardown asymmetry (DF-3768 twin, distinct resource)
**Severity:** Low (root-gated: kldload/kldunload of `i915kms.ko`, or error-probe → re-probe)

## What

`i915_mmio_setup()` (i915_drv.c:1027) maps the MMIO BAR:

```c
dev_priv->regs = pci_iomap(pdev, mmio_bar, mmio_size);   /* 512KB gen<5, 2MB gen>=5 */
```

On DragonFly, `pci_iomap()` (sys/dev/drm/include/linux/pci.h:299) =
`pci_resource_start()` + `pci_resource_len()` + `ioremap(base, size)`:
 * `pci_resource_start` does `bus_alloc_resource_any(..., RF_SHAREABLE)` and the
   caller never releases that resource (shim-wide issue), and
 * `ioremap()` → `__ioremap_common()` (sys/dev/drm/linux_iomapping.c:44) does
   `pmap_mapdev_attr()` (kernel KVA) and links a `kmalloc`'d `struct iomap`
   onto the global `iomap_list`.

The **only** unmap call anywhere under `sys/dev/drm/i915/` is compiled out:

```c
static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)   /* :1040 */
{
	intel_teardown_mchbar(dev_priv);
#if 0
	pci_iounmap(pdev, dev_priv->regs);      /* :1048 — never compiled */
#endif
}
```

`intel_uncore_fini()` (intel_uncore.c:1643 — called on the same unload path,
i915_drv.c:1867 → 1105) only sanitizes/forcewake-resets; it does not unmap.
`i915_driver_unload()` therefore never releases `dev_priv->regs`.

## Impact

Every i915 attach/detach cycle (kldload/kldunload i915kms.ko, or a probe that
fails after `i915_driver_init_mmio()` and is retried) permanently leaks:
 * 512KB / 2MB of `pmap_mapdev` KVA,
 * one `struct iomap` node on the global list, and
 * one bus-resource acquisition of the MMIO BAR.

Unbounded accumulation; on 32-bit kernels KVA exhaustion is realistic, on
64-bit it is a slow permanent leak. Root-gated (module load), no unprivileged
path, no memory corruption. Same class as DF-3768 (GGTT fictitious range,
i915_gem_gtt.c) but a distinct leaked resource and a distinct fix.

## Reproduce (on hardware with an Intel GPU)

See `mml_leak_cycle.sh` — kldload/kldunload loop; after N cycles
`vmstat -m | grep drm` / KVA map inspection shows N leaked iomap nodes
(2MB KVA each on gen5+). **Not runnable on this audit guest** (virtio VGA
only, no /dev/dri, no i915 device) — status honestly `inconclusive`,
source-certain (rg proves the single #if 0'd pci_iounmap).

## Fix

Un-`#if 0` the unmap in `i915_mmio_cleanup()` (fix.diff) — `iounmap(dev_priv->regs)`
undoes exactly what `pci_iomap()` did (`pmap_unmapdev` + node removal).
