aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/vm/hwpoison.txt10
-rw-r--r--mm/Kconfig1
-rw-r--r--mm/hwpoison-inject.c10
-rw-r--r--mm/internal.h2
-rw-r--r--mm/memory-failure.c20
5 files changed, 43 insertions, 0 deletions
diff --git a/Documentation/vm/hwpoison.txt b/Documentation/vm/hwpoison.txt
index 4ef7bb30d15c..f454d3cd4d60 100644
--- a/Documentation/vm/hwpoison.txt
+++ b/Documentation/vm/hwpoison.txt
@@ -123,6 +123,16 @@ Only handle memory failures to pages associated with the file system defined
123by block device major/minor. -1U is the wildcard value. 123by block device major/minor. -1U is the wildcard value.
124This should be only used for testing with artificial injection. 124This should be only used for testing with artificial injection.
125 125
126
127corrupt-filter-flags-mask
128corrupt-filter-flags-value
129
130When specified, only poison pages if ((page_flags & mask) == value).
131This allows stress testing of many kinds of pages. The page_flags
132are the same as in /proc/kpageflags. The flag bits are defined in
133include/linux/kernel-page-flags.h and documented in
134Documentation/vm/pagemap.txt
135
126Architecture specific MCE injector 136Architecture specific MCE injector
127 137
128x86 has mce-inject, mce-test 138x86 has mce-inject, mce-test
diff --git a/mm/Kconfig b/mm/Kconfig
index 2310984591ed..8cea7fde06e1 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -253,6 +253,7 @@ config MEMORY_FAILURE
253config HWPOISON_INJECT 253config HWPOISON_INJECT
254 tristate "Poison pages injector" 254 tristate "Poison pages injector"
255 depends on MEMORY_FAILURE && DEBUG_KERNEL 255 depends on MEMORY_FAILURE && DEBUG_KERNEL
256 select PROC_PAGE_MONITOR
256 257
257config NOMMU_INITIAL_TRIM_EXCESS 258config NOMMU_INITIAL_TRIM_EXCESS
258 int "Turn on mmap() excess space trimming before booting" 259 int "Turn on mmap() excess space trimming before booting"
diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c
index 2b6b3200fa65..c4dfd89f654a 100644
--- a/mm/hwpoison-inject.c
+++ b/mm/hwpoison-inject.c
@@ -102,6 +102,16 @@ static int pfn_inject_init(void)
102 if (!dentry) 102 if (!dentry)
103 goto fail; 103 goto fail;
104 104
105 dentry = debugfs_create_u64("corrupt-filter-flags-mask", 0600,
106 hwpoison_dir, &hwpoison_filter_flags_mask);
107 if (!dentry)
108 goto fail;
109
110 dentry = debugfs_create_u64("corrupt-filter-flags-value", 0600,
111 hwpoison_dir, &hwpoison_filter_flags_value);
112 if (!dentry)
113 goto fail;
114
105 return 0; 115 return 0;
106fail: 116fail:
107 pfn_inject_exit(); 117 pfn_inject_exit();
diff --git a/mm/internal.h b/mm/internal.h
index 04bbce8b8ba6..b2027c73119b 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -255,3 +255,5 @@ extern int hwpoison_filter(struct page *p);
255 255
256extern u32 hwpoison_filter_dev_major; 256extern u32 hwpoison_filter_dev_major;
257extern u32 hwpoison_filter_dev_minor; 257extern u32 hwpoison_filter_dev_minor;
258extern u64 hwpoison_filter_flags_mask;
259extern u64 hwpoison_filter_flags_value;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 82ac73436d0e..22d2b2028e54 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -34,6 +34,7 @@
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/mm.h> 35#include <linux/mm.h>
36#include <linux/page-flags.h> 36#include <linux/page-flags.h>
37#include <linux/kernel-page-flags.h>
37#include <linux/sched.h> 38#include <linux/sched.h>
38#include <linux/ksm.h> 39#include <linux/ksm.h>
39#include <linux/rmap.h> 40#include <linux/rmap.h>
@@ -50,8 +51,12 @@ atomic_long_t mce_bad_pages __read_mostly = ATOMIC_LONG_INIT(0);
50 51
51u32 hwpoison_filter_dev_major = ~0U; 52u32 hwpoison_filter_dev_major = ~0U;
52u32 hwpoison_filter_dev_minor = ~0U; 53u32 hwpoison_filter_dev_minor = ~0U;
54u64 hwpoison_filter_flags_mask;
55u64 hwpoison_filter_flags_value;
53EXPORT_SYMBOL_GPL(hwpoison_filter_dev_major); 56EXPORT_SYMBOL_GPL(hwpoison_filter_dev_major);
54EXPORT_SYMBOL_GPL(hwpoison_filter_dev_minor); 57EXPORT_SYMBOL_GPL(hwpoison_filter_dev_minor);
58EXPORT_SYMBOL_GPL(hwpoison_filter_flags_mask);
59EXPORT_SYMBOL_GPL(hwpoison_filter_flags_value);
55 60
56static int hwpoison_filter_dev(struct page *p) 61static int hwpoison_filter_dev(struct page *p)
57{ 62{
@@ -83,11 +88,26 @@ static int hwpoison_filter_dev(struct page *p)
83 return 0; 88 return 0;
84} 89}
85 90
91static int hwpoison_filter_flags(struct page *p)
92{
93 if (!hwpoison_filter_flags_mask)
94 return 0;
95
96 if ((stable_page_flags(p) & hwpoison_filter_flags_mask) ==
97 hwpoison_filter_flags_value)
98 return 0;
99 else
100 return -EINVAL;
101}
102
86int hwpoison_filter(struct page *p) 103int hwpoison_filter(struct page *p)
87{ 104{
88 if (hwpoison_filter_dev(p)) 105 if (hwpoison_filter_dev(p))
89 return -EINVAL; 106 return -EINVAL;
90 107
108 if (hwpoison_filter_flags(p))
109 return -EINVAL;
110
91 return 0; 111 return 0;
92} 112}
93EXPORT_SYMBOL_GPL(hwpoison_filter); 113EXPORT_SYMBOL_GPL(hwpoison_filter);