/*
 * DF-4581 — code-level reproduction scaffold.
 *
 * radeon_cs_parser_relocs() (sys/dev/drm/radeon/radeon_cs.c:190-192):
 *
 *     if (p->cs_flags & RADEON_CS_USE_VM)
 *         p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated);
 *
 * The return value is never checked.  radeon_vm_get_bos()
 * (sys/dev/drm/radeon/radeon_vm.c:128-163) returns NULL when its
 * kvmalloc_array() fails, AFTER NOTHING was added to @head — so on failure
 * the VM page directory and page tables are silently ABSENT from
 * p->validated:
 *   - they are never reserved (ttm_eu_reserve_buffers) nor validated/pinned,
 *   - they get no fence from ttm_eu_fence_buffer_objects (radeon_cs.c:427),
 *   - yet radeon_cs_ib_vm_chunk() -> radeon_bo_vm_update_pte()
 *     (radeon_cs.c:565) proceeds to radeon_vm_update_page_directory(),
 *     which submits a DMA IB that writes PDEs at pd_addr captured from
 *     radeon_bo_gpu_offset(pd) (radeon_vm.c:…) — a BO whose placement is
 *     not pinned for this submission and can be evicted/moved concurrently
 *     → GPU writes to a stale address (freed/reused memory), plus unsynced
 *     eviction while the IB executes.
 *
 * On DragonFly as compiled this is LATENT: kvmalloc_array()->kmalloc() with
 * GFP_KERNEL (M_WAITOK, no M_NULLOK) never returns NULL — it panics or
 * hangs instead (see DF-4580).  It becomes live the moment the DRM port
 * gains M_NULLOK semantics for kvmalloc (as any fix for DF-4580's panic
 * class should), and it is a live upstream bug on Linux where kmalloc
 * failure returns NULL.
 *
 * This guest has no radeon GPU, so no runtime trigger is possible here;
 * this file documents the exact trace and the one-line fix.
 */
#define DF_4581_CODE_TRACE_ONLY 1

/*
 * Required fix (see fix.diff):
 *
 *     p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated);
 *     if (p->vm_bos == NULL) {
 *             DRM_ERROR("Failed to get vm bos!\n");
 *             return -ENOMEM;
 *     }
 */
