]>
Commit | Line | Data |
---|---|---|
cae681fc AK |
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> | |
7c116f2b | 6 | #include "internal.h" |
cae681fc | 7 | |
847ce401 | 8 | static struct dentry *hwpoison_dir; |
cae681fc AK |
9 | |
10 | static 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 | ||
847ce401 WF |
18 | static 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 | ||
cae681fc | 26 | DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n"); |
847ce401 | 27 | DEFINE_SIMPLE_ATTRIBUTE(unpoison_fops, NULL, hwpoison_unpoison, "%lli\n"); |
cae681fc AK |
28 | |
29 | static void pfn_inject_exit(void) | |
30 | { | |
31 | if (hwpoison_dir) | |
32 | debugfs_remove_recursive(hwpoison_dir); | |
33 | } | |
34 | ||
35 | static int pfn_inject_init(void) | |
36 | { | |
847ce401 WF |
37 | struct dentry *dentry; |
38 | ||
cae681fc AK |
39 | hwpoison_dir = debugfs_create_dir("hwpoison", NULL); |
40 | if (hwpoison_dir == NULL) | |
41 | return -ENOMEM; | |
847ce401 WF |
42 | |
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, | |
cae681fc | 49 | NULL, &hwpoison_fops); |
847ce401 WF |
50 | 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 | ||
7c116f2b WF |
58 | 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 | ||
cae681fc | 68 | return 0; |
847ce401 WF |
69 | fail: |
70 | pfn_inject_exit(); | |
71 | return -ENOMEM; | |
cae681fc AK |
72 | } |
73 | ||
74 | module_init(pfn_inject_init); | |
75 | module_exit(pfn_inject_exit); | |
76 | MODULE_LICENSE("GPL"); |