pgalloc.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. */
  5. #ifndef _ASM_PGALLOC_H
  6. #define _ASM_PGALLOC_H
  7. #include <linux/mm.h>
  8. #include <linux/sched.h>
  9. #define __HAVE_ARCH_PMD_ALLOC_ONE
  10. #define __HAVE_ARCH_PUD_ALLOC_ONE
  11. #include <asm-generic/pgalloc.h>
  12. static inline void pmd_populate_kernel(struct mm_struct *mm,
  13. pmd_t *pmd, pte_t *pte)
  14. {
  15. set_pmd(pmd, __pmd((unsigned long)pte));
  16. }
  17. static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte)
  18. {
  19. set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
  20. }
  21. #ifndef __PAGETABLE_PMD_FOLDED
  22. static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  23. {
  24. set_pud(pud, __pud((unsigned long)pmd));
  25. }
  26. #endif
  27. #ifndef __PAGETABLE_PUD_FOLDED
  28. static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud)
  29. {
  30. set_p4d(p4d, __p4d((unsigned long)pud));
  31. }
  32. #endif /* __PAGETABLE_PUD_FOLDED */
  33. extern void pagetable_init(void);
  34. /*
  35. * Initialize a new pmd table with invalid pointers.
  36. */
  37. extern void pmd_init(unsigned long page, unsigned long pagetable);
  38. /*
  39. * Initialize a new pgd / pmd table with invalid pointers.
  40. */
  41. extern void pgd_init(unsigned long page);
  42. extern pgd_t *pgd_alloc(struct mm_struct *mm);
  43. #define __pte_free_tlb(tlb, pte, address) \
  44. do { \
  45. pgtable_pte_page_dtor(pte); \
  46. tlb_remove_page((tlb), pte); \
  47. } while (0)
  48. #ifndef __PAGETABLE_PMD_FOLDED
  49. static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  50. {
  51. pmd_t *pmd;
  52. struct page *pg;
  53. pg = alloc_page(GFP_KERNEL_ACCOUNT);
  54. if (!pg)
  55. return NULL;
  56. if (!pgtable_pmd_page_ctor(pg)) {
  57. __free_page(pg);
  58. return NULL;
  59. }
  60. pmd = (pmd_t *)page_address(pg);
  61. pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
  62. return pmd;
  63. }
  64. #define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x)
  65. #endif
  66. #ifndef __PAGETABLE_PUD_FOLDED
  67. static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
  68. {
  69. pud_t *pud;
  70. pud = (pud_t *) __get_free_page(GFP_KERNEL);
  71. if (pud)
  72. pud_init((unsigned long)pud, (unsigned long)invalid_pmd_table);
  73. return pud;
  74. }
  75. #define __pud_free_tlb(tlb, x, addr) pud_free((tlb)->mm, x)
  76. #endif /* __PAGETABLE_PUD_FOLDED */
  77. #endif /* _ASM_PGALLOC_H */