git: 1e99b2ee9095 - main - linuxkpi: Fix uses of `pmap_change_attr()`
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 03 Oct 2023 20:16:02 UTC
The branch main has been updated by dumbbell:
URL: https://cgit.FreeBSD.org/src/commit/?id=1e99b2ee90956f275c3668e92a408400f2dada1c
commit 1e99b2ee90956f275c3668e92a408400f2dada1c
Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2023-08-16 20:32:42 +0000
Commit: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2023-10-03 20:13:52 +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
---
.../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