| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> |
|---|
| 3 | 4 | * Copyright (C) 2008-2009 PetaLogix |
|---|
| 4 | 5 | * Copyright (C) 2006 Atmark Techno, Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This file is subject to the terms and conditions of the GNU General Public |
|---|
| 7 | | - * License. See the file "COPYING" in the main directory of this archive |
|---|
| 8 | | - * for more details. |
|---|
| 9 | 6 | */ |
|---|
| 10 | 7 | |
|---|
| 11 | 8 | #ifndef _ASM_MICROBLAZE_PGALLOC_H |
|---|
| .. | .. |
|---|
| 15 | 12 | |
|---|
| 16 | 13 | #include <linux/kernel.h> /* For min/max macros */ |
|---|
| 17 | 14 | #include <linux/highmem.h> |
|---|
| 15 | +#include <linux/pgtable.h> |
|---|
| 18 | 16 | #include <asm/setup.h> |
|---|
| 19 | 17 | #include <asm/io.h> |
|---|
| 20 | 18 | #include <asm/page.h> |
|---|
| 21 | 19 | #include <asm/cache.h> |
|---|
| 22 | | -#include <asm/pgtable.h> |
|---|
| 23 | 20 | |
|---|
| 24 | | -#define PGDIR_ORDER 0 |
|---|
| 25 | | - |
|---|
| 26 | | -/* |
|---|
| 27 | | - * This is handled very differently on MicroBlaze since out page tables |
|---|
| 28 | | - * are all 0's and I want to be able to use these zero'd pages elsewhere |
|---|
| 29 | | - * as well - it gives us quite a speedup. |
|---|
| 30 | | - * -- Cort |
|---|
| 31 | | - */ |
|---|
| 32 | | -extern struct pgtable_cache_struct { |
|---|
| 33 | | - unsigned long *pgd_cache; |
|---|
| 34 | | - unsigned long *pte_cache; |
|---|
| 35 | | - unsigned long pgtable_cache_sz; |
|---|
| 36 | | -} quicklists; |
|---|
| 37 | | - |
|---|
| 38 | | -#define pgd_quicklist (quicklists.pgd_cache) |
|---|
| 39 | | -#define pmd_quicklist ((unsigned long *)0) |
|---|
| 40 | | -#define pte_quicklist (quicklists.pte_cache) |
|---|
| 41 | | -#define pgtable_cache_size (quicklists.pgtable_cache_sz) |
|---|
| 42 | | - |
|---|
| 43 | | -extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */ |
|---|
| 44 | | -extern atomic_t zero_sz; /* # currently pre-zero'd pages */ |
|---|
| 45 | | -extern atomic_t zeropage_hits; /* # zero'd pages request that we've done */ |
|---|
| 46 | | -extern atomic_t zeropage_calls; /* # zero'd pages request that've been made */ |
|---|
| 47 | | -extern atomic_t zerototal; /* # pages zero'd over time */ |
|---|
| 48 | | - |
|---|
| 49 | | -#define zero_quicklist (zero_cache) |
|---|
| 50 | | -#define zero_cache_sz (zero_sz) |
|---|
| 51 | | -#define zero_cache_calls (zeropage_calls) |
|---|
| 52 | | -#define zero_cache_hits (zeropage_hits) |
|---|
| 53 | | -#define zero_cache_total (zerototal) |
|---|
| 54 | | - |
|---|
| 55 | | -/* |
|---|
| 56 | | - * return a pre-zero'd page from the list, |
|---|
| 57 | | - * return NULL if none available -- Cort |
|---|
| 58 | | - */ |
|---|
| 59 | | -extern unsigned long get_zero_page_fast(void); |
|---|
| 21 | +#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL |
|---|
| 22 | +#include <asm-generic/pgalloc.h> |
|---|
| 60 | 23 | |
|---|
| 61 | 24 | extern void __bad_pte(pmd_t *pmd); |
|---|
| 62 | 25 | |
|---|
| 63 | | -static inline pgd_t *get_pgd_slow(void) |
|---|
| 26 | +static inline pgd_t *get_pgd(void) |
|---|
| 64 | 27 | { |
|---|
| 65 | | - pgd_t *ret; |
|---|
| 66 | | - |
|---|
| 67 | | - ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER); |
|---|
| 68 | | - if (ret != NULL) |
|---|
| 69 | | - clear_page(ret); |
|---|
| 70 | | - return ret; |
|---|
| 28 | + return (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0); |
|---|
| 71 | 29 | } |
|---|
| 72 | 30 | |
|---|
| 73 | | -static inline pgd_t *get_pgd_fast(void) |
|---|
| 74 | | -{ |
|---|
| 75 | | - unsigned long *ret; |
|---|
| 76 | | - |
|---|
| 77 | | - ret = pgd_quicklist; |
|---|
| 78 | | - if (ret != NULL) { |
|---|
| 79 | | - pgd_quicklist = (unsigned long *)(*ret); |
|---|
| 80 | | - ret[0] = 0; |
|---|
| 81 | | - pgtable_cache_size--; |
|---|
| 82 | | - } else |
|---|
| 83 | | - ret = (unsigned long *)get_pgd_slow(); |
|---|
| 84 | | - return (pgd_t *)ret; |
|---|
| 85 | | -} |
|---|
| 86 | | - |
|---|
| 87 | | -static inline void free_pgd_fast(pgd_t *pgd) |
|---|
| 88 | | -{ |
|---|
| 89 | | - *(unsigned long **)pgd = pgd_quicklist; |
|---|
| 90 | | - pgd_quicklist = (unsigned long *) pgd; |
|---|
| 91 | | - pgtable_cache_size++; |
|---|
| 92 | | -} |
|---|
| 93 | | - |
|---|
| 94 | | -static inline void free_pgd_slow(pgd_t *pgd) |
|---|
| 95 | | -{ |
|---|
| 96 | | - free_page((unsigned long)pgd); |
|---|
| 97 | | -} |
|---|
| 98 | | - |
|---|
| 99 | | -#define pgd_free(mm, pgd) free_pgd_fast(pgd) |
|---|
| 100 | | -#define pgd_alloc(mm) get_pgd_fast() |
|---|
| 31 | +#define pgd_alloc(mm) get_pgd() |
|---|
| 101 | 32 | |
|---|
| 102 | 33 | #define pmd_pgtable(pmd) pmd_page(pmd) |
|---|
| 103 | 34 | |
|---|
| 104 | | -/* |
|---|
| 105 | | - * We don't have any real pmd's, and this code never triggers because |
|---|
| 106 | | - * the pgd will always be present.. |
|---|
| 107 | | - */ |
|---|
| 108 | | -#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); }) |
|---|
| 109 | | -#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) |
|---|
| 110 | | - |
|---|
| 111 | | -extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); |
|---|
| 112 | | - |
|---|
| 113 | | -static inline struct page *pte_alloc_one(struct mm_struct *mm, |
|---|
| 114 | | - unsigned long address) |
|---|
| 115 | | -{ |
|---|
| 116 | | - struct page *ptepage; |
|---|
| 117 | | - |
|---|
| 118 | | -#ifdef CONFIG_HIGHPTE |
|---|
| 119 | | - int flags = GFP_KERNEL | __GFP_HIGHMEM; |
|---|
| 120 | | -#else |
|---|
| 121 | | - int flags = GFP_KERNEL; |
|---|
| 122 | | -#endif |
|---|
| 123 | | - |
|---|
| 124 | | - ptepage = alloc_pages(flags, 0); |
|---|
| 125 | | - if (!ptepage) |
|---|
| 126 | | - return NULL; |
|---|
| 127 | | - clear_highpage(ptepage); |
|---|
| 128 | | - if (!pgtable_page_ctor(ptepage)) { |
|---|
| 129 | | - __free_page(ptepage); |
|---|
| 130 | | - return NULL; |
|---|
| 131 | | - } |
|---|
| 132 | | - return ptepage; |
|---|
| 133 | | -} |
|---|
| 134 | | - |
|---|
| 135 | | -static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, |
|---|
| 136 | | - unsigned long address) |
|---|
| 137 | | -{ |
|---|
| 138 | | - unsigned long *ret; |
|---|
| 139 | | - |
|---|
| 140 | | - ret = pte_quicklist; |
|---|
| 141 | | - if (ret != NULL) { |
|---|
| 142 | | - pte_quicklist = (unsigned long *)(*ret); |
|---|
| 143 | | - ret[0] = 0; |
|---|
| 144 | | - pgtable_cache_size--; |
|---|
| 145 | | - } |
|---|
| 146 | | - return (pte_t *)ret; |
|---|
| 147 | | -} |
|---|
| 148 | | - |
|---|
| 149 | | -static inline void pte_free_fast(pte_t *pte) |
|---|
| 150 | | -{ |
|---|
| 151 | | - *(unsigned long **)pte = pte_quicklist; |
|---|
| 152 | | - pte_quicklist = (unsigned long *) pte; |
|---|
| 153 | | - pgtable_cache_size++; |
|---|
| 154 | | -} |
|---|
| 155 | | - |
|---|
| 156 | | -static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) |
|---|
| 157 | | -{ |
|---|
| 158 | | - free_page((unsigned long)pte); |
|---|
| 159 | | -} |
|---|
| 160 | | - |
|---|
| 161 | | -static inline void pte_free_slow(struct page *ptepage) |
|---|
| 162 | | -{ |
|---|
| 163 | | - __free_page(ptepage); |
|---|
| 164 | | -} |
|---|
| 165 | | - |
|---|
| 166 | | -static inline void pte_free(struct mm_struct *mm, struct page *ptepage) |
|---|
| 167 | | -{ |
|---|
| 168 | | - pgtable_page_dtor(ptepage); |
|---|
| 169 | | - __free_page(ptepage); |
|---|
| 170 | | -} |
|---|
| 35 | +extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm); |
|---|
| 171 | 36 | |
|---|
| 172 | 37 | #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte)) |
|---|
| 173 | 38 | |
|---|
| .. | .. |
|---|
| 177 | 42 | #define pmd_populate_kernel(mm, pmd, pte) \ |
|---|
| 178 | 43 | (pmd_val(*(pmd)) = (unsigned long) (pte)) |
|---|
| 179 | 44 | |
|---|
| 180 | | -/* |
|---|
| 181 | | - * We don't have any real pmd's, and this code never triggers because |
|---|
| 182 | | - * the pgd will always be present.. |
|---|
| 183 | | - */ |
|---|
| 184 | | -#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); }) |
|---|
| 185 | | -#define pmd_free(mm, x) do { } while (0) |
|---|
| 186 | | -#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x) |
|---|
| 187 | | -#define pgd_populate(mm, pmd, pte) BUG() |
|---|
| 188 | | - |
|---|
| 189 | | -extern int do_check_pgt_cache(int, int); |
|---|
| 190 | | - |
|---|
| 191 | 45 | #endif /* CONFIG_MMU */ |
|---|
| 192 | | - |
|---|
| 193 | | -#define check_pgt_cache() do { } while (0) |
|---|
| 194 | 46 | |
|---|
| 195 | 47 | #endif /* _ASM_MICROBLAZE_PGALLOC_H */ |
|---|