# DF-5084 — radeon_agp.c treats `ai_aperture_size` (BYTES) as MB

**Severity: Info (latent — code is not compiled on DragonFly today)**
**File:** `sys/dev/drm/radeon/radeon_agp.c` lines 152-157, 245
**Status of bug:** certain (source-level, proven); **not compiled** into any
shipped DragonFly kernel/module build (`IS_ENABLED(CONFIG_AGP)` == 0).

## What the bug is

`sys/dev/drm/kconfig.h` (the Linux kconfig shim force-included by every file
in the drm/radeon build, `sys/dev/drm/radeon/Makefile:148`) does **not**
define `CONFIG_AGP`. On this tree:

* `radeon_agp_init()` compiles to `#else return 0;` (`radeon_agp.c:256-258`),
* `radeon_agp_fini()` / `radeon_agp_resume()` compile to empty bodies,
* the quirk table is not emitted.

Inside that dead body there is a genuine porting defect: the file was
imported from an old Linux revision whose `agp_info.aper_size` was in **MB**,
but DragonFly's `agp_info.ai_aperture_size` is in **BYTES** tree-wide
(`vm_size_t`, `sys/dev/agp/agpvar.h:50`, filled from `rman_get_size()` of the
aperture BAR at `sys/dev/agp/agp.c:904`; corroborated by
`sys/dev/drm/drm_agpsupport.c:500` which prints `ai_aperture_size >> 20` as
"…M"). Consequences **if** the code is ever compiled:

* `radeon_agp.c:152` `ai_aperture_size < 32` intends "< 32 MB" — with bytes it
  is a dead check (an aperture is ≥ 4 MB = 4194304).
* `radeon_agp.c:245` `ai_aperture_size << 20` intends MB→bytes — with bytes it
  inflates `mc.gtt_size` by 2^20: a 64 MB aperture yields a 64 TB GTT
  (`gtt_end` ~2^46). Downstream 32-bit register writes truncate:
  `r100.c:662-663` `AIC_HI_ADDR` (window inverts: hi < lo),
  `r100.c:3864-3865`, `r300.c:1334-1335`, `r520.c:153-154` `MC_AGP_TOP`,
  `evergreen.c:2892-2894` `MC_VM_AGP_TOP/BOT`, `r600.c:1085-1086`; and the TTM
  GTT heap is sized 2^20x too big (`radeon_ttm.c:940-941`).
  GATT *binds* beyond the real aperture are still rejected by
  `sys/dev/agp/agp.c:520-522`, so the kernel-visible impact of the wrong
  `gtt_size` is functional corruption of the GPU DMA window programming plus
  failed/DoS GTT allocations — not a direct GATT OOB write.

## How to reproduce the *analysis* (no AGP hardware needed)

On the audit DragonFly guest (or any DF box with /usr/src):

```
vm.sh run_root 'cc -include /usr/src/sys/dev/drm/kconfig.h \
    -I/usr/src/sys/dev/drm/include -E /tmp/iscfg2.c | grep -v "^#" | grep -v "^$"'
cc -O2 -o /tmp/units_demo /tmp/units_demo.c && /tmp/units_demo
```

Expected (see `run.log`):

```
const char *agp   = "AGP_DISABLED";    <- the buggy body is NOT compiled
const char *pci   = "PCI_ENABLED";     <- control
const char *undef_ = "UNDEF_DISABLED"; <- control
const char *cik   = "CIK_ENABLED";     <- control
aper= 64M base=0xd0000000 -> gtt_size=0x0000400000000000 (64 TB) ... AIC_HI_ADDR=0xcfffffff (LO=0xd0000000 → inverted)
```

## Artifacts

* `iscfg2.c` — preprocessor reachability proof (radeon module's exact flags)
* `units_demo.c` — impact arithmetic demo (gtt_size / truncated registers)
* `build.sh`, `run.sh` — exact commands
* `run.log` — full decisive output; `env.txt` — guest env + md5 match vs audit tree
* `fix.diff` — 3-line units fix (authored after verification; never applied to sys/)

## Fix

Treat `ai_aperture_size` as bytes — see `fix.diff`.
