1633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
2633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This file is subject to the terms and conditions of the GNU General Public
3633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * License.  See the file "COPYING" in the main directory of this archive
4633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * for more details.
5633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
6633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 1994 - 2001, 2003 by Ralf Baechle
7633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
8633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
9633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _ASM_PGALLOC_H
10633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define _ASM_PGALLOC_H
11633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
12633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/highmem.h>
13633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/mm.h>
14633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/sched.h>
15633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
16633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
17633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pte_t *pte)
18633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
19633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	set_pmd(pmd, __pmd((unsigned long)pte));
20633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
21633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
22633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
23633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pgtable_t pte)
24633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
25633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
26633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
27633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define pmd_pgtable(pmd) pmd_page(pmd)
28633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
29633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
30633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Initialize a new pmd table with invalid pointers.
31633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
32633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamextern void pmd_init(unsigned long page, unsigned long pagetable);
33633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
34633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_64BIT
35633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
36633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
37633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
38633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	set_pud(pud, __pud((unsigned long)pmd));
39633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
40633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
41633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
42633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
43633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Initialize a new pgd / pmd table with invalid pointers.
44633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
45633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamextern void pgd_init(unsigned long page);
46633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
47633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline pgd_t *pgd_alloc(struct mm_struct *mm)
48633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
49633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pgd_t *ret, *init;
50633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
51633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
52633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (ret) {
53633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		init = pgd_offset(&init_mm, 0UL);
54633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		pgd_init((unsigned long)ret);
55633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
56633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
57633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
58633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
59633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return ret;
60633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
61633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
62633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
63633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
64633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	free_pages((unsigned long)pgd, PGD_ORDER);
65633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
66633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
67633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
68633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long address)
69633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
70633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pte_t *pte;
71633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
72633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
73633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
74633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return pte;
75633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
76633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
77633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline struct page *pte_alloc_one(struct mm_struct *mm,
78633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long address)
79633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
80633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	struct page *pte;
81633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
82633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
83633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (pte) {
84633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		clear_highpage(pte);
85633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		pgtable_page_ctor(pte);
86633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
87633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return pte;
88633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
89633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
90633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
91633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
92633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	free_pages((unsigned long)pte, PTE_ORDER);
93633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
94633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
95633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pte_free(struct mm_struct *mm, pgtable_t pte)
96633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
97633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pgtable_page_dtor(pte);
98633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	__free_pages(pte, PTE_ORDER);
99633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
100633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
101633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __pte_free_tlb(tlb,pte)				\
102633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamdo {							\
103633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pgtable_page_dtor(pte);				\
104633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	tlb_remove_page((tlb), pte);			\
105633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} while (0)
106633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
107633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_32BIT
108633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
109633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
110633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * allocating and freeing a pmd is trivial: the 1-entry pmd is
111633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * inside the pgd, so has no extra memory associated with it.
112633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
113633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define pmd_free(mm, x)			do { } while (0)
114633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __pmd_free_tlb(tlb, x)		do { } while (0)
115633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
116633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
117633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
118633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_64BIT
119633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
120633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
121633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
122633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pmd_t *pmd;
123633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
124633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	pmd = (pmd_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PMD_ORDER);
125633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (pmd)
126633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
127633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return pmd;
128633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
129633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
130633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
131633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
132633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	free_pages((unsigned long)pmd, PMD_ORDER);
133633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
134633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
135633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __pmd_free_tlb(tlb, x)	pmd_free((tlb)->mm, x)
136633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
137633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
138633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
139633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define check_pgt_cache()	do { } while (0)
140633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
141633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamextern void pagetable_init(void);
142633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
143633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* _ASM_PGALLOC_H */
144