diff options
| -rw-r--r-- | include/asm-alpha/pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-arm/pgtable.h | 3 | ||||
| -rw-r--r-- | include/asm-avr32/pgtable.h | 8 | ||||
| -rw-r--r-- | include/asm-cris/pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-frv/pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-ia64/pgtable.h | 3 | ||||
| -rw-r--r-- | include/asm-m32r/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-m68k/motorola_pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-m68k/sun3_pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-mips/pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-mn10300/pgtable.h | 3 | ||||
| -rw-r--r-- | include/asm-parisc/pgtable.h | 2 | ||||
| -rw-r--r-- | include/asm-powerpc/pgtable-ppc32.h | 3 | ||||
| -rw-r--r-- | include/asm-powerpc/pgtable-ppc64.h | 3 | ||||
| -rw-r--r-- | include/asm-ppc/pgtable.h | 3 | ||||
| -rw-r--r-- | include/asm-s390/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-sh/pgtable_32.h | 3 | ||||
| -rw-r--r-- | include/asm-sh/pgtable_64.h | 10 | ||||
| -rw-r--r-- | include/asm-sparc/pgtable.h | 7 | ||||
| -rw-r--r-- | include/asm-sparc64/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-um/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-x86/pgtable.h | 10 | ||||
| -rw-r--r-- | include/asm-xtensa/pgtable.h | 4 | ||||
| -rw-r--r-- | include/linux/mm.h | 4 | ||||
| -rw-r--r-- | mm/memory.c | 99 |
25 files changed, 168 insertions, 49 deletions
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h index 99037b032357..05ce5fba43e3 100644 --- a/include/asm-alpha/pgtable.h +++ b/include/asm-alpha/pgtable.h | |||
| @@ -268,6 +268,7 @@ extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_FOW); } | |||
| 268 | extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 268 | extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 269 | extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 269 | extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 270 | extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 270 | extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 271 | extern inline int pte_special(pte_t pte) { return 0; } | ||
| 271 | 272 | ||
| 272 | extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } | 273 | extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } |
| 273 | extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } | 274 | extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } |
| @@ -275,6 +276,7 @@ extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); ret | |||
| 275 | extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } | 276 | extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } |
| 276 | extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } | 277 | extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } |
| 277 | extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } | 278 | extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } |
| 279 | extern inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 278 | 280 | ||
| 279 | #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) | 281 | #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) |
| 280 | 282 | ||
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index 5e0182485d8c..5571c13c3f3b 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h | |||
| @@ -260,6 +260,7 @@ extern struct page *empty_zero_page; | |||
| 260 | #define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) | 260 | #define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) |
| 261 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) | 261 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) |
| 262 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | 262 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) |
| 263 | #define pte_special(pte) (0) | ||
| 263 | 264 | ||
| 264 | /* | 265 | /* |
| 265 | * The following only works if pte_present() is not true. | 266 | * The following only works if pte_present() is not true. |
| @@ -280,6 +281,8 @@ PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); | |||
| 280 | PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); | 281 | PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); |
| 281 | PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); | 282 | PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); |
| 282 | 283 | ||
| 284 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 285 | |||
| 283 | /* | 286 | /* |
| 284 | * Mark the prot value as uncacheable and unbufferable. | 287 | * Mark the prot value as uncacheable and unbufferable. |
| 285 | */ | 288 | */ |
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h index 3ae7b548fce7..c0e5e29417df 100644 --- a/include/asm-avr32/pgtable.h +++ b/include/asm-avr32/pgtable.h | |||
| @@ -212,6 +212,10 @@ static inline int pte_young(pte_t pte) | |||
| 212 | { | 212 | { |
| 213 | return pte_val(pte) & _PAGE_ACCESSED; | 213 | return pte_val(pte) & _PAGE_ACCESSED; |
| 214 | } | 214 | } |
| 215 | static inline int pte_special(pte_t pte) | ||
| 216 | { | ||
| 217 | return 0; | ||
| 218 | } | ||
| 215 | 219 | ||
| 216 | /* | 220 | /* |
| 217 | * The following only work if pte_present() is not true. | 221 | * The following only work if pte_present() is not true. |
| @@ -252,6 +256,10 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 252 | set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); | 256 | set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); |
| 253 | return pte; | 257 | return pte; |
| 254 | } | 258 | } |
| 259 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 260 | { | ||
| 261 | return pte; | ||
| 262 | } | ||
| 255 | 263 | ||
| 256 | #define pmd_none(x) (!pmd_val(x)) | 264 | #define pmd_none(x) (!pmd_val(x)) |
| 257 | #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) | 265 | #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) |
diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h index a2607575681b..4c373624ee97 100644 --- a/include/asm-cris/pgtable.h +++ b/include/asm-cris/pgtable.h | |||
| @@ -115,6 +115,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WR | |||
| 115 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } | 115 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } |
| 116 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 116 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 117 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 117 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 118 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 118 | 119 | ||
| 119 | static inline pte_t pte_wrprotect(pte_t pte) | 120 | static inline pte_t pte_wrprotect(pte_t pte) |
| 120 | { | 121 | { |
| @@ -162,6 +163,7 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 162 | } | 163 | } |
| 163 | return pte; | 164 | return pte; |
| 164 | } | 165 | } |
| 166 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 165 | 167 | ||
| 166 | /* | 168 | /* |
| 167 | * Conversion functions: convert a page and protection to a page entry, | 169 | * Conversion functions: convert a page and protection to a page entry, |
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h index 4e219046fe42..83c51aba534b 100644 --- a/include/asm-frv/pgtable.h +++ b/include/asm-frv/pgtable.h | |||
| @@ -380,6 +380,7 @@ static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address) | |||
| 380 | static inline int pte_dirty(pte_t pte) { return (pte).pte & _PAGE_DIRTY; } | 380 | static inline int pte_dirty(pte_t pte) { return (pte).pte & _PAGE_DIRTY; } |
| 381 | static inline int pte_young(pte_t pte) { return (pte).pte & _PAGE_ACCESSED; } | 381 | static inline int pte_young(pte_t pte) { return (pte).pte & _PAGE_ACCESSED; } |
| 382 | static inline int pte_write(pte_t pte) { return !((pte).pte & _PAGE_WP); } | 382 | static inline int pte_write(pte_t pte) { return !((pte).pte & _PAGE_WP); } |
| 383 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 383 | 384 | ||
| 384 | static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; } | 385 | static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; } |
| 385 | static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; } | 386 | static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; } |
| @@ -387,6 +388,7 @@ static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte |= _PAGE_WP; return pte | |||
| 387 | static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; } | 388 | static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; } |
| 388 | static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; } | 389 | static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; } |
| 389 | static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; } | 390 | static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; } |
| 391 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 390 | 392 | ||
| 391 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) | 393 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) |
| 392 | { | 394 | { |
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index ed70862ea247..7a9bff47564f 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h | |||
| @@ -302,6 +302,8 @@ ia64_phys_addr_valid (unsigned long addr) | |||
| 302 | #define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0) | 302 | #define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0) |
| 303 | #define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0) | 303 | #define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0) |
| 304 | #define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0) | 304 | #define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0) |
| 305 | #define pte_special(pte) 0 | ||
| 306 | |||
| 305 | /* | 307 | /* |
| 306 | * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the | 308 | * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the |
| 307 | * access rights: | 309 | * access rights: |
| @@ -313,6 +315,7 @@ ia64_phys_addr_valid (unsigned long addr) | |||
| 313 | #define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D)) | 315 | #define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D)) |
| 314 | #define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D)) | 316 | #define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D)) |
| 315 | #define pte_mkhuge(pte) (__pte(pte_val(pte))) | 317 | #define pte_mkhuge(pte) (__pte(pte_val(pte))) |
| 318 | #define pte_mkspecial(pte) (pte) | ||
| 316 | 319 | ||
| 317 | /* | 320 | /* |
| 318 | * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to | 321 | * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to |
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h index 86505387be08..e6359c566b50 100644 --- a/include/asm-m32r/pgtable.h +++ b/include/asm-m32r/pgtable.h | |||
| @@ -214,6 +214,11 @@ static inline int pte_file(pte_t pte) | |||
| 214 | return pte_val(pte) & _PAGE_FILE; | 214 | return pte_val(pte) & _PAGE_FILE; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static inline int pte_special(pte_t pte) | ||
| 218 | { | ||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 217 | static inline pte_t pte_mkclean(pte_t pte) | 222 | static inline pte_t pte_mkclean(pte_t pte) |
| 218 | { | 223 | { |
| 219 | pte_val(pte) &= ~_PAGE_DIRTY; | 224 | pte_val(pte) &= ~_PAGE_DIRTY; |
| @@ -250,6 +255,11 @@ static inline pte_t pte_mkwrite(pte_t pte) | |||
| 250 | return pte; | 255 | return pte; |
| 251 | } | 256 | } |
| 252 | 257 | ||
| 258 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 259 | { | ||
| 260 | return pte; | ||
| 261 | } | ||
| 262 | |||
| 253 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) | 263 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) |
| 254 | { | 264 | { |
| 255 | return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); | 265 | return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); |
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h index 13135d4821d8..8e9a8a754dde 100644 --- a/include/asm-m68k/motorola_pgtable.h +++ b/include/asm-m68k/motorola_pgtable.h | |||
| @@ -168,6 +168,7 @@ static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); | |||
| 168 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 168 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 169 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 169 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 170 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 170 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 171 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 171 | 172 | ||
| 172 | static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } | 173 | static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } |
| 173 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } | 174 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } |
| @@ -185,6 +186,7 @@ static inline pte_t pte_mkcache(pte_t pte) | |||
| 185 | pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; | 186 | pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; |
| 186 | return pte; | 187 | return pte; |
| 187 | } | 188 | } |
| 189 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 188 | 190 | ||
| 189 | #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) | 191 | #define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) |
| 190 | 192 | ||
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h index b766fc261bde..f847ec732d62 100644 --- a/include/asm-m68k/sun3_pgtable.h +++ b/include/asm-m68k/sun3_pgtable.h | |||
| @@ -169,6 +169,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEA | |||
| 169 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } | 169 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } |
| 170 | static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } | 170 | static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } |
| 171 | static inline int pte_file(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } | 171 | static inline int pte_file(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } |
| 172 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 172 | 173 | ||
| 173 | static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } | 174 | static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } |
| 174 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } | 175 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } |
| @@ -181,6 +182,7 @@ static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE | |||
| 181 | //static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } | 182 | //static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } |
| 182 | // until then, use: | 183 | // until then, use: |
| 183 | static inline pte_t pte_mkcache(pte_t pte) { return pte; } | 184 | static inline pte_t pte_mkcache(pte_t pte) { return pte; } |
| 185 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 184 | 186 | ||
| 185 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 187 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
| 186 | extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; | 188 | extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; |
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 17a7703a2969..782221e57c0a 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h | |||
| @@ -285,6 +285,8 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 285 | return pte; | 285 | return pte; |
| 286 | } | 286 | } |
| 287 | #endif | 287 | #endif |
| 288 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 289 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 288 | 290 | ||
| 289 | /* | 291 | /* |
| 290 | * Macro to make mark a page protection value as "uncacheable". Note | 292 | * Macro to make mark a page protection value as "uncacheable". Note |
diff --git a/include/asm-mn10300/pgtable.h b/include/asm-mn10300/pgtable.h index 375c4941deda..6dc30fc827c4 100644 --- a/include/asm-mn10300/pgtable.h +++ b/include/asm-mn10300/pgtable.h | |||
| @@ -224,6 +224,7 @@ static inline int pte_read(pte_t pte) { return pte_val(pte) & __PAGE_PROT_USER; | |||
| 224 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 224 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 225 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 225 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 226 | static inline int pte_write(pte_t pte) { return pte_val(pte) & __PAGE_PROT_WRITE; } | 226 | static inline int pte_write(pte_t pte) { return pte_val(pte) & __PAGE_PROT_WRITE; } |
| 227 | static inline int pte_special(pte_t pte){ return 0; } | ||
| 227 | 228 | ||
| 228 | /* | 229 | /* |
| 229 | * The following only works if pte_present() is not true. | 230 | * The following only works if pte_present() is not true. |
| @@ -265,6 +266,8 @@ static inline pte_t pte_mkwrite(pte_t pte) | |||
| 265 | return pte; | 266 | return pte; |
| 266 | } | 267 | } |
| 267 | 268 | ||
| 269 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 270 | |||
| 268 | #define pte_ERROR(e) \ | 271 | #define pte_ERROR(e) \ |
| 269 | printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ | 272 | printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \ |
| 270 | __FILE__, __LINE__, pte_val(e)) | 273 | __FILE__, __LINE__, pte_val(e)) |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index dc86adbec916..470a4b88124d 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
| @@ -323,6 +323,7 @@ static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | |||
| 323 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 323 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 324 | static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } | 324 | static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } |
| 325 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 325 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 326 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 326 | 327 | ||
| 327 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } | 328 | static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } |
| 328 | static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } | 329 | static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } |
| @@ -330,6 +331,7 @@ static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; ret | |||
| 330 | static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } | 331 | static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } |
| 331 | static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } | 332 | static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } |
| 332 | static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; } | 333 | static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; } |
| 334 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 333 | 335 | ||
| 334 | /* | 336 | /* |
| 335 | * Conversion functions: convert a page and protection to a page entry, | 337 | * Conversion functions: convert a page and protection to a page entry, |
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index daea7692d070..7c97b5a08d08 100644 --- a/include/asm-powerpc/pgtable-ppc32.h +++ b/include/asm-powerpc/pgtable-ppc32.h | |||
| @@ -504,6 +504,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } | |||
| 504 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 504 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 505 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 505 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 506 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 506 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 507 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 507 | 508 | ||
| 508 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } | 509 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } |
| 509 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } | 510 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } |
| @@ -521,6 +522,8 @@ static inline pte_t pte_mkdirty(pte_t pte) { | |||
| 521 | pte_val(pte) |= _PAGE_DIRTY; return pte; } | 522 | pte_val(pte) |= _PAGE_DIRTY; return pte; } |
| 522 | static inline pte_t pte_mkyoung(pte_t pte) { | 523 | static inline pte_t pte_mkyoung(pte_t pte) { |
| 523 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } | 524 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } |
| 525 | static inline pte_t pte_mkspecial(pte_t pte) { | ||
| 526 | return pte; } | ||
| 524 | 527 | ||
| 525 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 528 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 526 | { | 529 | { |
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h index dd4c26dc57d2..27f18695f7d6 100644 --- a/include/asm-powerpc/pgtable-ppc64.h +++ b/include/asm-powerpc/pgtable-ppc64.h | |||
| @@ -239,6 +239,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;} | |||
| 239 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;} | 239 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;} |
| 240 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;} | 240 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;} |
| 241 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;} | 241 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;} |
| 242 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 242 | 243 | ||
| 243 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } | 244 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } |
| 244 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } | 245 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } |
| @@ -257,6 +258,8 @@ static inline pte_t pte_mkyoung(pte_t pte) { | |||
| 257 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } | 258 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } |
| 258 | static inline pte_t pte_mkhuge(pte_t pte) { | 259 | static inline pte_t pte_mkhuge(pte_t pte) { |
| 259 | return pte; } | 260 | return pte; } |
| 261 | static inline pte_t pte_mkspecial(pte_t pte) { | ||
| 262 | return pte; } | ||
| 260 | 263 | ||
| 261 | /* Atomic PTE updates */ | 264 | /* Atomic PTE updates */ |
| 262 | static inline unsigned long pte_update(struct mm_struct *mm, | 265 | static inline unsigned long pte_update(struct mm_struct *mm, |
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 70435d32129a..55f9d38e3bf8 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h | |||
| @@ -483,6 +483,7 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } | |||
| 483 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 483 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 484 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 484 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 485 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 485 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 486 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 486 | 487 | ||
| 487 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } | 488 | static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } |
| 488 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } | 489 | static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } |
| @@ -500,6 +501,8 @@ static inline pte_t pte_mkdirty(pte_t pte) { | |||
| 500 | pte_val(pte) |= _PAGE_DIRTY; return pte; } | 501 | pte_val(pte) |= _PAGE_DIRTY; return pte; } |
| 501 | static inline pte_t pte_mkyoung(pte_t pte) { | 502 | static inline pte_t pte_mkyoung(pte_t pte) { |
| 502 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } | 503 | pte_val(pte) |= _PAGE_ACCESSED; return pte; } |
| 504 | static inline pte_t pte_mkspecial(pte_t pte) { | ||
| 505 | return pte; } | ||
| 503 | 506 | ||
| 504 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 507 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 505 | { | 508 | { |
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 4c0698c0dda5..76e8a7904e8a 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
| @@ -518,6 +518,11 @@ static inline int pte_file(pte_t pte) | |||
| 518 | return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; | 518 | return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | static inline int pte_special(pte_t pte) | ||
| 522 | { | ||
| 523 | return 0; | ||
| 524 | } | ||
| 525 | |||
| 521 | #define __HAVE_ARCH_PTE_SAME | 526 | #define __HAVE_ARCH_PTE_SAME |
| 522 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) | 527 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) |
| 523 | 528 | ||
| @@ -715,6 +720,11 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 715 | return pte; | 720 | return pte; |
| 716 | } | 721 | } |
| 717 | 722 | ||
| 723 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 724 | { | ||
| 725 | return pte; | ||
| 726 | } | ||
| 727 | |||
| 718 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 728 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
| 719 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, | 729 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, |
| 720 | unsigned long addr, pte_t *ptep) | 730 | unsigned long addr, pte_t *ptep) |
diff --git a/include/asm-sh/pgtable_32.h b/include/asm-sh/pgtable_32.h index 3e3557c53c55..cbc731d35c25 100644 --- a/include/asm-sh/pgtable_32.h +++ b/include/asm-sh/pgtable_32.h | |||
| @@ -326,6 +326,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte) | |||
| 326 | #define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY) | 326 | #define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY) |
| 327 | #define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED) | 327 | #define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED) |
| 328 | #define pte_file(pte) ((pte).pte_low & _PAGE_FILE) | 328 | #define pte_file(pte) ((pte).pte_low & _PAGE_FILE) |
| 329 | #define pte_special(pte) (0) | ||
| 329 | 330 | ||
| 330 | #ifdef CONFIG_X2TLB | 331 | #ifdef CONFIG_X2TLB |
| 331 | #define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) | 332 | #define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) |
| @@ -356,6 +357,8 @@ PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY); | |||
| 356 | PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED); | 357 | PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED); |
| 357 | PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); | 358 | PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); |
| 358 | 359 | ||
| 360 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 361 | |||
| 359 | /* | 362 | /* |
| 360 | * Macro and implementation to make a page protection as uncachable. | 363 | * Macro and implementation to make a page protection as uncachable. |
| 361 | */ | 364 | */ |
diff --git a/include/asm-sh/pgtable_64.h b/include/asm-sh/pgtable_64.h index f9dd9d311441..c78990cda557 100644 --- a/include/asm-sh/pgtable_64.h +++ b/include/asm-sh/pgtable_64.h | |||
| @@ -254,10 +254,11 @@ extern void __handle_bad_pmd_kernel(pmd_t * pmd); | |||
| 254 | /* | 254 | /* |
| 255 | * The following have defined behavior only work if pte_present() is true. | 255 | * The following have defined behavior only work if pte_present() is true. |
| 256 | */ | 256 | */ |
| 257 | static inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; } | 257 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 258 | static inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; } | 258 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 259 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 259 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 260 | static inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_WRITE; } | 260 | static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } |
| 261 | static inline int pte_special(pte_t pte){ return 0; } | ||
| 261 | 262 | ||
| 262 | static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; } | 263 | static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; } |
| 263 | static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } | 264 | static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; } |
| @@ -266,6 +267,7 @@ static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | | |||
| 266 | static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } | 267 | static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } |
| 267 | static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } | 268 | static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } |
| 268 | static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } | 269 | static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; } |
| 270 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | ||
| 269 | 271 | ||
| 270 | 272 | ||
| 271 | /* | 273 | /* |
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index 2cc235b74d94..d84af6d95f5c 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h | |||
| @@ -219,6 +219,11 @@ static inline int pte_file(pte_t pte) | |||
| 219 | return pte_val(pte) & BTFIXUP_HALF(pte_filei); | 219 | return pte_val(pte) & BTFIXUP_HALF(pte_filei); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static inline int pte_special(pte_t pte) | ||
| 223 | { | ||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 222 | /* | 227 | /* |
| 223 | */ | 228 | */ |
| 224 | BTFIXUPDEF_HALF(pte_wrprotecti) | 229 | BTFIXUPDEF_HALF(pte_wrprotecti) |
| @@ -251,6 +256,8 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t) | |||
| 251 | #define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte) | 256 | #define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte) |
| 252 | #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte) | 257 | #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte) |
| 253 | 258 | ||
| 259 | #define pte_mkspecial(pte) (pte) | ||
| 260 | |||
| 254 | #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot) | 261 | #define pfn_pte(pfn, prot) mk_pte(pfn_to_page(pfn), prot) |
| 255 | 262 | ||
| 256 | BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t) | 263 | BTFIXUPDEF_CALL(unsigned long, pte_pfn, pte_t) |
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 549e45266b68..0e200e7acec7 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h | |||
| @@ -506,6 +506,11 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 506 | return __pte(pte_val(pte) | mask); | 506 | return __pte(pte_val(pte) | mask); |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 510 | { | ||
| 511 | return pte; | ||
| 512 | } | ||
| 513 | |||
| 509 | static inline unsigned long pte_young(pte_t pte) | 514 | static inline unsigned long pte_young(pte_t pte) |
| 510 | { | 515 | { |
| 511 | unsigned long mask; | 516 | unsigned long mask; |
| @@ -608,6 +613,11 @@ static inline unsigned long pte_present(pte_t pte) | |||
| 608 | return val; | 613 | return val; |
| 609 | } | 614 | } |
| 610 | 615 | ||
| 616 | static inline int pte_special(pte_t pte) | ||
| 617 | { | ||
| 618 | return 0; | ||
| 619 | } | ||
| 620 | |||
| 611 | #define pmd_set(pmdp, ptep) \ | 621 | #define pmd_set(pmdp, ptep) \ |
| 612 | (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) | 622 | (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL)) |
| 613 | #define pud_set(pudp, pmdp) \ | 623 | #define pud_set(pudp, pmdp) \ |
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index 4102b443e925..02db81b7b86e 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
| @@ -173,6 +173,11 @@ static inline int pte_newprot(pte_t pte) | |||
| 173 | return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT))); | 173 | return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT))); |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static inline int pte_special(pte_t pte) | ||
| 177 | { | ||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 176 | /* | 181 | /* |
| 177 | * ================================= | 182 | * ================================= |
| 178 | * Flags setting section. | 183 | * Flags setting section. |
| @@ -241,6 +246,11 @@ static inline pte_t pte_mknewpage(pte_t pte) | |||
| 241 | return(pte); | 246 | return(pte); |
| 242 | } | 247 | } |
| 243 | 248 | ||
| 249 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 250 | { | ||
| 251 | return(pte); | ||
| 252 | } | ||
| 253 | |||
| 244 | static inline void set_pte(pte_t *pteptr, pte_t pteval) | 254 | static inline void set_pte(pte_t *pteptr, pte_t pteval) |
| 245 | { | 255 | { |
| 246 | pte_copy(*pteptr, pteval); | 256 | pte_copy(*pteptr, pteval); |
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h index a496d6335d3b..801b31f71452 100644 --- a/include/asm-x86/pgtable.h +++ b/include/asm-x86/pgtable.h | |||
| @@ -195,6 +195,11 @@ static inline int pte_exec(pte_t pte) | |||
| 195 | return !(pte_val(pte) & _PAGE_NX); | 195 | return !(pte_val(pte) & _PAGE_NX); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | static inline int pte_special(pte_t pte) | ||
| 199 | { | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 198 | static inline int pmd_large(pmd_t pte) | 203 | static inline int pmd_large(pmd_t pte) |
| 199 | { | 204 | { |
| 200 | return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) == | 205 | return (pmd_val(pte) & (_PAGE_PSE | _PAGE_PRESENT)) == |
| @@ -256,6 +261,11 @@ static inline pte_t pte_clrglobal(pte_t pte) | |||
| 256 | return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); | 261 | return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); |
| 257 | } | 262 | } |
| 258 | 263 | ||
| 264 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 265 | { | ||
| 266 | return pte; | ||
| 267 | } | ||
| 268 | |||
| 259 | extern pteval_t __supported_pte_mask; | 269 | extern pteval_t __supported_pte_mask; |
| 260 | 270 | ||
| 261 | static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) | 271 | static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) |
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h index c8b024a48b4d..8014d96b21f1 100644 --- a/include/asm-xtensa/pgtable.h +++ b/include/asm-xtensa/pgtable.h | |||
| @@ -210,6 +210,8 @@ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITABLE; } | |||
| 210 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } | 210 | static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } |
| 211 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } | 211 | static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } |
| 212 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } | 212 | static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } |
| 213 | static inline int pte_special(pte_t pte) { return 0; } | ||
| 214 | |||
| 213 | static inline pte_t pte_wrprotect(pte_t pte) | 215 | static inline pte_t pte_wrprotect(pte_t pte) |
| 214 | { pte_val(pte) &= ~(_PAGE_WRITABLE | _PAGE_HW_WRITE); return pte; } | 216 | { pte_val(pte) &= ~(_PAGE_WRITABLE | _PAGE_HW_WRITE); return pte; } |
| 215 | static inline pte_t pte_mkclean(pte_t pte) | 217 | static inline pte_t pte_mkclean(pte_t pte) |
| @@ -222,6 +224,8 @@ static inline pte_t pte_mkyoung(pte_t pte) | |||
| 222 | { pte_val(pte) |= _PAGE_ACCESSED; return pte; } | 224 | { pte_val(pte) |= _PAGE_ACCESSED; return pte; } |
| 223 | static inline pte_t pte_mkwrite(pte_t pte) | 225 | static inline pte_t pte_mkwrite(pte_t pte) |
| 224 | { pte_val(pte) |= _PAGE_WRITABLE; return pte; } | 226 | { pte_val(pte) |= _PAGE_WRITABLE; return pte; } |
| 227 | static inline pte_t pte_mkspecial(pte_t pte) | ||
| 228 | { return pte; } | ||
| 225 | 229 | ||
| 226 | /* | 230 | /* |
| 227 | * Conversion functions: convert a page and protection to a page entry, | 231 | * Conversion functions: convert a page and protection to a page entry, |
diff --git a/include/linux/mm.h b/include/linux/mm.h index c657ea0bd6aa..ba86ddaa2bb8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -721,7 +721,9 @@ struct zap_details { | |||
| 721 | unsigned long truncate_count; /* Compare vm_truncate_count */ | 721 | unsigned long truncate_count; /* Compare vm_truncate_count */ |
| 722 | }; | 722 | }; |
| 723 | 723 | ||
| 724 | struct page *vm_normal_page(struct vm_area_struct *, unsigned long, pte_t); | 724 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, |
| 725 | pte_t pte); | ||
| 726 | |||
| 725 | unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, | 727 | unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, |
| 726 | unsigned long size, struct zap_details *); | 728 | unsigned long size, struct zap_details *); |
| 727 | unsigned long unmap_vmas(struct mmu_gather **tlb, | 729 | unsigned long unmap_vmas(struct mmu_gather **tlb, |
diff --git a/mm/memory.c b/mm/memory.c index 0da414c383e7..c5e88bcd8ec3 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -371,33 +371,37 @@ static inline int is_cow_mapping(unsigned int flags) | |||
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | /* | 373 | /* |
| 374 | * This function gets the "struct page" associated with a pte or returns | 374 | * vm_normal_page -- This function gets the "struct page" associated with a pte. |
| 375 | * NULL if no "struct page" is associated with the pte. | ||
| 376 | * | 375 | * |
| 377 | * A raw VM_PFNMAP mapping (ie. one that is not COWed) may not have any "struct | 376 | * "Special" mappings do not wish to be associated with a "struct page" (either |
| 378 | * page" backing, and even if they do, they are not refcounted. COWed pages of | 377 | * it doesn't exist, or it exists but they don't want to touch it). In this |
| 379 | * a VM_PFNMAP do always have a struct page, and they are normally refcounted | 378 | * case, NULL is returned here. "Normal" mappings do have a struct page. |
| 380 | * (they are _normal_ pages). | ||
| 381 | * | 379 | * |
| 382 | * So a raw PFNMAP mapping will have each page table entry just pointing | 380 | * There are 2 broad cases. Firstly, an architecture may define a pte_special() |
| 383 | * to a page frame number, and as far as the VM layer is concerned, those do | 381 | * pte bit, in which case this function is trivial. Secondly, an architecture |
| 384 | * not have pages associated with them - even if the PFN might point to memory | 382 | * may not have a spare pte bit, which requires a more complicated scheme, |
| 385 | * that otherwise is perfectly fine and has a "struct page". | 383 | * described below. |
| 384 | * | ||
| 385 | * A raw VM_PFNMAP mapping (ie. one that is not COWed) is always considered a | ||
| 386 | * special mapping (even if there are underlying and valid "struct pages"). | ||
| 387 | * COWed pages of a VM_PFNMAP are always normal. | ||
| 386 | * | 388 | * |
| 387 | * The way we recognize COWed pages within VM_PFNMAP mappings is through the | 389 | * The way we recognize COWed pages within VM_PFNMAP mappings is through the |
| 388 | * rules set up by "remap_pfn_range()": the vma will have the VM_PFNMAP bit | 390 | * rules set up by "remap_pfn_range()": the vma will have the VM_PFNMAP bit |
| 389 | * set, and the vm_pgoff will point to the first PFN mapped: thus every | 391 | * set, and the vm_pgoff will point to the first PFN mapped: thus every special |
| 390 | * page that is a raw mapping will always honor the rule | 392 | * mapping will always honor the rule |
| 391 | * | 393 | * |
| 392 | * pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT) | 394 | * pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT) |
| 393 | * | 395 | * |
| 394 | * A call to vm_normal_page() will return NULL for such a page. | 396 | * And for normal mappings this is false. |
| 397 | * | ||
| 398 | * This restricts such mappings to be a linear translation from virtual address | ||
| 399 | * to pfn. To get around this restriction, we allow arbitrary mappings so long | ||
| 400 | * as the vma is not a COW mapping; in that case, we know that all ptes are | ||
| 401 | * special (because none can have been COWed). | ||
| 395 | * | 402 | * |
| 396 | * If the page doesn't follow the "remap_pfn_range()" rule in a VM_PFNMAP | ||
| 397 | * then the page has been COW'ed. A COW'ed page _does_ have a "struct page" | ||
| 398 | * associated with it even if it is in a VM_PFNMAP range. Calling | ||
| 399 | * vm_normal_page() on such a page will therefore return the "struct page". | ||
| 400 | * | 403 | * |
| 404 | * In order to support COW of arbitrary special mappings, we have VM_MIXEDMAP. | ||
| 401 | * | 405 | * |
| 402 | * VM_MIXEDMAP mappings can likewise contain memory with or without "struct | 406 | * VM_MIXEDMAP mappings can likewise contain memory with or without "struct |
| 403 | * page" backing, however the difference is that _all_ pages with a struct | 407 | * page" backing, however the difference is that _all_ pages with a struct |
| @@ -407,16 +411,29 @@ static inline int is_cow_mapping(unsigned int flags) | |||
| 407 | * advantage is that we don't have to follow the strict linearity rule of | 411 | * advantage is that we don't have to follow the strict linearity rule of |
| 408 | * PFNMAP mappings in order to support COWable mappings. | 412 | * PFNMAP mappings in order to support COWable mappings. |
| 409 | * | 413 | * |
| 410 | * A call to vm_normal_page() with a VM_MIXEDMAP mapping will return the | ||
| 411 | * associated "struct page" or NULL for memory not backed by a "struct page". | ||
| 412 | * | ||
| 413 | * | ||
| 414 | * All other mappings should have a valid struct page, which will be | ||
| 415 | * returned by a call to vm_normal_page(). | ||
| 416 | */ | 414 | */ |
| 417 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte) | 415 | #ifdef __HAVE_ARCH_PTE_SPECIAL |
| 416 | # define HAVE_PTE_SPECIAL 1 | ||
| 417 | #else | ||
| 418 | # define HAVE_PTE_SPECIAL 0 | ||
| 419 | #endif | ||
| 420 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, | ||
| 421 | pte_t pte) | ||
| 418 | { | 422 | { |
| 419 | unsigned long pfn = pte_pfn(pte); | 423 | unsigned long pfn; |
| 424 | |||
| 425 | if (HAVE_PTE_SPECIAL) { | ||
| 426 | if (likely(!pte_special(pte))) { | ||
| 427 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); | ||
| 428 | return pte_page(pte); | ||
| 429 | } | ||
| 430 | VM_BUG_ON(!(vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))); | ||
| 431 | return NULL; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* !HAVE_PTE_SPECIAL case follows: */ | ||
| 435 | |||
| 436 | pfn = pte_pfn(pte); | ||
| 420 | 437 | ||
| 421 | if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { | 438 | if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) { |
| 422 | if (vma->vm_flags & VM_MIXEDMAP) { | 439 | if (vma->vm_flags & VM_MIXEDMAP) { |
| @@ -424,7 +441,8 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ | |||
| 424 | return NULL; | 441 | return NULL; |
| 425 | goto out; | 442 | goto out; |
| 426 | } else { | 443 | } else { |
| 427 | unsigned long off = (addr-vma->vm_start) >> PAGE_SHIFT; | 444 | unsigned long off; |
| 445 | off = (addr - vma->vm_start) >> PAGE_SHIFT; | ||
| 428 | if (pfn == vma->vm_pgoff + off) | 446 | if (pfn == vma->vm_pgoff + off) |
| 429 | return NULL; | 447 | return NULL; |
| 430 | if (!is_cow_mapping(vma->vm_flags)) | 448 | if (!is_cow_mapping(vma->vm_flags)) |
| @@ -432,25 +450,12 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ | |||
| 432 | } | 450 | } |
| 433 | } | 451 | } |
| 434 | 452 | ||
| 435 | #ifdef CONFIG_DEBUG_VM | 453 | VM_BUG_ON(!pfn_valid(pfn)); |
| 436 | /* | ||
| 437 | * Add some anal sanity checks for now. Eventually, | ||
| 438 | * we should just do "return pfn_to_page(pfn)", but | ||
| 439 | * in the meantime we check that we get a valid pfn, | ||
| 440 | * and that the resulting page looks ok. | ||
| 441 | */ | ||
| 442 | if (unlikely(!pfn_valid(pfn))) { | ||
| 443 | print_bad_pte(vma, pte, addr); | ||
| 444 | return NULL; | ||
| 445 | } | ||
| 446 | #endif | ||
| 447 | 454 | ||
| 448 | /* | 455 | /* |
| 449 | * NOTE! We still have PageReserved() pages in the page | 456 | * NOTE! We still have PageReserved() pages in the page tables. |
| 450 | * tables. | ||
| 451 | * | 457 | * |
| 452 | * The PAGE_ZERO() pages and various VDSO mappings can | 458 | * eg. VDSO mappings can cause them to exist. |
| 453 | * cause them to exist. | ||
| 454 | */ | 459 | */ |
| 455 | out: | 460 | out: |
| 456 | return pfn_to_page(pfn); | 461 | return pfn_to_page(pfn); |
| @@ -1263,6 +1268,12 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, | |||
| 1263 | pte_t *pte, entry; | 1268 | pte_t *pte, entry; |
| 1264 | spinlock_t *ptl; | 1269 | spinlock_t *ptl; |
| 1265 | 1270 | ||
| 1271 | /* | ||
| 1272 | * Technically, architectures with pte_special can avoid all these | ||
| 1273 | * restrictions (same for remap_pfn_range). However we would like | ||
| 1274 | * consistency in testing and feature parity among all, so we should | ||
| 1275 | * try to keep these invariants in place for everybody. | ||
| 1276 | */ | ||
| 1266 | BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))); | 1277 | BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))); |
| 1267 | BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) == | 1278 | BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) == |
| 1268 | (VM_PFNMAP|VM_MIXEDMAP)); | 1279 | (VM_PFNMAP|VM_MIXEDMAP)); |
| @@ -1278,7 +1289,7 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, | |||
| 1278 | goto out_unlock; | 1289 | goto out_unlock; |
| 1279 | 1290 | ||
| 1280 | /* Ok, finally just insert the thing.. */ | 1291 | /* Ok, finally just insert the thing.. */ |
| 1281 | entry = pfn_pte(pfn, vma->vm_page_prot); | 1292 | entry = pte_mkspecial(pfn_pte(pfn, vma->vm_page_prot)); |
| 1282 | set_pte_at(mm, addr, pte, entry); | 1293 | set_pte_at(mm, addr, pte, entry); |
| 1283 | update_mmu_cache(vma, addr, entry); | 1294 | update_mmu_cache(vma, addr, entry); |
| 1284 | 1295 | ||
| @@ -1309,7 +1320,7 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd, | |||
| 1309 | arch_enter_lazy_mmu_mode(); | 1320 | arch_enter_lazy_mmu_mode(); |
| 1310 | do { | 1321 | do { |
| 1311 | BUG_ON(!pte_none(*pte)); | 1322 | BUG_ON(!pte_none(*pte)); |
| 1312 | set_pte_at(mm, addr, pte, pfn_pte(pfn, prot)); | 1323 | set_pte_at(mm, addr, pte, pte_mkspecial(pfn_pte(pfn, prot))); |
| 1313 | pfn++; | 1324 | pfn++; |
| 1314 | } while (pte++, addr += PAGE_SIZE, addr != end); | 1325 | } while (pte++, addr += PAGE_SIZE, addr != end); |
| 1315 | arch_leave_lazy_mmu_mode(); | 1326 | arch_leave_lazy_mmu_mode(); |
