linux/arch/powerpc/include/asm/pgalloc-64.h
<<
>>
Prefs
   1#ifndef _ASM_POWERPC_PGALLOC_64_H
   2#define _ASM_POWERPC_PGALLOC_64_H
   3/*
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version
   7 * 2 of the License, or (at your option) any later version.
   8 */
   9
  10#include <linux/slab.h>
  11#include <linux/cpumask.h>
  12#include <linux/percpu.h>
  13
  14struct vmemmap_backing {
  15        struct vmemmap_backing *list;
  16        unsigned long phys;
  17        unsigned long virt_addr;
  18};
  19
  20/*
  21 * Functions that deal with pagetables that could be at any level of
  22 * the table need to be passed an "index_size" so they know how to
  23 * handle allocation.  For PTE pages (which are linked to a struct
  24 * page for now, and drawn from the main get_free_pages() pool), the
  25 * allocation size will be (2^index_size * sizeof(pointer)) and
  26 * allocations are drawn from the kmem_cache in PGT_CACHE(index_size).
  27 *
  28 * The maximum index size needs to be big enough to allow any
  29 * pagetable sizes we need, but small enough to fit in the low bits of
  30 * any page table pointer.  In other words all pagetables, even tiny
  31 * ones, must be aligned to allow at least enough low 0 bits to
  32 * contain this value.  This value is also used as a mask, so it must
  33 * be one less than a power of two.
  34 */
  35#define MAX_PGTABLE_INDEX_SIZE  0xf
  36
  37extern struct kmem_cache *pgtable_cache[];
  38#define PGT_CACHE(shift) ({                             \
  39                        BUG_ON(!(shift));               \
  40                        pgtable_cache[(shift) - 1];     \
  41                })
  42
  43static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  44{
  45        return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL);
  46}
  47
  48static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
  49{
  50        kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
  51}
  52
  53#ifndef CONFIG_PPC_64K_PAGES
  54
  55#define pgd_populate(MM, PGD, PUD)      pgd_set(PGD, PUD)
  56
  57static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
  58{
  59        return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
  60                                GFP_KERNEL|__GFP_REPEAT);
  61}
  62
  63static inline void pud_free(struct mm_struct *mm, pud_t *pud)
  64{
  65        kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
  66}
  67
  68static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  69{
  70        pud_set(pud, (unsigned long)pmd);
  71}
  72
  73#define pmd_populate(mm, pmd, pte_page) \
  74        pmd_populate_kernel(mm, pmd, page_address(pte_page))
  75#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
  76#define pmd_pgtable(pmd) pmd_page(pmd)
  77
  78static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
  79                                          unsigned long address)
  80{
  81        return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
  82}
  83
  84static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
  85                                      unsigned long address)
  86{
  87        struct page *page;
  88        pte_t *pte;
  89
  90        pte = pte_alloc_one_kernel(mm, address);
  91        if (!pte)
  92                return NULL;
  93        page = virt_to_page(pte);
  94        pgtable_page_ctor(page);
  95        return page;
  96}
  97
  98static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
  99{
 100        free_page((unsigned long)pte);
 101}
 102
 103static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
 104{
 105        pgtable_page_dtor(ptepage);
 106        __free_page(ptepage);
 107}
 108
 109static inline void pgtable_free(void *table, unsigned index_size)
 110{
 111        if (!index_size)
 112                free_page((unsigned long)table);
 113        else {
 114                BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
 115                kmem_cache_free(PGT_CACHE(index_size), table);
 116        }
 117}
 118
 119#ifdef CONFIG_SMP
 120static inline void pgtable_free_tlb(struct mmu_gather *tlb,
 121                                    void *table, int shift)
 122{
 123        unsigned long pgf = (unsigned long)table;
 124        BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
 125        pgf |= shift;
 126        tlb_remove_table(tlb, (void *)pgf);
 127}
 128
 129static inline void __tlb_remove_table(void *_table)
 130{
 131        void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
 132        unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
 133
 134        pgtable_free(table, shift);
 135}
 136#else /* !CONFIG_SMP */
 137static inline void pgtable_free_tlb(struct mmu_gather *tlb,
 138                                    void *table, int shift)
 139{
 140        pgtable_free(table, shift);
 141}
 142#endif /* CONFIG_SMP */
 143
 144static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 145                                  unsigned long address)
 146{
 147        struct page *page = page_address(table);
 148
 149        tlb_flush_pgtable(tlb, address);
 150        pgtable_page_dtor(page);
 151        pgtable_free_tlb(tlb, page, 0);
 152}
 153
 154#else /* if CONFIG_PPC_64K_PAGES */
 155/*
 156 * we support 16 fragments per PTE page.
 157 */
 158#define PTE_FRAG_NR     16
 159/*
 160 * We use a 2K PTE page fragment and another 2K for storing
 161 * real_pte_t hash index
 162 */
 163#define PTE_FRAG_SIZE_SHIFT  12
 164#define PTE_FRAG_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t))
 165
 166extern pte_t *page_table_alloc(struct mm_struct *, unsigned long, int);
 167extern void page_table_free(struct mm_struct *, unsigned long *, int);
 168extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
 169#ifdef CONFIG_SMP
 170extern void __tlb_remove_table(void *_table);
 171#endif
 172
 173#define pud_populate(mm, pud, pmd)      pud_set(pud, (unsigned long)pmd)
 174
 175static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
 176                                       pte_t *pte)
 177{
 178        pmd_set(pmd, (unsigned long)pte);
 179}
 180
 181static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 182                                pgtable_t pte_page)
 183{
 184        pmd_set(pmd, (unsigned long)pte_page);
 185}
 186
 187static inline pgtable_t pmd_pgtable(pmd_t pmd)
 188{
 189        return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS);
 190}
 191
 192static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 193                                          unsigned long address)
 194{
 195        return (pte_t *)page_table_alloc(mm, address, 1);
 196}
 197
 198static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
 199                                        unsigned long address)
 200{
 201        return (pgtable_t)page_table_alloc(mm, address, 0);
 202}
 203
 204static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 205{
 206        page_table_free(mm, (unsigned long *)pte, 1);
 207}
 208
 209static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
 210{
 211        page_table_free(mm, (unsigned long *)ptepage, 0);
 212}
 213
 214static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 215                                  unsigned long address)
 216{
 217        tlb_flush_pgtable(tlb, address);
 218        pgtable_free_tlb(tlb, table, 0);
 219}
 220#endif /* CONFIG_PPC_64K_PAGES */
 221
 222static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 223{
 224        return kmem_cache_alloc(PGT_CACHE(PMD_CACHE_INDEX),
 225                                GFP_KERNEL|__GFP_REPEAT);
 226}
 227
 228static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 229{
 230        kmem_cache_free(PGT_CACHE(PMD_CACHE_INDEX), pmd);
 231}
 232
 233#define __pmd_free_tlb(tlb, pmd, addr)                \
 234        pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX)
 235#ifndef CONFIG_PPC_64K_PAGES
 236#define __pud_free_tlb(tlb, pud, addr)                \
 237        pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
 238
 239#endif /* CONFIG_PPC_64K_PAGES */
 240
 241#define check_pgt_cache()       do { } while (0)
 242
 243#endif /* _ASM_POWERPC_PGALLOC_64_H */
 244