at v2.6.21 2.9 kB view raw
1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994 - 2001, 2003 by Ralf Baechle 7 * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. 8 */ 9#ifndef _ASM_PGALLOC_H 10#define _ASM_PGALLOC_H 11 12#include <linux/highmem.h> 13#include <linux/mm.h> 14 15static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 16 pte_t *pte) 17{ 18 set_pmd(pmd, __pmd((unsigned long)pte)); 19} 20 21static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 22 struct page *pte) 23{ 24 set_pmd(pmd, __pmd((unsigned long)page_address(pte))); 25} 26 27/* 28 * Initialize a new pmd table with invalid pointers. 29 */ 30extern void pmd_init(unsigned long page, unsigned long pagetable); 31 32#ifdef CONFIG_64BIT 33 34static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 35{ 36 set_pud(pud, __pud((unsigned long)pmd)); 37} 38#endif 39 40/* 41 * Initialize a new pgd / pmd table with invalid pointers. 42 */ 43extern void pgd_init(unsigned long page); 44 45static inline pgd_t *pgd_alloc(struct mm_struct *mm) 46{ 47 pgd_t *ret, *init; 48 49 ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); 50 if (ret) { 51 init = pgd_offset(&init_mm, 0UL); 52 pgd_init((unsigned long)ret); 53 memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, 54 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 55 } 56 57 return ret; 58} 59 60static inline void pgd_free(pgd_t *pgd) 61{ 62 free_pages((unsigned long)pgd, PGD_ORDER); 63} 64 65static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 66 unsigned long address) 67{ 68 pte_t *pte; 69 70 pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER); 71 72 return pte; 73} 74 75static inline struct page *pte_alloc_one(struct mm_struct *mm, 76 unsigned long address) 77{ 78 struct page *pte; 79 80 pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER); 81 if (pte) 82 clear_highpage(pte); 83 84 return pte; 85} 86 87static inline void pte_free_kernel(pte_t *pte) 88{ 89 free_pages((unsigned long)pte, PTE_ORDER); 90} 91 92static inline void pte_free(struct page *pte) 93{ 94 __free_pages(pte, PTE_ORDER); 95} 96 97#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) 98 99#ifdef CONFIG_32BIT 100 101/* 102 * allocating and freeing a pmd is trivial: the 1-entry pmd is 103 * inside the pgd, so has no extra memory associated with it. 104 */ 105#define pmd_free(x) do { } while (0) 106#define __pmd_free_tlb(tlb,x) do { } while (0) 107 108#endif 109 110#ifdef CONFIG_64BIT 111 112static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) 113{ 114 pmd_t *pmd; 115 116 pmd = (pmd_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PMD_ORDER); 117 if (pmd) 118 pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); 119 return pmd; 120} 121 122static inline void pmd_free(pmd_t *pmd) 123{ 124 free_pages((unsigned long)pmd, PMD_ORDER); 125} 126 127#define __pmd_free_tlb(tlb,x) pmd_free(x) 128 129#endif 130 131#define check_pgt_cache() do { } while (0) 132 133extern void pagetable_init(void); 134 135#endif /* _ASM_PGALLOC_H */