diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h index f328fcabd243..6ab28ad5943d 100644 --- a/sys/compat/linuxkpi/common/include/asm/set_memory.h +++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h @@ -29,6 +29,9 @@ #ifndef _LINUXKPI_ASM_SET_MEMORY_H_ #define _LINUXKPI_ASM_SET_MEMORY_H_ +#include +#include +#include #include static inline int @@ -63,34 +66,46 @@ set_memory_wb(unsigned long addr, int numpages) } static inline int -set_pages_uc(struct page *page, int numpages) +set_pages_attr(struct page *page, int numpages, vm_memattr_t ma) { - KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages)); + 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++; + } - pmap_page_set_memattr(page, VM_MEMATTR_UNCACHEABLE); return (0); } static inline int -set_pages_wc(struct page *page, int numpages) +set_pages_uc(struct page *page, int numpages) { - KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages)); + return (set_pages_attr(page, numpages, VM_MEMATTR_UNCACHEABLE)); +} +static inline int +set_pages_wc(struct page *page, int numpages) +{ #ifdef VM_MEMATTR_WRITE_COMBINING - pmap_page_set_memattr(page, VM_MEMATTR_WRITE_COMBINING); + return (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 (set_pages_attr(page, numpages, VM_MEMATTR_WRITE_BACK)); } static inline int