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
  14#ifndef CONFIG_PPC_SUBPAGE_PROT
  15static inline void subpage_prot_free(pgd_t *pgd) {}
  16#endif
  17
  18extern struct kmem_cache *pgtable_cache[];
  19
  20#define PGD_CACHE_NUM           0
  21#define PUD_CACHE_NUM           1
  22#define PMD_CACHE_NUM           1
  23#define HUGEPTE_CACHE_NUM       2
  24#define PTE_NONCACHE_NUM        7  /* from GFP rather than kmem_cache */
  25
  26static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  27{
  28        return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
  29}
  30
  31static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
  32{
  33        subpage_prot_free(pgd);
  34        kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
  35}
  36
  37#ifndef CONFIG_PPC_64K_PAGES
  38
  39#define pgd_populate(MM, PGD, PUD)      pgd_set(PGD, PUD)
  40
  41static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
  42{
  43        return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
  44                                GFP_KERNEL|__GFP_REPEAT);
  45}
  46
  47static inline void pud_free(struct mm_struct *mm, pud_t *pud)
  48{
  49        kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
  50}
  51
  52static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  53{
  54        pud_set(pud, (unsigned long)pmd);
  55}
  56
  57#define pmd_populate(mm, pmd, pte_page) \
  58        pmd_populate_kernel(mm, pmd, page_address(pte_page))
  59#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
  60#define pmd_pgtable(pmd) pmd_page(pmd)
  61
  62
  63#else /* CONFIG_PPC_64K_PAGES */
  64
  65#define pud_populate(mm, pud, pmd)      pud_set(pud, (unsigned long)pmd)
  66
  67static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
  68                                       pte_t *pte)
  69{
  70        pmd_set(pmd, (unsigned long)pte);
  71}
  72
  73#define pmd_populate(mm, pmd, pte_page) \
  74        pmd_populate_kernel(mm, pmd, page_address(pte_page))
  75#define pmd_pgtable(pmd) pmd_page(pmd)
  76
  77#endif /* CONFIG_PPC_64K_PAGES */
  78
  79static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
  80{
  81        return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
  82                                GFP_KERNEL|__GFP_REPEAT);
  83}
  84
  85static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
  86{
  87        kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
  88}
  89
  90static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
  91                                          unsigned long address)
  92{
  93        return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
  94}
  95
  96static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
  97                                        unsigned long address)
  98{
  99        struct page *page;
 100        pte_t *pte;
 101
 102        pte = pte_alloc_one_kernel(mm, address);
 103        if (!pte)
 104                return NULL;
 105        page = virt_to_page(pte);
 106        pgtable_page_ctor(page);
 107        return page;
 108}
 109
 110static inline void pgtable_free(pgtable_free_t pgf)
 111{
 112        void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
 113        int cachenum = pgf.val & PGF_CACHENUM_MASK;
 114
 115        if (cachenum == PTE_NONCACHE_NUM)
 116                free_page((unsigned long)p);
 117        else
 118                kmem_cache_free(pgtable_cache[cachenum], p);
 119}
 120
 121#define __pmd_free_tlb(tlb, pmd,addr)                 \
 122        pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
 123                PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
 124#ifndef CONFIG_PPC_64K_PAGES
 125#define __pud_free_tlb(tlb, pud, addr)                \
 126        pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
 127                PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
 128#endif /* CONFIG_PPC_64K_PAGES */
 129
 130#define check_pgt_cache()       do { } while (0)
 131
 132#endif /* _ASM_POWERPC_PGALLOC_64_H */
 133