~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/hexagon/include/asm/pgalloc.h

Version: ~ [ linux-5.8 ] ~ [ linux-5.7.12 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.55 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.136 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.191 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.232 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.232 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Page table support for the Hexagon architecture
  3  *
  4  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 and
  8  * only version 2 as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU General Public License
 16  * along with this program; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 18  * 02110-1301, USA.
 19  */
 20 
 21 #ifndef _ASM_PGALLOC_H
 22 #define _ASM_PGALLOC_H
 23 
 24 #include <asm/mem-layout.h>
 25 #include <asm/atomic.h>
 26 
 27 #define check_pgt_cache() do {} while (0)
 28 
 29 extern unsigned long long kmap_generation;
 30 
 31 /*
 32  * Page table creation interface
 33  */
 34 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 35 {
 36         pgd_t *pgd;
 37 
 38         pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
 39 
 40         /*
 41          * There may be better ways to do this, but to ensure
 42          * that new address spaces always contain the kernel
 43          * base mapping, and to ensure that the user area is
 44          * initially marked invalid, initialize the new map
 45          * map with a copy of the kernel's persistent map.
 46          */
 47 
 48         memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t *));
 49         mm->context.generation = kmap_generation;
 50 
 51         /* Physical version is what is passed to virtual machine on switch */
 52         mm->context.ptbase = __pa(pgd);
 53 
 54         return pgd;
 55 }
 56 
 57 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 58 {
 59         free_page((unsigned long) pgd);
 60 }
 61 
 62 static inline struct page *pte_alloc_one(struct mm_struct *mm,
 63                                          unsigned long address)
 64 {
 65         struct page *pte;
 66 
 67         pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
 68         if (!pte)
 69                 return NULL;
 70         if (!pgtable_page_ctor(pte)) {
 71                 __free_page(pte);
 72                 return NULL;
 73         }
 74         return pte;
 75 }
 76 
 77 /* _kernel variant gets to use a different allocator */
 78 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 79                                           unsigned long address)
 80 {
 81         gfp_t flags =  GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO;
 82         return (pte_t *) __get_free_page(flags);
 83 }
 84 
 85 static inline void pte_free(struct mm_struct *mm, struct page *pte)
 86 {
 87         pgtable_page_dtor(pte);
 88         __free_page(pte);
 89 }
 90 
 91 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 92 {
 93         free_page((unsigned long)pte);
 94 }
 95 
 96 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 97                                 pgtable_t pte)
 98 {
 99         /*
100          * Conveniently, zero in 3 LSB means indirect 4K page table.
101          * Not so convenient when you're trying to vary the page size.
102          */
103         set_pmd(pmd, __pmd(((unsigned long)page_to_pfn(pte) << PAGE_SHIFT) |
104                 HEXAGON_L1_PTE_SIZE));
105 }
106 
107 /*
108  * Other architectures seem to have ways of making all processes
109  * share the same pmd's for their kernel mappings, but the v0.3
110  * Hexagon VM spec has a "monolithic" L1 table for user and kernel
111  * segments.  We track "generations" of the kernel map to minimize
112  * overhead, and update the "slave" copies of the kernel mappings
113  * as part of switch_mm.  However, we still need to update the
114  * kernel map of the active thread who's calling pmd_populate_kernel...
115  */
116 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
117                                        pte_t *pte)
118 {
119         extern spinlock_t kmap_gen_lock;
120         pmd_t *ppmd;
121         int pmdindex;
122 
123         spin_lock(&kmap_gen_lock);
124         kmap_generation++;
125         mm->context.generation = kmap_generation;
126         current->active_mm->context.generation = kmap_generation;
127         spin_unlock(&kmap_gen_lock);
128 
129         set_pmd(pmd, __pmd(((unsigned long)__pa(pte)) | HEXAGON_L1_PTE_SIZE));
130 
131         /*
132          * Now the "slave" copy of the current thread.
133          * This is pointer arithmetic, not byte addresses!
134          */
135         pmdindex = (pgd_t *)pmd - mm->pgd;
136         ppmd = (pmd_t *)current->active_mm->pgd + pmdindex;
137         set_pmd(ppmd, __pmd(((unsigned long)__pa(pte)) | HEXAGON_L1_PTE_SIZE));
138         if (pmdindex > max_kernel_seg)
139                 max_kernel_seg = pmdindex;
140 }
141 
142 #define __pte_free_tlb(tlb, pte, addr)          \
143 do {                                            \
144         pgtable_page_dtor((pte));               \
145         tlb_remove_page((tlb), (pte));          \
146 } while (0)
147 
148 #endif
149 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp