DF-4581 / DF-4581-trace.c
/* * 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; * } */ |