aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/asm-powerpc/cacheflush.h6
5 files changed, 74 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
diff --git a/include/asm-powerpc/cacheflush.h b/include/asm-powerpc/cacheflush.h
index 08e93e789219..ba667a383b8c 100644
--- a/include/asm-powerpc/cacheflush.h
+++ b/include/asm-powerpc/cacheflush.h
@@ -64,6 +64,12 @@ extern void flush_dcache_phys_range(unsigned long start, unsigned long stop);
64 memcpy(dst, src, len) 64 memcpy(dst, src, len)
65 65
66 66
67
68#ifdef CONFIG_DEBUG_PAGEALLOC
69/* internal debugging function */
70void kernel_map_pages(struct page *page, int numpages, int enable);
71#endif
72
67#endif /* __KERNEL__ */ 73#endif /* __KERNEL__ */
68 74
69#endif /* _ASM_POWERPC_CACHEFLUSH_H */ 75#endif /* _ASM_POWERPC_CACHEFLUSH_H */