git: bb01efa6f87a - stable/14 - linuxkpi: Fix uses of `pmap_change_attr()`

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Sat, 17 Feb 2024 21:32:27 UTC
The branch stable/14 has been updated by wulf:

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

commit bb01efa6f87a8588f0190fe778f2376736c93acc
Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2023-08-16 20:32:42 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2024-02-17 20:58:34 +0000

    linuxkpi: Fix uses of `pmap_change_attr()`
    
    [Why]
    This function takes an offset and a length as argument, not a physical
    address and a number of pages.
    
    This misuse caused the `set_memory_*()` and
    `arch_io_reserve_memtype_wc()` functions to return EINVAL.
    
    Another problem was the fact that they returned errors as a positive
    integer, whereas Linux uses negative integers.
    
    [How]
    Physical addresses and number of pages are converted to offset+length in
    the `set_memory_*()` functions.
    
    `arch_io_reserve_memtype_wc()` now calls `pmap_change_attr()` directly
    instead of using `set_memory_wc()`.
    
    Reviewed by:    manu
    Approved by:    manu
    Differential Revision:  https://reviews.freebsd.org/D42053
    
    (cherry picked from commit 1e99b2ee90956f275c3668e92a408400f2dada1c)
---
 .../linuxkpi/common/include/asm/set_memory.h       | 24 +++++++++++++++++++---
 sys/compat/linuxkpi/common/include/linux/io.h      | 15 ++++++++++++--
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h
index ae50148f0314..69f659001c60 100644
--- a/sys/compat/linuxkpi/common/include/asm/set_memory.h
+++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h
@@ -34,14 +34,26 @@
 static inline int
 set_memory_uc(unsigned long addr, int numpages)
 {
-	return (pmap_change_attr(addr, numpages, VM_MEMATTR_UNCACHEABLE));
+	vm_offset_t va;
+	vm_size_t len;
+
+	va = PHYS_TO_DMAP(addr);
+	len = numpages << PAGE_SHIFT;
+
+	return (-pmap_change_attr(va, len, VM_MEMATTR_UNCACHEABLE));
 }
 
 static inline int
 set_memory_wc(unsigned long addr, int numpages)
 {
 #ifdef VM_MEMATTR_WRITE_COMBINING
-	return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_COMBINING));
+	vm_offset_t va;
+	vm_size_t len;
+
+	va = PHYS_TO_DMAP(addr);
+	len = numpages << PAGE_SHIFT;
+
+	return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_COMBINING));
 #else
 	return (set_memory_uc(addr, numpages));
 #endif
@@ -50,7 +62,13 @@ set_memory_wc(unsigned long addr, int numpages)
 static inline int
 set_memory_wb(unsigned long addr, int numpages)
 {
-	return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_BACK));
+	vm_offset_t va;
+	vm_size_t len;
+
+	va = PHYS_TO_DMAP(addr);
+	len = numpages << PAGE_SHIFT;
+
+	return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_BACK));
 }
 
 static inline int
diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h
index ee46d354a5ae..2345967898e6 100644
--- a/sys/compat/linuxkpi/common/include/linux/io.h
+++ b/sys/compat/linuxkpi/common/include/linux/io.h
@@ -532,14 +532,25 @@ void lkpi_arch_phys_wc_del(int);
 static inline int
 arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
 {
+	vm_offset_t va;
 
-	return (set_memory_wc(start, size >> PAGE_SHIFT));
+	va = PHYS_TO_DMAP(start);
+
+#ifdef VM_MEMATTR_WRITE_COMBINING
+	return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
+#else
+	return (-pmap_change_attr(va, size, VM_MEMATTR_UNCACHEABLE));
+#endif
 }
 
 static inline void
 arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
 {
-	set_memory_wb(start, size >> PAGE_SHIFT);
+	vm_offset_t va;
+
+	va = PHYS_TO_DMAP(start);
+
+	pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
 }
 #endif