blob: ac692a9b766c87cf6d8b8ccbf3cd295ed0c48ccd [file] [log] [blame]
Andi Kleencae681f2009-09-16 11:50:17 +02001/* 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>
Wu Fengguang7c116f22009-12-16 12:19:59 +01006#include "internal.h"
Andi Kleencae681f2009-09-16 11:50:17 +02007
Wu Fengguang847ce402009-12-16 12:19:58 +01008static struct dentry *hwpoison_dir;
Andi Kleencae681f2009-09-16 11:50:17 +02009
10static int hwpoison_inject(void *data, u64 val)
11{
12 if (!capable(CAP_SYS_ADMIN))
13 return -EPERM;
14 printk(KERN_INFO "Injecting memory failure at pfn %Lx\n", val);
15 return __memory_failure(val, 18, 0);
16}
17
Wu Fengguang847ce402009-12-16 12:19:58 +010018static int hwpoison_unpoison(void *data, u64 val)
19{
20 if (!capable(CAP_SYS_ADMIN))
21 return -EPERM;
22
23 return unpoison_memory(val);
24}
25
Andi Kleencae681f2009-09-16 11:50:17 +020026DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n");
Wu Fengguang847ce402009-12-16 12:19:58 +010027DEFINE_SIMPLE_ATTRIBUTE(unpoison_fops, NULL, hwpoison_unpoison, "%lli\n");
Andi Kleencae681f2009-09-16 11:50:17 +020028
29static void pfn_inject_exit(void)
30{
31 if (hwpoison_dir)
32 debugfs_remove_recursive(hwpoison_dir);
33}
34
35static int pfn_inject_init(void)
36{
Wu Fengguang847ce402009-12-16 12:19:58 +010037 struct dentry *dentry;
38
Andi Kleencae681f2009-09-16 11:50:17 +020039 hwpoison_dir = debugfs_create_dir("hwpoison", NULL);
40 if (hwpoison_dir == NULL)
41 return -ENOMEM;
Wu Fengguang847ce402009-12-16 12:19:58 +010042
43 /*
44 * Note that the below poison/unpoison interfaces do not involve
45 * hardware status change, hence do not require hardware support.
46 * They are mainly for testing hwpoison in software level.
47 */
48 dentry = debugfs_create_file("corrupt-pfn", 0600, hwpoison_dir,
Andi Kleencae681f2009-09-16 11:50:17 +020049 NULL, &hwpoison_fops);
Wu Fengguang847ce402009-12-16 12:19:58 +010050 if (!dentry)
51 goto fail;
52
53 dentry = debugfs_create_file("unpoison-pfn", 0600, hwpoison_dir,
54 NULL, &unpoison_fops);
55 if (!dentry)
56 goto fail;
57
Wu Fengguang7c116f22009-12-16 12:19:59 +010058 dentry = debugfs_create_u32("corrupt-filter-dev-major", 0600,
59 hwpoison_dir, &hwpoison_filter_dev_major);
60 if (!dentry)
61 goto fail;
62
63 dentry = debugfs_create_u32("corrupt-filter-dev-minor", 0600,
64 hwpoison_dir, &hwpoison_filter_dev_minor);
65 if (!dentry)
66 goto fail;
67
Andi Kleencae681f2009-09-16 11:50:17 +020068 return 0;
Wu Fengguang847ce402009-12-16 12:19:58 +010069fail:
70 pfn_inject_exit();
71 return -ENOMEM;
Andi Kleencae681f2009-09-16 11:50:17 +020072}
73
74module_init(pfn_inject_init);
75module_exit(pfn_inject_exit);
76MODULE_LICENSE("GPL");