aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/pgtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-x86/pgtable.h')
-rw-r--r--include/asm-x86/pgtable.h178
1 files changed, 135 insertions, 43 deletions
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 9cf472aeb9ce..f1d9f4a03f6f 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -4,13 +4,13 @@
4#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1) 4#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1)
5#define FIRST_USER_ADDRESS 0 5#define FIRST_USER_ADDRESS 0
6 6
7#define _PAGE_BIT_PRESENT 0 7#define _PAGE_BIT_PRESENT 0 /* is present */
8#define _PAGE_BIT_RW 1 8#define _PAGE_BIT_RW 1 /* writeable */
9#define _PAGE_BIT_USER 2 9#define _PAGE_BIT_USER 2 /* userspace addressable */
10#define _PAGE_BIT_PWT 3 10#define _PAGE_BIT_PWT 3 /* page write through */
11#define _PAGE_BIT_PCD 4 11#define _PAGE_BIT_PCD 4 /* page cache disabled */
12#define _PAGE_BIT_ACCESSED 5 12#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */
13#define _PAGE_BIT_DIRTY 6 13#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */
14#define _PAGE_BIT_FILE 6 14#define _PAGE_BIT_FILE 6
15#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ 15#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
16#define _PAGE_BIT_PAT 7 /* on 4KB pages */ 16#define _PAGE_BIT_PAT 7 /* on 4KB pages */
@@ -48,24 +48,39 @@
48#endif 48#endif
49 49
50/* If _PAGE_PRESENT is clear, we use these: */ 50/* If _PAGE_PRESENT is clear, we use these: */
51#define _PAGE_FILE _PAGE_DIRTY /* nonlinear file mapping, saved PTE; unset:swap */ 51#define _PAGE_FILE _PAGE_DIRTY /* nonlinear file mapping,
52 * saved PTE; unset:swap */
52#define _PAGE_PROTNONE _PAGE_PSE /* if the user mapped it with PROT_NONE; 53#define _PAGE_PROTNONE _PAGE_PSE /* if the user mapped it with PROT_NONE;
53 pte_present gives true */ 54 pte_present gives true */
54 55
55#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) 56#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
56#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 57 _PAGE_ACCESSED | _PAGE_DIRTY)
58#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
59 _PAGE_DIRTY)
57 60
58#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) 61#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
59 62
60#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) 63#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT)
61#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) 64#define _PAGE_CACHE_WB (0)
65#define _PAGE_CACHE_WC (_PAGE_PWT)
66#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD)
67#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT)
62 68
63#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) 69#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
64#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) 70#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
65#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) 71 _PAGE_ACCESSED | _PAGE_NX)
72
73#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \
74 _PAGE_USER | _PAGE_ACCESSED)
75#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
76 _PAGE_ACCESSED | _PAGE_NX)
77#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
78 _PAGE_ACCESSED)
66#define PAGE_COPY PAGE_COPY_NOEXEC 79#define PAGE_COPY PAGE_COPY_NOEXEC
67#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) 80#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \
68#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) 81 _PAGE_ACCESSED | _PAGE_NX)
82#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
83 _PAGE_ACCESSED)
69 84
70#ifdef CONFIG_X86_32 85#ifdef CONFIG_X86_32
71#define _PAGE_KERNEL_EXEC \ 86#define _PAGE_KERNEL_EXEC \
@@ -84,6 +99,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
84#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) 99#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
85#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) 100#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
86#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT) 101#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
102#define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
87#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) 103#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
88#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD) 104#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
89#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) 105#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
@@ -101,6 +117,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
101#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) 117#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
102#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) 118#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
103#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX) 119#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX)
120#define PAGE_KERNEL_WC MAKE_GLOBAL(__PAGE_KERNEL_WC)
104#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) 121#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
105#define PAGE_KERNEL_UC_MINUS MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS) 122#define PAGE_KERNEL_UC_MINUS MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
106#define PAGE_KERNEL_EXEC_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE) 123#define PAGE_KERNEL_EXEC_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
@@ -134,7 +151,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
134 * ZERO_PAGE is a global shared page that is always zero: used 151 * ZERO_PAGE is a global shared page that is always zero: used
135 * for zero-mapped memory areas etc.. 152 * for zero-mapped memory areas etc..
136 */ 153 */
137extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; 154extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
138#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) 155#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
139 156
140extern spinlock_t pgd_lock; 157extern spinlock_t pgd_lock;
@@ -144,30 +161,101 @@ extern struct list_head pgd_list;
144 * The following only work if pte_present() is true. 161 * The following only work if pte_present() is true.
145 * Undefined behaviour if not.. 162 * Undefined behaviour if not..
146 */ 163 */
147static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } 164static inline int pte_dirty(pte_t pte)
148static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } 165{
149static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } 166 return pte_val(pte) & _PAGE_DIRTY;
150static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } 167}
151static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; } 168
152static inline int pte_global(pte_t pte) { return pte_val(pte) & _PAGE_GLOBAL; } 169static inline int pte_young(pte_t pte)
153static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); } 170{
154 171 return pte_val(pte) & _PAGE_ACCESSED;
155static inline int pmd_large(pmd_t pte) { 172}
156 return (pmd_val(pte) & (_PAGE_PSE|_PAGE_PRESENT)) == 173
157 (_PAGE_PSE|_PAGE_PRESENT); 174static inline int pte_write(pte_t pte)
175{
176 return pte_val(pte) & _PAGE_RW;
177}
178
179static inline int pte_file(pte_t pte)
180{
181 return pte_val(pte) & _PAGE_FILE;
182}
183
184static inline int pte_huge(pte_t pte)
185{
186 return pte_val(pte) & _PAGE_PSE;
187}
188
189static inline int pte_global(pte_t pte)
190{
191 return pte_val(pte) & _PAGE_GLOBAL;
192}
193
194static inline int pte_exec(pte_t pte)
195{
196 return !(pte_val(pte) & _PAGE_NX);
197}
198
199static inline int pmd_large(pmd_t pte)
200{
201 return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
202 (_PAGE_PSE | _PAGE_PRESENT);
203}
204
205static inline pte_t pte_mkclean(pte_t pte)
206{
207 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY);
208}
209
210static inline pte_t pte_mkold(pte_t pte)
211{
212 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED);
213}
214
215static inline pte_t pte_wrprotect(pte_t pte)
216{
217 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW);
218}
219
220static inline pte_t pte_mkexec(pte_t pte)
221{
222 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
223}
224
225static inline pte_t pte_mkdirty(pte_t pte)
226{
227 return __pte(pte_val(pte) | _PAGE_DIRTY);
228}
229
230static inline pte_t pte_mkyoung(pte_t pte)
231{
232 return __pte(pte_val(pte) | _PAGE_ACCESSED);
158} 233}
159 234
160static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); } 235static inline pte_t pte_mkwrite(pte_t pte)
161static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); } 236{
162static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); } 237 return __pte(pte_val(pte) | _PAGE_RW);
163static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); } 238}
164static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); } 239
165static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); } 240static inline pte_t pte_mkhuge(pte_t pte)
166static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); } 241{
167static inline pte_t pte_mkhuge(pte_t pte) { return __pte(pte_val(pte) | _PAGE_PSE); } 242 return __pte(pte_val(pte) | _PAGE_PSE);
168static inline pte_t pte_clrhuge(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_PSE); } 243}
169static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); } 244
170static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); } 245static inline pte_t pte_clrhuge(pte_t pte)
246{
247 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_PSE);
248}
249
250static inline pte_t pte_mkglobal(pte_t pte)
251{
252 return __pte(pte_val(pte) | _PAGE_GLOBAL);
253}
254
255static inline pte_t pte_clrglobal(pte_t pte)
256{
257 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL);
258}
171 259
172extern pteval_t __supported_pte_mask; 260extern pteval_t __supported_pte_mask;
173 261
@@ -334,7 +422,8 @@ static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr,
334}) 422})
335 423
336#define __HAVE_ARCH_PTEP_GET_AND_CLEAR 424#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
337static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 425static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
426 pte_t *ptep)
338{ 427{
339 pte_t pte = native_ptep_get_and_clear(ptep); 428 pte_t pte = native_ptep_get_and_clear(ptep);
340 pte_update(mm, addr, ptep); 429 pte_update(mm, addr, ptep);
@@ -342,7 +431,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
342} 431}
343 432
344#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL 433#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
345static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full) 434static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
435 unsigned long addr, pte_t *ptep,
436 int full)
346{ 437{
347 pte_t pte; 438 pte_t pte;
348 if (full) { 439 if (full) {
@@ -358,7 +449,8 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
358} 449}
359 450
360#define __HAVE_ARCH_PTEP_SET_WRPROTECT 451#define __HAVE_ARCH_PTEP_SET_WRPROTECT
361static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 452static inline void ptep_set_wrprotect(struct mm_struct *mm,
453 unsigned long addr, pte_t *ptep)
362{ 454{
363 clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); 455 clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte);
364 pte_update(mm, addr, ptep); 456 pte_update(mm, addr, ptep);