linux/io: handle memtype_wc mapping for !DMAP range

The amdgpu driver in drm-kmod will attempt to update/reserve certain GPU
VRAM ranges as write-combining. Depending on the system, this address
range may fall outside of FreeBSD's constructed DMAP. We cannot use
pmap_change_attr() in this case.

When INVARIANTS is enabled, this results in the following:

  panic: physical address 0x880000000 not covered by the DMAP

Add a guard against triggering the KASSERT in PHYS_TO_DMAP().

This limitation in our implementation of arch_io_reserve_memtype_wc() is
already known in drm-kmod's amdgpu_bo_init(), and errors are ignored
there (see "BSDFIXME"). This change is only to eliminate the preventable
assertion failure within this scheme.

Tested by:	kevans
Reviewed by:	kib, emaste
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D56971
This commit is contained in:
Mitchell Horne
2026-05-14 11:20:22 -03:00
parent 4cdcacb9b2
commit 988c039804
@@ -544,6 +544,9 @@ arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
#if defined(__amd64__)
void *va;
if (!PHYS_IN_DMAP(start) || !PHYS_IN_DMAP(start + size))
return (-EINVAL);
va = PHYS_TO_DMAP(start);
return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
#else
@@ -557,8 +560,10 @@ arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
#if defined(__amd64__)
void *va;
va = PHYS_TO_DMAP(start);
if (!PHYS_IN_DMAP(start) || !PHYS_IN_DMAP(start + size))
return;
va = PHYS_TO_DMAP(start);
pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
#endif
}