| 1 |
|
| 2 | #ifndef _ASM_PGALLOC_H
|
| 3 | #define _ASM_PGALLOC_H
|
| 4 |
|
| 5 | #include <linux/gfp.h>
|
| 6 | #include <linux/mm.h>
|
| 7 | #include <linux/threads.h>
|
| 8 | #include <asm/processor.h>
|
| 9 | #include <asm/fixmap.h>
|
| 10 |
|
| 11 | #include <asm/cache.h>
|
| 12 |
|
| 13 | #define __HAVE_ARCH_PMD_ALLOC_ONE
|
| 14 | #include <asm-generic/pgalloc.h>
|
| 15 |
|
| 16 |
|
| 17 | static inline pgd_t *pgd_alloc(struct mm_struct *mm)
|
| 18 | {
|
| 19 | return __pgd_alloc(mm, PGD_TABLE_ORDER);
|
| 20 | }
|
| 21 |
|
| 22 | #if CONFIG_PGTABLE_LEVELS == 3
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
|
| 27 | {
|
| 28 | set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
|
| 29 | (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
|
| 30 | }
|
| 31 |
|
| 32 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
|
| 33 | {
|
| 34 | struct ptdesc *ptdesc;
|
| 35 | gfp_t gfp = GFP_PGTABLE_USER;
|
| 36 |
|
| 37 | if (mm == &init_mm)
|
| 38 | gfp = GFP_PGTABLE_KERNEL;
|
| 39 | ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
|
| 40 | if (!ptdesc)
|
| 41 | return NULL;
|
| 42 | if (!pagetable_pmd_ctor(mm, ptdesc)) {
|
| 43 | pagetable_free(ptdesc);
|
| 44 | return NULL;
|
| 45 | }
|
| 46 | return ptdesc_address(ptdesc);
|
| 47 | }
|
| 48 | #endif
|
| 49 |
|
| 50 | static inline void
|
| 51 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
|
| 52 | {
|
| 53 | set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
|
| 54 | + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
|
| 55 | }
|
| 56 |
|
| 57 | #define pmd_populate(mm, pmd, pte_page) \
|
| 58 | pmd_populate_kernel(mm, pmd, page_address(pte_page))
|
| 59 |
|
| 60 | #endif
|