pgalloc.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_PGALLOC_H
  3. #define _ASM_PGALLOC_H
  4. #include <linux/gfp.h>
  5. #include <linux/mm.h>
  6. #include <linux/threads.h>
  7. #include <asm/processor.h>
  8. #include <asm/fixmap.h>
  9. #include <asm/cache.h>
  10. #define __HAVE_ARCH_PMD_ALLOC_ONE
  11. #include <asm-generic/pgalloc.h>
  12. /* Allocate the top level pgd (page directory) */
  13. static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  14. {
  15. return __pgd_alloc(mm, PGD_TABLE_ORDER);
  16. }
  17. #if CONFIG_PGTABLE_LEVELS == 3
  18. /* Three Level Page Table Support for pmd's */
  19. static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  20. {
  21. set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
  22. (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
  23. }
  24. static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  25. {
  26. struct ptdesc *ptdesc;
  27. gfp_t gfp = GFP_PGTABLE_USER;
  28. if (mm == &init_mm)
  29. gfp = GFP_PGTABLE_KERNEL;
  30. ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
  31. if (!ptdesc)
  32. return NULL;
  33. if (!pagetable_pmd_ctor(mm, ptdesc)) {
  34. pagetable_free(ptdesc);
  35. return NULL;
  36. }
  37. return ptdesc_address(ptdesc);
  38. }
  39. #endif
  40. static inline void
  41. pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
  42. {
  43. set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
  44. + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
  45. }
  46. #define pmd_populate(mm, pmd, pte_page) \
  47. pmd_populate_kernel(mm, pmd, page_address(pte_page))
  48. #endif