Merge commit 'v2.6.26-rc9' into sched/devel
[pandora-kernel.git] / include / asm-powerpc / pgalloc-64.h
index 94d0294..6898099 100644 (file)
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
 
+#ifndef CONFIG_PPC_SUBPAGE_PROT
+static inline void subpage_prot_free(pgd_t *pgd) {}
+#endif
+
 extern struct kmem_cache *pgtable_cache[];
 
 #define PGD_CACHE_NUM          0
@@ -25,8 +29,9 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
        return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
 }
 
-static inline void pgd_free(pgd_t *pgd)
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
+       subpage_prot_free(pgd);
        kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
 }
 
@@ -40,7 +45,7 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
                                GFP_KERNEL|__GFP_REPEAT);
 }
 
-static inline void pud_free(pud_t *pud)
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
        kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
 }
@@ -53,6 +58,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 #define pmd_populate(mm, pmd, pte_page) \
        pmd_populate_kernel(mm, pmd, page_address(pte_page))
 #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
+#define pmd_pgtable(pmd) pmd_page(pmd)
 
 
 #else /* CONFIG_PPC_64K_PAGES */
@@ -67,6 +73,7 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
 
 #define pmd_populate(mm, pmd, pte_page) \
        pmd_populate_kernel(mm, pmd, page_address(pte_page))
+#define pmd_pgtable(pmd) pmd_page(pmd)
 
 #endif /* CONFIG_PPC_64K_PAGES */
 
@@ -76,7 +83,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
                                GFP_KERNEL|__GFP_REPEAT);
 }
 
-static inline void pmd_free(pmd_t *pmd)
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
        kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
 }
@@ -87,20 +94,28 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
         return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
 }
 
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
-                                        unsigned long address)
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
+                                       unsigned long address)
 {
-       pte_t *pte = pte_alloc_one_kernel(mm, address);
-       return pte ? virt_to_page(pte) : NULL;
+       struct page *page;
+       pte_t *pte;
+
+       pte = pte_alloc_one_kernel(mm, address);
+       if (!pte)
+               return NULL;
+       page = virt_to_page(pte);
+       pgtable_page_ctor(page);
+       return page;
 }
 
-static inline void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
        free_page((unsigned long)pte);
 }
 
-static inline void pte_free(struct page *ptepage)
+static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
 {
+       pgtable_page_dtor(ptepage);
        __free_page(ptepage);
 }
 
@@ -131,9 +146,12 @@ static inline void pgtable_free(pgtable_free_t pgf)
 
 extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
 
-#define __pte_free_tlb(tlb, ptepage)   \
+#define __pte_free_tlb(tlb,ptepage)    \
+do { \
+       pgtable_page_dtor(ptepage); \
        pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
-               PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1))
+               PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
+} while (0)
 #define __pmd_free_tlb(tlb, pmd)       \
        pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
                PMD_CACHE_NUM, PMD_TABLE_SIZE-1))