git: 6d526fa72b72 - stable/14 - linux/io: handle memtype_wc mapping for !DMAP range

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Thu, 11 Jun 2026 17:12:01 UTC
The branch stable/14 has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=6d526fa72b723f28e72e0e8ff40029f0ae7db9b9

commit 6d526fa72b723f28e72e0e8ff40029f0ae7db9b9
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2026-05-14 14:20:22 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-06-11 17:11:40 +0000

    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
    
    (cherry picked from commit 988c03980452a56fb0fbb15e18b0a644602d0ab3)
---
 sys/compat/linuxkpi/common/include/linux/io.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h
index 164347dbc4e7..021add1153f7 100644
--- a/sys/compat/linuxkpi/common/include/linux/io.h
+++ b/sys/compat/linuxkpi/common/include/linux/io.h
@@ -547,6 +547,9 @@ arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
 #if defined(__amd64__)
 	vm_offset_t 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
@@ -560,8 +563,10 @@ arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
 #if defined(__amd64__)
 	vm_offset_t 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
 }