Skip site navigation (1)Skip section navigation (2)



index | | raw e-mail

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


home | help