xref: /openbmc/linux/arch/sh/include/asm/pgalloc.h (revision f15cbe6f1a4b4d9df59142fc8e4abb973302cf44)
1*f15cbe6fSPaul Mundt #ifndef __ASM_SH_PGALLOC_H
2*f15cbe6fSPaul Mundt #define __ASM_SH_PGALLOC_H
3*f15cbe6fSPaul Mundt 
4*f15cbe6fSPaul Mundt #include <linux/quicklist.h>
5*f15cbe6fSPaul Mundt #include <asm/page.h>
6*f15cbe6fSPaul Mundt 
7*f15cbe6fSPaul Mundt #define QUICK_PGD 0	/* We preserve special mappings over free */
8*f15cbe6fSPaul Mundt #define QUICK_PT 1	/* Other page table pages that are zero on free */
9*f15cbe6fSPaul Mundt 
10*f15cbe6fSPaul Mundt static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
11*f15cbe6fSPaul Mundt 				       pte_t *pte)
12*f15cbe6fSPaul Mundt {
13*f15cbe6fSPaul Mundt 	set_pmd(pmd, __pmd((unsigned long)pte));
14*f15cbe6fSPaul Mundt }
15*f15cbe6fSPaul Mundt 
16*f15cbe6fSPaul Mundt static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
17*f15cbe6fSPaul Mundt 				pgtable_t pte)
18*f15cbe6fSPaul Mundt {
19*f15cbe6fSPaul Mundt 	set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
20*f15cbe6fSPaul Mundt }
21*f15cbe6fSPaul Mundt #define pmd_pgtable(pmd) pmd_page(pmd)
22*f15cbe6fSPaul Mundt 
23*f15cbe6fSPaul Mundt static inline void pgd_ctor(void *x)
24*f15cbe6fSPaul Mundt {
25*f15cbe6fSPaul Mundt 	pgd_t *pgd = x;
26*f15cbe6fSPaul Mundt 
27*f15cbe6fSPaul Mundt 	memcpy(pgd + USER_PTRS_PER_PGD,
28*f15cbe6fSPaul Mundt 	       swapper_pg_dir + USER_PTRS_PER_PGD,
29*f15cbe6fSPaul Mundt 	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
30*f15cbe6fSPaul Mundt }
31*f15cbe6fSPaul Mundt 
32*f15cbe6fSPaul Mundt /*
33*f15cbe6fSPaul Mundt  * Allocate and free page tables.
34*f15cbe6fSPaul Mundt  */
35*f15cbe6fSPaul Mundt static inline pgd_t *pgd_alloc(struct mm_struct *mm)
36*f15cbe6fSPaul Mundt {
37*f15cbe6fSPaul Mundt 	return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
38*f15cbe6fSPaul Mundt }
39*f15cbe6fSPaul Mundt 
40*f15cbe6fSPaul Mundt static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
41*f15cbe6fSPaul Mundt {
42*f15cbe6fSPaul Mundt 	quicklist_free(QUICK_PGD, NULL, pgd);
43*f15cbe6fSPaul Mundt }
44*f15cbe6fSPaul Mundt 
45*f15cbe6fSPaul Mundt static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
46*f15cbe6fSPaul Mundt 					  unsigned long address)
47*f15cbe6fSPaul Mundt {
48*f15cbe6fSPaul Mundt 	return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
49*f15cbe6fSPaul Mundt }
50*f15cbe6fSPaul Mundt 
51*f15cbe6fSPaul Mundt static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
52*f15cbe6fSPaul Mundt 					unsigned long address)
53*f15cbe6fSPaul Mundt {
54*f15cbe6fSPaul Mundt 	struct page *page;
55*f15cbe6fSPaul Mundt 	void *pg;
56*f15cbe6fSPaul Mundt 
57*f15cbe6fSPaul Mundt 	pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
58*f15cbe6fSPaul Mundt 	if (!pg)
59*f15cbe6fSPaul Mundt 		return NULL;
60*f15cbe6fSPaul Mundt 	page = virt_to_page(pg);
61*f15cbe6fSPaul Mundt 	pgtable_page_ctor(page);
62*f15cbe6fSPaul Mundt 	return page;
63*f15cbe6fSPaul Mundt }
64*f15cbe6fSPaul Mundt 
65*f15cbe6fSPaul Mundt static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
66*f15cbe6fSPaul Mundt {
67*f15cbe6fSPaul Mundt 	quicklist_free(QUICK_PT, NULL, pte);
68*f15cbe6fSPaul Mundt }
69*f15cbe6fSPaul Mundt 
70*f15cbe6fSPaul Mundt static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
71*f15cbe6fSPaul Mundt {
72*f15cbe6fSPaul Mundt 	pgtable_page_dtor(pte);
73*f15cbe6fSPaul Mundt 	quicklist_free_page(QUICK_PT, NULL, pte);
74*f15cbe6fSPaul Mundt }
75*f15cbe6fSPaul Mundt 
76*f15cbe6fSPaul Mundt #define __pte_free_tlb(tlb,pte)				\
77*f15cbe6fSPaul Mundt do {							\
78*f15cbe6fSPaul Mundt 	pgtable_page_dtor(pte);				\
79*f15cbe6fSPaul Mundt 	tlb_remove_page((tlb), (pte));			\
80*f15cbe6fSPaul Mundt } while (0)
81*f15cbe6fSPaul Mundt 
82*f15cbe6fSPaul Mundt /*
83*f15cbe6fSPaul Mundt  * allocating and freeing a pmd is trivial: the 1-entry pmd is
84*f15cbe6fSPaul Mundt  * inside the pgd, so has no extra memory associated with it.
85*f15cbe6fSPaul Mundt  */
86*f15cbe6fSPaul Mundt 
87*f15cbe6fSPaul Mundt #define pmd_free(mm, x)			do { } while (0)
88*f15cbe6fSPaul Mundt #define __pmd_free_tlb(tlb,x)		do { } while (0)
89*f15cbe6fSPaul Mundt 
90*f15cbe6fSPaul Mundt static inline void check_pgt_cache(void)
91*f15cbe6fSPaul Mundt {
92*f15cbe6fSPaul Mundt 	quicklist_trim(QUICK_PGD, NULL, 25, 16);
93*f15cbe6fSPaul Mundt 	quicklist_trim(QUICK_PT, NULL, 25, 16);
94*f15cbe6fSPaul Mundt }
95*f15cbe6fSPaul Mundt 
96*f15cbe6fSPaul Mundt #endif /* __ASM_SH_PGALLOC_H */
97