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