6e35e563bf50b660ac30a8808c9942e6083c9657
[sfrench/cifs-2.6.git] / mm / hwpoison-inject.c
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;
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 static int hwpoison_unpoison(void *data, u64 val)
18 {
19         if (!capable(CAP_SYS_ADMIN))
20                 return -EPERM;
21
22         return unpoison_memory(val);
23 }
24
25 DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n");
26 DEFINE_SIMPLE_ATTRIBUTE(unpoison_fops, NULL, hwpoison_unpoison, "%lli\n");
27
28 static void pfn_inject_exit(void)
29 {
30         if (hwpoison_dir)
31                 debugfs_remove_recursive(hwpoison_dir);
32 }
33
34 static int pfn_inject_init(void)
35 {
36         struct dentry *dentry;
37
38         hwpoison_dir = debugfs_create_dir("hwpoison", NULL);
39         if (hwpoison_dir == NULL)
40                 return -ENOMEM;
41
42         /*
43          * Note that the below poison/unpoison interfaces do not involve
44          * hardware status change, hence do not require hardware support.
45          * They are mainly for testing hwpoison in software level.
46          */
47         dentry = debugfs_create_file("corrupt-pfn", 0600, hwpoison_dir,
48                                           NULL, &hwpoison_fops);
49         if (!dentry)
50                 goto fail;
51
52         dentry = debugfs_create_file("unpoison-pfn", 0600, hwpoison_dir,
53                                      NULL, &unpoison_fops);
54         if (!dentry)
55                 goto fail;
56
57         return 0;
58 fail:
59         pfn_inject_exit();
60         return -ENOMEM;
61 }
62
63 module_init(pfn_inject_init);
64 module_exit(pfn_inject_exit);
65 MODULE_LICENSE("GPL");