m commit 8dad29555a5807bf21941807752e1589e20312de) --- sys/compat/linuxkpi/common/include/asm/set_memory.h | 15 +++------------ sys/compat/linuxkpi/common/include/linux/page.h | 2 ++ sys/compat/linuxkpi/common/src/linux_page.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h index 1019aaf264a0..54a1311ef9a5 100644 --- a/sys/compat/linuxkpi/common/include/asm/set_memory.h +++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h @@ -65,32 +65,23 @@ set_memory_wb(unsigned long addr, int numpages) static inline int set_pages_uc(struct page *page, int numpages) { - KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages)); - - pmap_page_set_memattr(page, VM_MEMATTR_UNCACHEABLE); - return (0); + return (lkpi_set_pages_attr(page, numpages, VM_MEMATTR_UNCACHEABLE)); } static inline int set_pages_wc(struct page *page, int numpages) { - KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages)); - #ifdef VM_MEMATTR_WRITE_COMBINING - pmap_page_set_memattr(page, VM_MEMATTR_WRITE_COMBINING); + return (lkpi_set_pages_attr(page, numpages, VM_MEMATTR_WRITE_COMBINING)); #else return (set_pages_uc(page, numpages)); #endif - return (0); } static inline int set_pages_wb(struct page *page, int numpages) { - KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages)); - - pmap_page_set_memattr(page, VM_MEMATTR_WRITE_BACK); - return (0); + return (lkpi_set_pages_attr(page, numpages, VM_MEMATTR_WRITE_BACK)); } static inline int diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h index 37ab593a64e9..6f5f37d2fd0f 100644 --- a/sys/compat/linuxkpi/common/include/linux/page.h +++ b/sys/compat/linuxkpi/common/include/linux/page.h @@ -127,4 +127,6 @@ clflush_cache_range(void *addr, unsigned int size) } #endif +int lkpi_set_pages_attr(struct page *page, int numpages, vm_memattr_t ma); + #endif /* _LINUXKPI_LINUX_PAGE_H_ */ diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c index d8b65a12dc67..f562bd5e0dbd 100644 --- a/sys/compat/linuxkpi/common/src/linux_page.c +++ b/sys/compat/linuxkpi/common/src/linux_page.c @@ -710,6 +710,27 @@ lkpi_arch_phys_wc_del(int reg) #endif } +int +lkpi_set_pages_attr(struct page *page, int numpages, vm_memattr_t ma) +{ + while (numpages-- > 0) { + /* + * pmap_page_set_memattr() would only update the DMAP mapping + * if it's a normal page, leaving the kernel map untouched. + */ + MPASS(page->object != kernel_object); + + /* + * pmap_page_set_memattr() sets page->md.pat_mode, which is + * crucial for future userspace mappings. + */ + pmap_page_set_memattr(page, ma); + page++; + } + + return (0); +} + /* * This is a highly simplified version of the Linux page_frag_cache. * We only support up-to 1 single page as fragment size and we will