Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _SPARC64_PGALLOC_H
0003 #define _SPARC64_PGALLOC_H
0004 
0005 #include <linux/kernel.h>
0006 #include <linux/sched.h>
0007 #include <linux/mm.h>
0008 #include <linux/slab.h>
0009 
0010 #include <asm/spitfire.h>
0011 #include <asm/cpudata.h>
0012 #include <asm/cacheflush.h>
0013 #include <asm/page.h>
0014 
0015 /* Page table allocation/freeing. */
0016 
0017 extern struct kmem_cache *pgtable_cache;
0018 
0019 static inline void __p4d_populate(p4d_t *p4d, pud_t *pud)
0020 {
0021     p4d_set(p4d, pud);
0022 }
0023 
0024 #define p4d_populate(MM, P4D, PUD)  __p4d_populate(P4D, PUD)
0025 
0026 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
0027 {
0028     return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
0029 }
0030 
0031 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
0032 {
0033     kmem_cache_free(pgtable_cache, pgd);
0034 }
0035 
0036 static inline void __pud_populate(pud_t *pud, pmd_t *pmd)
0037 {
0038     pud_set(pud, pmd);
0039 }
0040 
0041 #define pud_populate(MM, PUD, PMD)  __pud_populate(PUD, PMD)
0042 
0043 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
0044 {
0045     return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
0046 }
0047 
0048 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
0049 {
0050     kmem_cache_free(pgtable_cache, pud);
0051 }
0052 
0053 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
0054 {
0055     return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
0056 }
0057 
0058 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
0059 {
0060     kmem_cache_free(pgtable_cache, pmd);
0061 }
0062 
0063 pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
0064 pgtable_t pte_alloc_one(struct mm_struct *mm);
0065 void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
0066 void pte_free(struct mm_struct *mm, pgtable_t ptepage);
0067 
0068 #define pmd_populate_kernel(MM, PMD, PTE)   pmd_set(MM, PMD, PTE)
0069 #define pmd_populate(MM, PMD, PTE)      pmd_set(MM, PMD, PTE)
0070 
0071 void pgtable_free(void *table, bool is_page);
0072 
0073 #ifdef CONFIG_SMP
0074 
0075 struct mmu_gather;
0076 void tlb_remove_table(struct mmu_gather *, void *);
0077 
0078 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page)
0079 {
0080     unsigned long pgf = (unsigned long)table;
0081     if (is_page)
0082         pgf |= 0x1UL;
0083     tlb_remove_table(tlb, (void *)pgf);
0084 }
0085 
0086 static inline void __tlb_remove_table(void *_table)
0087 {
0088     void *table = (void *)((unsigned long)_table & ~0x1UL);
0089     bool is_page = false;
0090 
0091     if ((unsigned long)_table & 0x1UL)
0092         is_page = true;
0093     pgtable_free(table, is_page);
0094 }
0095 #else /* CONFIG_SMP */
0096 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page)
0097 {
0098     pgtable_free(table, is_page);
0099 }
0100 #endif /* !CONFIG_SMP */
0101 
0102 static inline void __pte_free_tlb(struct mmu_gather *tlb, pte_t *pte,
0103                   unsigned long address)
0104 {
0105     pgtable_free_tlb(tlb, pte, true);
0106 }
0107 
0108 #define __pmd_free_tlb(tlb, pmd, addr)            \
0109     pgtable_free_tlb(tlb, pmd, false)
0110 
0111 #define __pud_free_tlb(tlb, pud, addr)            \
0112     pgtable_free_tlb(tlb, pud, false)
0113 
0114 #endif /* _SPARC64_PGALLOC_H */