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.h89
1 files changed, 51 insertions, 38 deletions
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 801b31f71452..bcb5446a08d1 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -20,30 +20,25 @@
20#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ 20#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
21#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ 21#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
22 22
23/* 23#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
24 * Note: we use _AC(1, L) instead of _AC(1, UL) so that we get a 24#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
25 * sign-extended value on 32-bit with all 1's in the upper word, 25#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER)
26 * which preserves the upper pte values on 64-bit ptes: 26#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
27 */ 27#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
28#define _PAGE_PRESENT (_AC(1, L)<<_PAGE_BIT_PRESENT) 28#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
29#define _PAGE_RW (_AC(1, L)<<_PAGE_BIT_RW) 29#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
30#define _PAGE_USER (_AC(1, L)<<_PAGE_BIT_USER) 30#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
31#define _PAGE_PWT (_AC(1, L)<<_PAGE_BIT_PWT) 31#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
32#define _PAGE_PCD (_AC(1, L)<<_PAGE_BIT_PCD) 32#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
33#define _PAGE_ACCESSED (_AC(1, L)<<_PAGE_BIT_ACCESSED) 33#define _PAGE_UNUSED2 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED2)
34#define _PAGE_DIRTY (_AC(1, L)<<_PAGE_BIT_DIRTY) 34#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
35#define _PAGE_PSE (_AC(1, L)<<_PAGE_BIT_PSE) /* 2MB page */ 35#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
36#define _PAGE_GLOBAL (_AC(1, L)<<_PAGE_BIT_GLOBAL) /* Global TLB entry */ 36#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
37#define _PAGE_UNUSED1 (_AC(1, L)<<_PAGE_BIT_UNUSED1)
38#define _PAGE_UNUSED2 (_AC(1, L)<<_PAGE_BIT_UNUSED2)
39#define _PAGE_UNUSED3 (_AC(1, L)<<_PAGE_BIT_UNUSED3)
40#define _PAGE_PAT (_AC(1, L)<<_PAGE_BIT_PAT)
41#define _PAGE_PAT_LARGE (_AC(1, L)<<_PAGE_BIT_PAT_LARGE)
42 37
43#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) 38#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
44#define _PAGE_NX (_AC(1, ULL) << _PAGE_BIT_NX) 39#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
45#else 40#else
46#define _PAGE_NX 0 41#define _PAGE_NX (_AT(pteval_t, 0))
47#endif 42#endif
48 43
49/* If _PAGE_PRESENT is clear, we use these: */ 44/* If _PAGE_PRESENT is clear, we use these: */
@@ -57,7 +52,9 @@
57#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ 52#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
58 _PAGE_DIRTY) 53 _PAGE_DIRTY)
59 54
60#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) 55/* Set of bits not changed in pte_modify */
56#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_PCD | _PAGE_PWT | \
57 _PAGE_ACCESSED | _PAGE_DIRTY)
61 58
62#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) 59#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT)
63#define _PAGE_CACHE_WB (0) 60#define _PAGE_CACHE_WB (0)
@@ -162,37 +159,37 @@ extern struct list_head pgd_list;
162 */ 159 */
163static inline int pte_dirty(pte_t pte) 160static inline int pte_dirty(pte_t pte)
164{ 161{
165 return pte_val(pte) & _PAGE_DIRTY; 162 return pte_flags(pte) & _PAGE_DIRTY;
166} 163}
167 164
168static inline int pte_young(pte_t pte) 165static inline int pte_young(pte_t pte)
169{ 166{
170 return pte_val(pte) & _PAGE_ACCESSED; 167 return pte_flags(pte) & _PAGE_ACCESSED;
171} 168}
172 169
173static inline int pte_write(pte_t pte) 170static inline int pte_write(pte_t pte)
174{ 171{
175 return pte_val(pte) & _PAGE_RW; 172 return pte_flags(pte) & _PAGE_RW;
176} 173}
177 174
178static inline int pte_file(pte_t pte) 175static inline int pte_file(pte_t pte)
179{ 176{
180 return pte_val(pte) & _PAGE_FILE; 177 return pte_flags(pte) & _PAGE_FILE;
181} 178}
182 179
183static inline int pte_huge(pte_t pte) 180static inline int pte_huge(pte_t pte)
184{ 181{
185 return pte_val(pte) & _PAGE_PSE; 182 return pte_flags(pte) & _PAGE_PSE;
186} 183}
187 184
188static inline int pte_global(pte_t pte) 185static inline int pte_global(pte_t pte)
189{ 186{
190 return pte_val(pte) & _PAGE_GLOBAL; 187 return pte_flags(pte) & _PAGE_GLOBAL;
191} 188}
192 189
193static inline int pte_exec(pte_t pte) 190static inline int pte_exec(pte_t pte)
194{ 191{
195 return !(pte_val(pte) & _PAGE_NX); 192 return !(pte_flags(pte) & _PAGE_NX);
196} 193}
197 194
198static inline int pte_special(pte_t pte) 195static inline int pte_special(pte_t pte)
@@ -208,22 +205,22 @@ static inline int pmd_large(pmd_t pte)
208 205
209static inline pte_t pte_mkclean(pte_t pte) 206static inline pte_t pte_mkclean(pte_t pte)
210{ 207{
211 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); 208 return __pte(pte_val(pte) & ~_PAGE_DIRTY);
212} 209}
213 210
214static inline pte_t pte_mkold(pte_t pte) 211static inline pte_t pte_mkold(pte_t pte)
215{ 212{
216 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); 213 return __pte(pte_val(pte) & ~_PAGE_ACCESSED);
217} 214}
218 215
219static inline pte_t pte_wrprotect(pte_t pte) 216static inline pte_t pte_wrprotect(pte_t pte)
220{ 217{
221 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); 218 return __pte(pte_val(pte) & ~_PAGE_RW);
222} 219}
223 220
224static inline pte_t pte_mkexec(pte_t pte) 221static inline pte_t pte_mkexec(pte_t pte)
225{ 222{
226 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); 223 return __pte(pte_val(pte) & ~_PAGE_NX);
227} 224}
228 225
229static inline pte_t pte_mkdirty(pte_t pte) 226static inline pte_t pte_mkdirty(pte_t pte)
@@ -248,7 +245,7 @@ static inline pte_t pte_mkhuge(pte_t pte)
248 245
249static inline pte_t pte_clrhuge(pte_t pte) 246static inline pte_t pte_clrhuge(pte_t pte)
250{ 247{
251 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_PSE); 248 return __pte(pte_val(pte) & ~_PAGE_PSE);
252} 249}
253 250
254static inline pte_t pte_mkglobal(pte_t pte) 251static inline pte_t pte_mkglobal(pte_t pte)
@@ -258,7 +255,7 @@ static inline pte_t pte_mkglobal(pte_t pte)
258 255
259static inline pte_t pte_clrglobal(pte_t pte) 256static inline pte_t pte_clrglobal(pte_t pte)
260{ 257{
261 return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); 258 return __pte(pte_val(pte) & ~_PAGE_GLOBAL);
262} 259}
263 260
264static inline pte_t pte_mkspecial(pte_t pte) 261static inline pte_t pte_mkspecial(pte_t pte)
@@ -288,13 +285,22 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
288 * Chop off the NX bit (if present), and add the NX portion of 285 * Chop off the NX bit (if present), and add the NX portion of
289 * the newprot (if present): 286 * the newprot (if present):
290 */ 287 */
291 val &= _PAGE_CHG_MASK & ~_PAGE_NX; 288 val &= _PAGE_CHG_MASK;
292 val |= pgprot_val(newprot) & __supported_pte_mask; 289 val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask;
293 290
294 return __pte(val); 291 return __pte(val);
295} 292}
296 293
297#define pte_pgprot(x) __pgprot(pte_val(x) & (0xfff | _PAGE_NX)) 294/* mprotect needs to preserve PAT bits when updating vm_page_prot */
295#define pgprot_modify pgprot_modify
296static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
297{
298 pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK;
299 pgprotval_t addbits = pgprot_val(newprot);
300 return __pgprot(preservebits | addbits);
301}
302
303#define pte_pgprot(x) __pgprot(pte_flags(x) & ~PTE_MASK)
298 304
299#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) 305#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
300 306
@@ -358,8 +364,15 @@ enum {
358 PG_LEVEL_4K, 364 PG_LEVEL_4K,
359 PG_LEVEL_2M, 365 PG_LEVEL_2M,
360 PG_LEVEL_1G, 366 PG_LEVEL_1G,
367 PG_LEVEL_NUM
361}; 368};
362 369
370#ifdef CONFIG_PROC_FS
371extern void update_page_count(int level, unsigned long pages);
372#else
373static inline void update_page_count(int level, unsigned long pages) { }
374#endif
375
363/* 376/*
364 * Helper function that returns the kernel pagetable entry controlling 377 * Helper function that returns the kernel pagetable entry controlling
365 * the virtual address 'address'. NULL means no pagetable entry present. 378 * the virtual address 'address'. NULL means no pagetable entry present.