aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-04-12 01:30:22 -0400
committerPaul Mackerras <paulus@samba.org>2007-04-12 14:09:39 -0400
commit88df6e90fa9782dbf44d936e44649afe271e4790 (patch)
treed0f4c46731e35e96a381dd3e3138f0276741ca57 /arch/powerpc
parentee4f2ea48674b6c9d91bc854edc51a3e6a7168c4 (diff)
[POWERPC] DEBUG_PAGEALLOC for 32-bit
Here's an implementation of DEBUG_PAGEALLOC for ppc32. It disables BAT mapping and is only tested with Hash table based processor though it shouldn't be too hard to adapt it to others. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> arch/powerpc/Kconfig.debug | 9 ++++++ arch/powerpc/mm/init_32.c | 4 +++ arch/powerpc/mm/pgtable_32.c | 52 +++++++++++++++++++++++++++++++++++++++ arch/powerpc/mm/ppc_mmu_32.c | 4 ++- include/asm-powerpc/cacheflush.h | 6 ++++ 5 files changed, 74 insertions(+), 1 deletion(-) Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig.debug9
-rw-r--r--arch/powerpc/mm/init_32.c4
-rw-r--r--arch/powerpc/mm/pgtable_32.c52
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c4
4 files changed, 68 insertions, 1 deletions
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 50f48f0c5630..0f8bb86995b4 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -18,6 +18,15 @@ config DEBUG_STACK_USAGE
18 18
19 This option will slow down process creation somewhat. 19 This option will slow down process creation somewhat.
20 20
21config DEBUG_PAGEALLOC
22 bool "Debug page memory allocations"
23 depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND && PPC32
24 help
25 Unmap pages from the kernel linear mapping after free_pages().
26 This results in a large slowdown, but helps to find certain types
27 of memory corruptions.
28
29
21config HCALL_STATS 30config HCALL_STATS
22 bool "Hypervisor call instrumentation" 31 bool "Hypervisor call instrumentation"
23 depends on PPC_PSERIES && DEBUG_FS 32 depends on PPC_PSERIES && DEBUG_FS
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 0e53ca8f02fb..5fce6ccecb8d 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -115,6 +115,10 @@ void MMU_setup(void)
115 if (strstr(cmd_line, "noltlbs")) { 115 if (strstr(cmd_line, "noltlbs")) {
116 __map_without_ltlbs = 1; 116 __map_without_ltlbs = 1;
117 } 117 }
118#ifdef CONFIG_DEBUG_PAGEALLOC
119 __map_without_bats = 1;
120 __map_without_ltlbs = 1;
121#endif
118} 122}
119 123
120/* 124/*
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index f75f2fc7bc7e..8a2fc16ee0a7 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -451,3 +451,55 @@ exit:
451 return ret; 451 return ret;
452} 452}
453 453
454#ifdef CONFIG_DEBUG_PAGEALLOC
455
456static int __change_page_attr(struct page *page, pgprot_t prot)
457{
458 pte_t *kpte;
459 pmd_t *kpmd;
460 unsigned long address;
461
462 BUG_ON(PageHighMem(page));
463 address = (unsigned long)page_address(page);
464
465 if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address))
466 return 0;
467 if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
468 return -EINVAL;
469 set_pte_at(&init_mm, address, kpte, mk_pte(page, prot));
470 wmb();
471 flush_HPTE(0, address, pmd_val(*kpmd));
472 pte_unmap(kpte);
473
474 return 0;
475}
476
477/*
478 * Change the page attributes of an page in the linear mapping.
479 *
480 * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY
481 */
482static int change_page_attr(struct page *page, int numpages, pgprot_t prot)
483{
484 int i, err = 0;
485 unsigned long flags;
486
487 local_irq_save(flags);
488 for (i = 0; i < numpages; i++, page++) {
489 err = __change_page_attr(page, prot);
490 if (err)
491 break;
492 }
493 local_irq_restore(flags);
494 return err;
495}
496
497
498void kernel_map_pages(struct page *page, int numpages, int enable)
499{
500 if (PageHighMem(page))
501 return;
502
503 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
504}
505#endif /* CONFIG_DEBUG_PAGEALLOC */
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index 7cceb2c44cb9..05066674a7a0 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -85,8 +85,10 @@ unsigned long __init mmu_mapin_ram(void)
85 unsigned long max_size = (256<<20); 85 unsigned long max_size = (256<<20);
86 unsigned long align; 86 unsigned long align;
87 87
88 if (__map_without_bats) 88 if (__map_without_bats) {
89 printk(KERN_DEBUG "RAM mapped without BATs\n");
89 return 0; 90 return 0;
91 }
90 92
91 /* Set up BAT2 and if necessary BAT3 to cover RAM. */ 93 /* Set up BAT2 and if necessary BAT3 to cover RAM. */
92 94