pgalloc.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
  12. #include <asm-generic/pgalloc.h>
  13. static inline void pmd_populate_kernel(struct mm_struct *mm,
  14. pmd_t *pmd, pte_t *pte)
  15. {
  16. set_pmd(pmd, __pmd((unsigned long)pte));
  17. }
  18. static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte)
  19. {
  20. set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
  21. }
  22. #ifndef __PAGETABLE_PMD_FOLDED
  23. static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  24. {
  25. set_pud(pud, __pud((unsigned long)pmd));
  26. }
  27. #endif
  28. #ifndef __PAGETABLE_PUD_FOLDED
  29. static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud)
  30. {
  31. set_p4d(p4d, __p4d((unsigned long)pud));
  32. }
  33. #endif /* __PAGETABLE_PUD_FOLDED */
  34. extern void pagetable_init(void);
  35. extern pgd_t *pgd_alloc(struct mm_struct *mm);
  36. static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
  37. {
  38. pte_t *pte = __pte_alloc_one_kernel(mm);
  39. if (pte)
  40. kernel_pte_init(pte);
  41. return pte;
  42. }
  43. #define __pte_free_tlb(tlb, pte, address) tlb_remove_ptdesc((tlb), page_ptdesc(pte))
  44. #ifndef __PAGETABLE_PMD_FOLDED
  45. static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  46. {
  47. pmd_t *pmd;
  48. struct ptdesc *ptdesc;
  49. ptdesc = pagetable_alloc(GFP_KERNEL_ACCOUNT, 0);
  50. if (!ptdesc)
  51. return NULL;
  52. if (!pagetable_pmd_ctor(mm, ptdesc)) {
  53. pagetable_free(ptdesc);
  54. return NULL;
  55. }
  56. pmd = ptdesc_address(ptdesc);
  57. pmd_init(pmd);
  58. return pmd;
  59. }
  60. #define __pmd_free_tlb(tlb, x, addr) tlb_remove_ptdesc((tlb), virt_to_ptdesc(x))
  61. #endif
  62. #ifndef __PAGETABLE_PUD_FOLDED
  63. static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
  64. {
  65. pud_t *pud;
  66. struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
  67. if (!ptdesc)
  68. return NULL;
  69. pagetable_pud_ctor(ptdesc);
  70. pud = ptdesc_address(ptdesc);
  71. pud_init(pud);
  72. return pud;
  73. }
  74. #define __pud_free_tlb(tlb, x, addr) tlb_remove_ptdesc((tlb), virt_to_ptdesc(x))
  75. #endif /* __PAGETABLE_PUD_FOLDED */
  76. extern pte_t * __init populate_kernel_pte(unsigned long addr);
  77. #endif /* _ASM_PGALLOC_H */