diff options
| author | Andi Kleen <andi@firstfloor.org> | 2009-09-16 05:50:17 -0400 |
|---|---|---|
| committer | Andi Kleen <ak@linux.intel.com> | 2009-09-16 05:50:17 -0400 |
| commit | cae681fc12a824631337906d6ba1dbd498e751a5 (patch) | |
| tree | 121ca5ece3adc954010f32f1d502066158124887 | |
| parent | 9893e49d64a4874ea67849ee2cfbf3f3d6817573 (diff) | |
HWPOISON: Add simple debugfs interface to inject hwpoison on arbitary PFNs
Useful for some testing scenarios, although specific testing is often
done better through MADV_POISON
This can be done with the x86 level MCE injector too, but this interface
allows it to do independently from low level x86 changes.
v2: Add module license (Haicheng Li)
Signed-off-by: Andi Kleen <ak@linux.intel.com>
| -rw-r--r-- | mm/Kconfig | 4 | ||||
| -rw-r--r-- | mm/Makefile | 1 | ||||
| -rw-r--r-- | mm/hwpoison-inject.c | 41 |
3 files changed, 46 insertions, 0 deletions
diff --git a/mm/Kconfig b/mm/Kconfig index ea2d8b61c631..4b4e57a9643e 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
| @@ -243,6 +243,10 @@ config MEMORY_FAILURE | |||
| 243 | even when some of its memory has uncorrected errors. This requires | 243 | even when some of its memory has uncorrected errors. This requires |
| 244 | special hardware support and typically ECC memory. | 244 | special hardware support and typically ECC memory. |
| 245 | 245 | ||
| 246 | config HWPOISON_INJECT | ||
| 247 | tristate "Poison pages injector" | ||
| 248 | depends on MEMORY_FAILURE && DEBUG_KERNEL | ||
| 249 | |||
| 246 | config NOMMU_INITIAL_TRIM_EXCESS | 250 | config NOMMU_INITIAL_TRIM_EXCESS |
| 247 | int "Turn on mmap() excess space trimming before booting" | 251 | int "Turn on mmap() excess space trimming before booting" |
| 248 | depends on !MMU | 252 | depends on !MMU |
diff --git a/mm/Makefile b/mm/Makefile index dc2551e7d006..713c9f82d5ab 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
| @@ -41,5 +41,6 @@ endif | |||
| 41 | obj-$(CONFIG_QUICKLIST) += quicklist.o | 41 | obj-$(CONFIG_QUICKLIST) += quicklist.o |
| 42 | obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o | 42 | obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o |
| 43 | obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o | 43 | obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o |
| 44 | obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o | ||
| 44 | obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o | 45 | obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o |
| 45 | obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o | 46 | obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o |
diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c new file mode 100644 index 000000000000..e1d85137f086 --- /dev/null +++ b/mm/hwpoison-inject.c | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* Inject a hwpoison memory failure on a arbitary pfn */ | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/debugfs.h> | ||
| 4 | #include <linux/kernel.h> | ||
| 5 | #include <linux/mm.h> | ||
| 6 | |||
| 7 | static struct dentry *hwpoison_dir, *corrupt_pfn; | ||
| 8 | |||
| 9 | static int hwpoison_inject(void *data, u64 val) | ||
| 10 | { | ||
| 11 | if (!capable(CAP_SYS_ADMIN)) | ||
| 12 | return -EPERM; | ||
| 13 | printk(KERN_INFO "Injecting memory failure at pfn %Lx\n", val); | ||
| 14 | return __memory_failure(val, 18, 0); | ||
| 15 | } | ||
| 16 | |||
| 17 | DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n"); | ||
| 18 | |||
| 19 | static void pfn_inject_exit(void) | ||
| 20 | { | ||
| 21 | if (hwpoison_dir) | ||
| 22 | debugfs_remove_recursive(hwpoison_dir); | ||
| 23 | } | ||
| 24 | |||
| 25 | static int pfn_inject_init(void) | ||
| 26 | { | ||
| 27 | hwpoison_dir = debugfs_create_dir("hwpoison", NULL); | ||
| 28 | if (hwpoison_dir == NULL) | ||
| 29 | return -ENOMEM; | ||
| 30 | corrupt_pfn = debugfs_create_file("corrupt-pfn", 0600, hwpoison_dir, | ||
| 31 | NULL, &hwpoison_fops); | ||
| 32 | if (corrupt_pfn == NULL) { | ||
| 33 | pfn_inject_exit(); | ||
| 34 | return -ENOMEM; | ||
| 35 | } | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | module_init(pfn_inject_init); | ||
| 40 | module_exit(pfn_inject_exit); | ||
| 41 | MODULE_LICENSE("GPL"); | ||
