diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-02-05 16:50:37 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-05 16:50:54 +0100 |
commit | 2485579bf5d3ea30d39b251defa1620ad77168bd (patch) | |
tree | ef07e9e793f7f73d69b21c539ad96d5346787182 /arch | |
parent | 01bc8ad165490458a8feb744c8f401c1a7098e3a (diff) |
[S390] DEBUG_PAGEALLOC support for s390.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/Kconfig.debug | 8 | ||||
-rw-r--r-- | arch/s390/kernel/traps.c | 5 | ||||
-rw-r--r-- | arch/s390/mm/init.c | 27 |
3 files changed, 39 insertions, 1 deletions
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug index 2283933a9a9..4599fa06bd8 100644 --- a/arch/s390/Kconfig.debug +++ b/arch/s390/Kconfig.debug @@ -6,4 +6,12 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on DEBUG_KERNEL + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a slowdown, but helps to find certain types of + memory corruptions. + endmenu diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 52b8342c6bf..1a2fdb6991d 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -271,7 +271,10 @@ void die(const char * str, struct pt_regs * regs, long err) printk("PREEMPT "); #endif #ifdef CONFIG_SMP - printk("SMP"); + printk("SMP "); +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); #endif printk("\n"); notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index b234bb4a6da..983ec6ec0e7 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -167,6 +167,33 @@ void __init mem_init(void) PFN_ALIGN((unsigned long)&_eshared) - 1); } +#ifdef CONFIG_DEBUG_PAGEALLOC +void kernel_map_pages(struct page *page, int numpages, int enable) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + unsigned long address; + int i; + + for (i = 0; i < numpages; i++) { + address = page_to_phys(page + i); + pgd = pgd_offset_k(address); + pud = pud_offset(pgd, address); + pmd = pmd_offset(pud, address); + pte = pte_offset_kernel(pmd, address); + if (!enable) { + ptep_invalidate(address, pte); + continue; + } + *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); + /* Flush cpu write queue. */ + mb(); + } +} +#endif + void free_initmem(void) { unsigned long addr; |