0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #ifndef _ASM_ARC_PGALLOC_H
0030 #define _ASM_ARC_PGALLOC_H
0031
0032 #include <linux/mm.h>
0033 #include <linux/log2.h>
0034 #include <asm-generic/pgalloc.h>
0035
0036 static inline void
0037 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
0038 {
0039
0040
0041
0042
0043
0044
0045
0046 set_pmd(pmd, __pmd((unsigned long)pte));
0047 }
0048
0049 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_page)
0050 {
0051 set_pmd(pmd, __pmd((unsigned long)page_address(pte_page)));
0052 }
0053
0054 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
0055 {
0056 pgd_t *ret = (pgd_t *) __get_free_page(GFP_KERNEL);
0057
0058 if (ret) {
0059 int num, num2;
0060 num = USER_PTRS_PER_PGD + USER_KERNEL_GUTTER / PGDIR_SIZE;
0061 memzero(ret, num * sizeof(pgd_t));
0062
0063 num2 = VMALLOC_SIZE / PGDIR_SIZE;
0064 memcpy(ret + num, swapper_pg_dir + num, num2 * sizeof(pgd_t));
0065
0066 memzero(ret + num + num2,
0067 (PTRS_PER_PGD - num - num2) * sizeof(pgd_t));
0068
0069 }
0070 return ret;
0071 }
0072
0073 #if CONFIG_PGTABLE_LEVELS > 3
0074
0075 static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
0076 {
0077 set_p4d(p4dp, __p4d((unsigned long)pudp));
0078 }
0079
0080 #define __pud_free_tlb(tlb, pmd, addr) pud_free((tlb)->mm, pmd)
0081
0082 #endif
0083
0084 #if CONFIG_PGTABLE_LEVELS > 2
0085
0086 static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
0087 {
0088 set_pud(pudp, __pud((unsigned long)pmdp));
0089 }
0090
0091 #define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
0092
0093 #endif
0094
0095 #define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
0096
0097 #endif