diff options
author | Yuri Tikhonov <yur@emcraft.com> | 2008-02-02 02:47:31 -0500 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2008-03-07 17:56:54 -0500 |
commit | 1757f2d12dce775982aaa006bce1cf4f7ce90111 (patch) | |
tree | 068d45767a864ad383ece702fbcbcf3cd2e2752e | |
parent | 3e0d65bf6d5b464949b749a8da7977f6b197d301 (diff) |
[PPC] 8xx: swap bug-fix
This makes swap routines operate correctly on the ppc_8xx based machines.
Recent kernel's size makes swap feature very important on low-memory platfor
those are actually non-operable without it.
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r-- | arch/ppc/kernel/head_8xx.S | 30 | ||||
-rw-r--r-- | include/asm-ppc/pgtable.h | 8 |
2 files changed, 29 insertions, 9 deletions
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index eb8d26f87362..321bda2de2cb 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S | |||
@@ -329,8 +329,18 @@ InstructionTLBMiss: | |||
329 | mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ | 329 | mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ |
330 | lwz r10, 0(r11) /* Get the pte */ | 330 | lwz r10, 0(r11) /* Get the pte */ |
331 | 331 | ||
332 | #ifdef CONFIG_SWAP | ||
333 | /* do not set the _PAGE_ACCESSED bit of a non-present page */ | ||
334 | andi. r11, r10, _PAGE_PRESENT | ||
335 | beq 4f | ||
336 | ori r10, r10, _PAGE_ACCESSED | ||
337 | mfspr r11, SPRN_MD_TWC /* get the pte address again */ | ||
338 | stw r10, 0(r11) | ||
339 | 4: | ||
340 | #else | ||
332 | ori r10, r10, _PAGE_ACCESSED | 341 | ori r10, r10, _PAGE_ACCESSED |
333 | stw r10, 0(r11) | 342 | stw r10, 0(r11) |
343 | #endif | ||
334 | 344 | ||
335 | /* The Linux PTE won't go exactly into the MMU TLB. | 345 | /* The Linux PTE won't go exactly into the MMU TLB. |
336 | * Software indicator bits 21, 22 and 28 must be clear. | 346 | * Software indicator bits 21, 22 and 28 must be clear. |
@@ -395,8 +405,17 @@ DataStoreTLBMiss: | |||
395 | DO_8xx_CPU6(0x3b80, r3) | 405 | DO_8xx_CPU6(0x3b80, r3) |
396 | mtspr SPRN_MD_TWC, r11 | 406 | mtspr SPRN_MD_TWC, r11 |
397 | 407 | ||
398 | mfspr r11, SPRN_MD_TWC /* get the pte address again */ | 408 | #ifdef CONFIG_SWAP |
409 | /* do not set the _PAGE_ACCESSED bit of a non-present page */ | ||
410 | andi. r11, r10, _PAGE_PRESENT | ||
411 | beq 4f | ||
412 | ori r10, r10, _PAGE_ACCESSED | ||
413 | 4: | ||
414 | /* and update pte in table */ | ||
415 | #else | ||
399 | ori r10, r10, _PAGE_ACCESSED | 416 | ori r10, r10, _PAGE_ACCESSED |
417 | #endif | ||
418 | mfspr r11, SPRN_MD_TWC /* get the pte address again */ | ||
400 | stw r10, 0(r11) | 419 | stw r10, 0(r11) |
401 | 420 | ||
402 | /* The Linux PTE won't go exactly into the MMU TLB. | 421 | /* The Linux PTE won't go exactly into the MMU TLB. |
@@ -575,7 +594,16 @@ DataTLBError: | |||
575 | 594 | ||
576 | /* Update 'changed', among others. | 595 | /* Update 'changed', among others. |
577 | */ | 596 | */ |
597 | #ifdef CONFIG_SWAP | ||
598 | ori r10, r10, _PAGE_DIRTY|_PAGE_HWWRITE | ||
599 | /* do not set the _PAGE_ACCESSED bit of a non-present page */ | ||
600 | andi. r11, r10, _PAGE_PRESENT | ||
601 | beq 4f | ||
602 | ori r10, r10, _PAGE_ACCESSED | ||
603 | 4: | ||
604 | #else | ||
578 | ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE | 605 | ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE |
606 | #endif | ||
579 | mfspr r11, SPRN_MD_TWC /* Get pte address again */ | 607 | mfspr r11, SPRN_MD_TWC /* Get pte address again */ |
580 | stw r10, 0(r11) /* and update pte in table */ | 608 | stw r10, 0(r11) /* and update pte in table */ |
581 | 609 | ||
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 69347bdbb401..70435d32129a 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h | |||
@@ -299,14 +299,6 @@ extern unsigned long ioremap_bot, ioremap_base; | |||
299 | #define _PMD_PAGE_MASK 0x000c | 299 | #define _PMD_PAGE_MASK 0x000c |
300 | #define _PMD_PAGE_8M 0x000c | 300 | #define _PMD_PAGE_8M 0x000c |
301 | 301 | ||
302 | /* | ||
303 | * The 8xx TLB miss handler allegedly sets _PAGE_ACCESSED in the PTE | ||
304 | * for an address even if _PAGE_PRESENT is not set, as a performance | ||
305 | * optimization. This is a bug if you ever want to use swap unless | ||
306 | * _PAGE_ACCESSED is 2, which it isn't, or unless you have 8xx-specific | ||
307 | * definitions for __swp_entry etc. below, which would be gross. | ||
308 | * -- paulus | ||
309 | */ | ||
310 | #define _PTE_NONE_MASK _PAGE_ACCESSED | 302 | #define _PTE_NONE_MASK _PAGE_ACCESSED |
311 | 303 | ||
312 | #else /* CONFIG_6xx */ | 304 | #else /* CONFIG_6xx */ |