diff options
Diffstat (limited to 'include/asm-i386/pgtable.h')
-rw-r--r-- | include/asm-i386/pgtable.h | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index c3b58d473a55..c6b8b944120c 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h | |||
@@ -159,6 +159,7 @@ void paging_init(void); | |||
159 | 159 | ||
160 | extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; | 160 | extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; |
161 | #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) | 161 | #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) |
162 | #define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) | ||
162 | #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) | 163 | #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) |
163 | #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) | 164 | #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) |
164 | #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) | 165 | #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) |
@@ -166,6 +167,7 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; | |||
166 | #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) | 167 | #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) |
167 | #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) | 168 | #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) |
168 | #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) | 169 | #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) |
170 | #define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) | ||
169 | #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) | 171 | #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) |
170 | #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) | 172 | #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) |
171 | #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) | 173 | #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) |
@@ -241,6 +243,8 @@ static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; re | |||
241 | static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } | 243 | static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } |
242 | static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } | 244 | static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } |
243 | 245 | ||
246 | extern void vmalloc_sync_all(void); | ||
247 | |||
244 | #ifdef CONFIG_X86_PAE | 248 | #ifdef CONFIG_X86_PAE |
245 | # include <asm/pgtable-3level.h> | 249 | # include <asm/pgtable-3level.h> |
246 | #else | 250 | #else |
@@ -263,9 +267,18 @@ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return p | |||
263 | */ | 267 | */ |
264 | #define pte_update(mm, addr, ptep) do { } while (0) | 268 | #define pte_update(mm, addr, ptep) do { } while (0) |
265 | #define pte_update_defer(mm, addr, ptep) do { } while (0) | 269 | #define pte_update_defer(mm, addr, ptep) do { } while (0) |
266 | #define paravirt_map_pt_hook(slot, va, pfn) do { } while (0) | ||
267 | #endif | 270 | #endif |
268 | 271 | ||
272 | /* local pte updates need not use xchg for locking */ | ||
273 | static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) | ||
274 | { | ||
275 | pte_t res = *ptep; | ||
276 | |||
277 | /* Pure native function needs no input for mm, addr */ | ||
278 | native_pte_clear(NULL, 0, ptep); | ||
279 | return res; | ||
280 | } | ||
281 | |||
269 | /* | 282 | /* |
270 | * We only update the dirty/accessed state if we set | 283 | * We only update the dirty/accessed state if we set |
271 | * the dirty bit by hand in the kernel, since the hardware | 284 | * the dirty bit by hand in the kernel, since the hardware |
@@ -330,7 +343,7 @@ do { \ | |||
330 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | 343 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR |
331 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 344 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
332 | { | 345 | { |
333 | pte_t pte = raw_ptep_get_and_clear(ptep); | 346 | pte_t pte = native_ptep_get_and_clear(ptep); |
334 | pte_update(mm, addr, ptep); | 347 | pte_update(mm, addr, ptep); |
335 | return pte; | 348 | return pte; |
336 | } | 349 | } |
@@ -340,8 +353,11 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long | |||
340 | { | 353 | { |
341 | pte_t pte; | 354 | pte_t pte; |
342 | if (full) { | 355 | if (full) { |
343 | pte = *ptep; | 356 | /* |
344 | pte_clear(mm, addr, ptep); | 357 | * Full address destruction in progress; paravirt does not |
358 | * care about updates and native needs no locking | ||
359 | */ | ||
360 | pte = native_local_ptep_get_and_clear(ptep); | ||
345 | } else { | 361 | } else { |
346 | pte = ptep_get_and_clear(mm, addr, ptep); | 362 | pte = ptep_get_and_clear(mm, addr, ptep); |
347 | } | 363 | } |
@@ -470,24 +486,10 @@ extern pte_t *lookup_address(unsigned long address); | |||
470 | #endif | 486 | #endif |
471 | 487 | ||
472 | #if defined(CONFIG_HIGHPTE) | 488 | #if defined(CONFIG_HIGHPTE) |
473 | #define pte_offset_map(dir, address) \ | 489 | #define pte_offset_map(dir, address) \ |
474 | ({ \ | 490 | ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) |
475 | pte_t *__ptep; \ | 491 | #define pte_offset_map_nested(dir, address) \ |
476 | unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ | 492 | ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE1) + pte_index(address)) |
477 | __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE0);\ | ||
478 | paravirt_map_pt_hook(KM_PTE0,__ptep, pfn); \ | ||
479 | __ptep = __ptep + pte_index(address); \ | ||
480 | __ptep; \ | ||
481 | }) | ||
482 | #define pte_offset_map_nested(dir, address) \ | ||
483 | ({ \ | ||
484 | pte_t *__ptep; \ | ||
485 | unsigned pfn = pmd_val(*(dir)) >> PAGE_SHIFT; \ | ||
486 | __ptep = (pte_t *)kmap_atomic(pfn_to_page(pfn),KM_PTE1);\ | ||
487 | paravirt_map_pt_hook(KM_PTE1,__ptep, pfn); \ | ||
488 | __ptep = __ptep + pte_index(address); \ | ||
489 | __ptep; \ | ||
490 | }) | ||
491 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) | 493 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) |
492 | #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) | 494 | #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) |
493 | #else | 495 | #else |
@@ -510,6 +512,22 @@ do { \ | |||
510 | * tables contain all the necessary information. | 512 | * tables contain all the necessary information. |
511 | */ | 513 | */ |
512 | #define update_mmu_cache(vma,address,pte) do { } while (0) | 514 | #define update_mmu_cache(vma,address,pte) do { } while (0) |
515 | |||
516 | void native_pagetable_setup_start(pgd_t *base); | ||
517 | void native_pagetable_setup_done(pgd_t *base); | ||
518 | |||
519 | #ifndef CONFIG_PARAVIRT | ||
520 | static inline void paravirt_pagetable_setup_start(pgd_t *base) | ||
521 | { | ||
522 | native_pagetable_setup_start(base); | ||
523 | } | ||
524 | |||
525 | static inline void paravirt_pagetable_setup_done(pgd_t *base) | ||
526 | { | ||
527 | native_pagetable_setup_done(base); | ||
528 | } | ||
529 | #endif /* !CONFIG_PARAVIRT */ | ||
530 | |||
513 | #endif /* !__ASSEMBLY__ */ | 531 | #endif /* !__ASSEMBLY__ */ |
514 | 532 | ||
515 | #ifdef CONFIG_FLATMEM | 533 | #ifdef CONFIG_FLATMEM |