aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2023-08-16 20:32:42 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2023-10-03 20:13:52 +0000
commit1e99b2ee90956f275c3668e92a408400f2dada1c (patch)
treeac706f0cb07ff2fbf3b200768adeb410b082b691
parent5a82fc7859f746d95811e43b3a117b8eea297749 (diff)
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
-rw-r--r--sys/compat/linuxkpi/common/include/asm/set_memory.h24
-rw-r--r--sys/compat/linuxkpi/common/include/linux/io.h15
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