# DF-2212 — ttm_exit() uninterruptible deadlock (dead wait_event)

sys/dev/drm/ttm/ttm_module.c:98 — `ttm_exit()` ends with
`wait_event(exit_q, atomic_read(&device_released) == 1)` but the only
compiled setter of `device_released=1` is `#if 0`'d out; the init
success path zeroes it and success is guaranteed (dev_set_name and
drm_class_device_register are no-ops returning 0 on DF). The thread
that runs ttm_exit at module unload — the kldunload(2) thread via
linker_file_sysuninit (kern_linker.c:535) — sleeps uninterruptibly
forever: D-state, SIGKILL ignored, module half-unloaded.

**Verdict: reproduced** (baseline: 80 s watchdog, 16/16 samples blocked,
sigkill pending+ignored, D0/wchan "lwe"; fixed: exit returns in 0 ms,
500 clean init/exit cycles). Impact: unkillable-thread DoS wedge,
root-triggered (kldunload); no unprivileged reach, no memory
corruption. Severity Low.

## Reproduce (on the DragonFly audit guest)

```
# 1. push the pack to the guest (or use the copies under /root/poc/DF-2212)
#    df_ttm2212.c build.sh run.sh run_fixed.sh ttm_module_fixed.c fix.diff
# 2. build + install the baseline harness kernel (pristine ttm_module.c,
#    sha256-gated 56d64f99e2ee74fee71bdb775463f51cbc6a1d3f9096f2da25af60b55ab26b8e)
sh build.sh baseline            # make -j6 nativekernel KERNCONF=DFV2212
cp /usr/obj/usr/src/sys/DFV2212/kernel.stripped /boot/kernel/kernel
cp /usr/obj/usr/src/sys/DFV2212/kernel.debug   /boot/kernel/kernel.debug
shutdown -r now
# 3. run the baseline test (~100 s)
sh run.sh                       # -> run.log: D0 state, wchan lwe,
                                #    kill -9 ignored, watchdog verdict

# 4. apply the fix, rebuild, rerun
cp ttm_module_fixed.c /usr/src/sys/dev/drm/ttm/ttm_module.c   # == fix.diff applied
sh build.sh fixed
cp /usr/obj/usr/src/sys/DFV2212/kernel.stripped /boot/kernel/kernel
cp /usr/obj/usr/src/sys/DFV2212/kernel.debug   /boot/kernel/kernel.debug
shutdown -r now
sh run_fixed.sh                 # -> run_fixed.log: returns in 0 ms,
                                #    500 cycles, nothing stuck
```

Success criterion (baseline): `ps` shows the trigger process in state
`D0` with wchan `lwe` at t=3 s, 6 s, 33 s and 93 s after `kill -9`;
kernel log shows 16/16 watchdog samples with `TDF_TSLEEPQ=YES
wmesg="lwe" device_released=0 sigkill_pending=1` and the final WATCHDOG
VERDICT line; the trigger sysctl never returns. Success criterion
(fixed): `ttm_exit() RETURNED after 0 ms`, 500 init/exit cycles
complete, no stuck processes.

## Rig

`df_ttm2212.c` is compiled into the kernel (config DFV2212 =
X86_64_GENERIC + `device dfverify`) and `#include`s the REAL
`<dev/drm/ttm/ttm_module.c>` (sha256-gated by build.sh) plus verbatim
lkpi `linux_wait.c`/`linux_sched.c`. The two drm_sysfs externs are
provided with exactly the shipped semantics (drm_sysfs.c:60-75).
`module_init(ttm_init)` runs at boot (control); `hw.df_ttm2212.trigger`
calls the real `ttm_exit()` in the calling thread (kldunload-thread
simulation); a 5 s callout watchdog samples the blocked thread.

## Files

* `df_ttm2212.c` — harness (verbatim interposition)
* `build.sh` — sha256-gated baseline/fixed kernel build
* `run.sh` / `run_fixed.log`-companion `run_fixed.sh` — test drivers
* `ttm_module_fixed.c` — pristine+fix.diff (sha256 4faabe2f…)
* `fix.diff` — the verified one-hunk fix
* `build.log` / `fix_build.log` — FULL untrimmed kernel builds
* `run.log` — FULL baseline runtime output (decisive)
* `run_fixed.log` — FULL fixed runtime output
* `trigger.out` — baseline trigger process stdout (no exit line)
* `dmesg.txt` — full dmesg spanning baseline and fixed eras
* `env.txt` — guest environment
* `VERDICT.md` — full narrative
* `manifest.json` / `verdict.json` — machine-readable
