From: Akinobu Mita <akinobu.mita@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: linux-arch@vger.kernel.org, linux-mm@kvack.org,
akpm@linux-foundation.org
Subject: [PATCH] generic debug pagealloc
Date: Wed, 4 Mar 2009 01:01:04 +0900 [thread overview]
Message-ID: <20090303160103.GB5812@localhost.localdomain> (raw)
CONFIG_DEBUG_PAGEALLOC is now supported by x86, powerpc, sparc (64bit),
and s390. This patch implements it for the rest of the architectures
by filling the pages with poison byte patterns after free_pages() and
verifying the poison patterns before alloc_pages().
This generic one cannot detect invalid read accesses and it can only
detect invalid write accesses after a long delay. But it is an feasible way
for nommu architectures.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: linux-arch@vger.kernel.org
Cc: linux-mm@kvack.org
---
arch/avr32/mm/fault.c | 18 ----------
arch/powerpc/Kconfig | 3 +
arch/powerpc/Kconfig.debug | 1
arch/s390/Kconfig | 3 +
arch/s390/Kconfig.debug | 1
arch/sparc/Kconfig | 3 +
arch/sparc/Kconfig.debug | 3 +
arch/x86/Kconfig | 3 +
arch/x86/Kconfig.debug | 1
include/linux/mm_types.h | 4 ++
include/linux/poison.h | 3 +
lib/Kconfig.debug | 1
mm/Kconfig.debug | 8 ++++
mm/Makefile | 1
mm/debug-pagealloc.c | 81 +++++++++++++++++++++++++++++++++++++++++++++
15 files changed, 115 insertions(+), 19 deletions(-)
Index: 2.6-poison/include/linux/poison.h
===================================================================
--- 2.6-poison.orig/include/linux/poison.h
+++ 2.6-poison/include/linux/poison.h
@@ -17,6 +17,9 @@
*/
#define TIMER_ENTRY_STATIC ((void *) 0x74737461)
+/********** mm/debug-pagealloc.c **********/
+#define PAGE_POISON 0xaa
+
/********** mm/slab.c **********/
/*
* Magic nums for obj red zoning.
Index: 2.6-poison/mm/debug-pagealloc.c
===================================================================
--- /dev/null
+++ 2.6-poison/mm/debug-pagealloc.c
@@ -0,0 +1,81 @@
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+
+static void poison_page(struct page *page)
+{
+ void *addr;
+
+ page->poison = true;
+ addr = kmap_atomic(page, KM_USER0);
+ memset(addr, PAGE_POISON, PAGE_SIZE);
+ kunmap_atomic(addr, KM_USER0);
+}
+
+static void poison_pages(struct page *page, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ poison_page(page + i);
+}
+
+static void dump_broken_mem(unsigned char *mem)
+{
+ int i;
+ int start = 0;
+ int end = PAGE_SIZE - 1;
+
+ for (i = 0; i < PAGE_SIZE; i++) {
+ if (mem[i] != PAGE_POISON) {
+ start = i;
+ break;
+ }
+ }
+ for (i = PAGE_SIZE - 1; i >= start; i--) {
+ if (mem[i] != PAGE_POISON) {
+ end = i;
+ break;
+ }
+ }
+ printk(KERN_ERR "Page corruption: %p-%p\n", mem + start, mem + end);
+ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, mem + start,
+ end - start + 1, 1);
+}
+
+static void unpoison_page(struct page *page)
+{
+ unsigned char *mem;
+ int i;
+
+ if (!page->poison)
+ return;
+
+ mem = kmap_atomic(page, KM_USER0);
+ for (i = 0; i < PAGE_SIZE; i++) {
+ if (mem[i] != PAGE_POISON) {
+ dump_broken_mem(mem);
+ break;
+ }
+ }
+ kunmap_atomic(mem, KM_USER0);
+ page->poison = false;
+}
+
+static void unpoison_pages(struct page *page, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ unpoison_page(page + i);
+}
+
+void kernel_map_pages(struct page *page, int numpages, int enable)
+{
+ if (!debug_pagealloc_enabled)
+ return;
+
+ if (enable)
+ unpoison_pages(page, numpages);
+ else
+ poison_pages(page, numpages);
+}
Index: 2.6-poison/mm/Kconfig.debug
===================================================================
--- /dev/null
+++ 2.6-poison/mm/Kconfig.debug
@@ -0,0 +1,8 @@
+config PAGE_POISONING
+ bool "Debug page memory allocations"
+ depends on !ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ select DEBUG_PAGEALLOC
+ help
+ Fill the pages with poison patterns after free_pages() and verify
+ the patterns before alloc_pages(). This results in a large slowdown,
+ but helps to find certain types of memory corruptions.
Index: 2.6-poison/mm/Makefile
===================================================================
--- 2.6-poison.orig/mm/Makefile
+++ 2.6-poison/mm/Makefile
@@ -33,3 +33,4 @@ obj-$(CONFIG_MIGRATION) += migrate.o
obj-$(CONFIG_SMP) += allocpercpu.o
obj-$(CONFIG_QUICKLIST) += quicklist.o
obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
+obj-$(CONFIG_PAGE_POISONING) += debug-pagealloc.o
Index: 2.6-poison/lib/Kconfig.debug
===================================================================
--- 2.6-poison.orig/lib/Kconfig.debug
+++ 2.6-poison/lib/Kconfig.debug
@@ -796,6 +796,7 @@ config SYSCTL_SYSCALL_CHECK
to properly maintain and use. This enables checks that help
you to keep things correct.
+source mm/Kconfig.debug
source kernel/trace/Kconfig
config PROVIDE_OHCI1394_DMA_INIT
Index: 2.6-poison/arch/powerpc/Kconfig.debug
===================================================================
--- 2.6-poison.orig/arch/powerpc/Kconfig.debug
+++ 2.6-poison/arch/powerpc/Kconfig.debug
@@ -30,6 +30,7 @@ config DEBUG_STACK_USAGE
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
depends on DEBUG_KERNEL && !HIBERNATION
+ depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
Index: 2.6-poison/arch/s390/Kconfig.debug
===================================================================
--- 2.6-poison.orig/arch/s390/Kconfig.debug
+++ 2.6-poison/arch/s390/Kconfig.debug
@@ -9,6 +9,7 @@ source "lib/Kconfig.debug"
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
depends on DEBUG_KERNEL
+ depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a slowdown, but helps to find certain types of
Index: 2.6-poison/arch/sparc/Kconfig.debug
===================================================================
--- 2.6-poison.orig/arch/sparc/Kconfig.debug
+++ 2.6-poison/arch/sparc/Kconfig.debug
@@ -24,7 +24,8 @@ config STACK_DEBUG
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
- depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION
+ depends on DEBUG_KERNEL && !HIBERNATION
+ depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
Index: 2.6-poison/arch/x86/Kconfig
===================================================================
--- 2.6-poison.orig/arch/x86/Kconfig
+++ 2.6-poison/arch/x86/Kconfig
@@ -160,6 +160,9 @@ config AUDIT_ARCH
config ARCH_SUPPORTS_OPTIMIZED_INLINING
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
# Use the generic interrupt handling code in kernel/irq/:
config GENERIC_HARDIRQS
bool
Index: 2.6-poison/arch/x86/Kconfig.debug
===================================================================
--- 2.6-poison.orig/arch/x86/Kconfig.debug
+++ 2.6-poison/arch/x86/Kconfig.debug
@@ -75,6 +75,7 @@ config DEBUG_STACK_USAGE
config DEBUG_PAGEALLOC
bool "Debug page memory allocations"
depends on DEBUG_KERNEL
+ depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
Index: 2.6-poison/arch/powerpc/Kconfig
===================================================================
--- 2.6-poison.orig/arch/powerpc/Kconfig
+++ 2.6-poison/arch/powerpc/Kconfig
@@ -227,6 +227,9 @@ config PPC_OF_PLATFORM_PCI
depends on PPC64 # not supported on 32 bits yet
default n
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
Index: 2.6-poison/arch/sparc/Kconfig
===================================================================
--- 2.6-poison.orig/arch/sparc/Kconfig
+++ 2.6-poison/arch/sparc/Kconfig
@@ -124,6 +124,9 @@ config ARCH_NO_VIRT_TO_BUS
config OF
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y if SPARC64
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
Index: 2.6-poison/arch/avr32/mm/fault.c
===================================================================
--- 2.6-poison.orig/arch/avr32/mm/fault.c
+++ 2.6-poison/arch/avr32/mm/fault.c
@@ -250,21 +250,3 @@ asmlinkage void do_bus_error(unsigned lo
dump_dtlb();
die("Bus Error", regs, SIGKILL);
}
-
-/*
- * This functionality is currently not possible to implement because
- * we're using segmentation to ensure a fixed mapping of the kernel
- * virtual address space.
- *
- * It would be possible to implement this, but it would require us to
- * disable segmentation at startup and load the kernel mappings into
- * the TLB like any other pages. There will be lots of trickery to
- * avoid recursive invocation of the TLB miss handler, though...
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-void kernel_map_pages(struct page *page, int numpages, int enable)
-{
-
-}
-EXPORT_SYMBOL(kernel_map_pages);
-#endif
Index: 2.6-poison/arch/s390/Kconfig
===================================================================
--- 2.6-poison.orig/arch/s390/Kconfig
+++ 2.6-poison/arch/s390/Kconfig
@@ -72,6 +72,9 @@ config PGSTE
config VIRT_CPU_ACCOUNTING
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
mainmenu "Linux Kernel Configuration"
config S390
Index: 2.6-poison/include/linux/mm_types.h
===================================================================
--- 2.6-poison.orig/include/linux/mm_types.h
+++ 2.6-poison/include/linux/mm_types.h
@@ -94,6 +94,10 @@ struct page {
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
+
+#ifdef CONFIG_PAGE_POISONING
+ bool poison;
+#endif /* CONFIG_PAGE_POISONING */
};
/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next reply other threads:[~2009-03-03 16:01 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-03 16:01 Akinobu Mita [this message]
2009-03-03 16:05 ` Ingo Molnar
2009-03-04 14:12 ` Akinobu Mita
2009-03-03 16:12 ` Jiri Slaby
2009-03-04 14:13 ` Akinobu Mita
2009-03-03 21:36 ` Andrew Morton
2009-03-03 22:07 ` Russell King
2009-03-04 14:17 ` Akinobu Mita
2009-03-06 9:14 ` Benjamin Herrenschmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090303160103.GB5812@localhost.localdomain \
--to=akinobu.mita@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox