|
@@ -6,6 +6,14 @@
|
|
|
|
|
|
#define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO
|
|
|
|
|
|
+#ifdef CONFIG_HIGHPTE
|
|
|
+#define PGALLOC_USER_GFP __GFP_HIGHMEM
|
|
|
+#else
|
|
|
+#define PGALLOC_USER_GFP 0
|
|
|
+#endif
|
|
|
+
|
|
|
+gfp_t __userpte_alloc_gfp = PGALLOC_GFP | PGALLOC_USER_GFP;
|
|
|
+
|
|
|
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
|
|
|
{
|
|
|
return (pte_t *)__get_free_page(PGALLOC_GFP);
|
|
@@ -15,16 +23,29 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
|
|
|
{
|
|
|
struct page *pte;
|
|
|
|
|
|
-#ifdef CONFIG_HIGHPTE
|
|
|
- pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
|
|
|
-#else
|
|
|
- pte = alloc_pages(PGALLOC_GFP, 0);
|
|
|
-#endif
|
|
|
+ pte = alloc_pages(__userpte_alloc_gfp, 0);
|
|
|
if (pte)
|
|
|
pgtable_page_ctor(pte);
|
|
|
return pte;
|
|
|
}
|
|
|
|
|
|
+static int __init setup_userpte(char *arg)
|
|
|
+{
|
|
|
+ if (!arg)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * "userpte=nohigh" disables allocation of user pagetables in
|
|
|
+ * high memory.
|
|
|
+ */
|
|
|
+ if (strcmp(arg, "nohigh") == 0)
|
|
|
+ __userpte_alloc_gfp &= ~__GFP_HIGHMEM;
|
|
|
+ else
|
|
|
+ return -EINVAL;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+early_param("userpte", setup_userpte);
|
|
|
+
|
|
|
void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
|
|
|
{
|
|
|
pgtable_page_dtor(pte);
|