linux/arch/sparc/include/asm/pgalloc_64.h
<<
>>
Prefs
   1#ifndef _SPARC64_PGALLOC_H
   2#define _SPARC64_PGALLOC_H
   3
   4#include <linux/kernel.h>
   5#include <linux/sched.h>
   6#include <linux/mm.h>
   7#include <linux/slab.h>
   8
   9#include <asm/spitfire.h>
  10#include <asm/cpudata.h>
  11#include <asm/cacheflush.h>
  12#include <asm/page.h>
  13
  14/* Page table allocation/freeing. */
  15
  16extern struct kmem_cache *pgtable_cache;
  17
  18static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  19{
  20        return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
  21}
  22
  23static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
  24{
  25        kmem_cache_free(pgtable_cache, pgd);
  26}
  27
  28#define pud_populate(MM, PUD, PMD)      pud_set(PUD, PMD)
  29
  30static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
  31{
  32        return kmem_cache_alloc(pgtable_cache,
  33                                GFP_KERNEL|__GFP_REPEAT);
  34}
  35
  36static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
  37{
  38        kmem_cache_free(pgtable_cache, pmd);
  39}
  40
  41static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
  42                                          unsigned long address)
  43{
  44        return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
  45}
  46
  47static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
  48                                        unsigned long address)
  49{
  50        struct page *page;
  51        pte_t *pte;
  52
  53        pte = pte_alloc_one_kernel(mm, address);
  54        if (!pte)
  55                return NULL;
  56        page = virt_to_page(pte);
  57        pgtable_page_ctor(page);
  58        return page;
  59}
  60
  61static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
  62{
  63        free_page((unsigned long)pte);
  64}
  65
  66static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
  67{
  68        pgtable_page_dtor(ptepage);
  69        __free_page(ptepage);
  70}
  71
  72#define pmd_populate_kernel(MM, PMD, PTE)       pmd_set(PMD, PTE)
  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#define check_pgt_cache()       do { } while (0)
  78
  79static inline void pgtable_free(void *table, bool is_page)
  80{
  81        if (is_page)
  82                free_page((unsigned long)table);
  83        else
  84                kmem_cache_free(pgtable_cache, table);
  85}
  86
  87#ifdef CONFIG_SMP
  88
  89struct mmu_gather;
  90extern void tlb_remove_table(struct mmu_gather *, void *);
  91
  92static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page)
  93{
  94        unsigned long pgf = (unsigned long)table;
  95        if (is_page)
  96                pgf |= 0x1UL;
  97        tlb_remove_table(tlb, (void *)pgf);
  98}
  99
 100static inline void __tlb_remove_table(void *_table)
 101{
 102        void *table = (void *)((unsigned long)_table & ~0x1UL);
 103        bool is_page = false;
 104
 105        if ((unsigned long)_table & 0x1UL)
 106                is_page = true;
 107        pgtable_free(table, is_page);
 108}
 109#else /* CONFIG_SMP */
 110static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page)
 111{
 112        pgtable_free(table, is_page);
 113}
 114#endif /* !CONFIG_SMP */
 115
 116static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
 117                                  unsigned long address)
 118{
 119        pgtable_page_dtor(ptepage);
 120        pgtable_free_tlb(tlb, page_address(ptepage), true);
 121}
 122
 123#define __pmd_free_tlb(tlb, pmd, addr)                \
 124        pgtable_free_tlb(tlb, pmd, false)
 125
 126#endif /* _SPARC64_PGALLOC_H */
 127