0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/fs.h>
0015 #include <linux/mm.h>
0016 #include <linux/hugetlb.h>
0017 #include <linux/pagemap.h>
0018 #include <linux/err.h>
0019 #include <linux/sysctl.h>
0020 #include <asm/mman.h>
0021 #include <asm/tlb.h>
0022 #include <asm/tlbflush.h>
0023
0024 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
0025 unsigned long addr, unsigned long sz)
0026 {
0027 pgd_t *pgd;
0028 p4d_t *p4d;
0029 pud_t *pud;
0030 pte_t *pte = NULL;
0031
0032 pgd = pgd_offset(mm, addr);
0033 p4d = p4d_alloc(mm, pgd, addr);
0034 pud = pud_alloc(mm, p4d, addr);
0035 if (pud)
0036 pte = (pte_t *)pmd_alloc(mm, pud, addr);
0037
0038 return pte;
0039 }
0040
0041 pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
0042 unsigned long sz)
0043 {
0044 pgd_t *pgd;
0045 p4d_t *p4d;
0046 pud_t *pud;
0047 pmd_t *pmd = NULL;
0048
0049 pgd = pgd_offset(mm, addr);
0050 if (pgd_present(*pgd)) {
0051 p4d = p4d_offset(pgd, addr);
0052 if (p4d_present(*p4d)) {
0053 pud = pud_offset(p4d, addr);
0054 if (pud_present(*pud))
0055 pmd = pmd_offset(pud, addr);
0056 }
0057 }
0058 return (pte_t *) pmd;
0059 }
0060
0061 int pmd_huge(pmd_t pmd)
0062 {
0063 return (pmd_val(pmd) & _PAGE_HUGE) != 0;
0064 }
0065
0066 int pud_huge(pud_t pud)
0067 {
0068 return (pud_val(pud) & _PAGE_HUGE) != 0;
0069 }