~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/mm/hwpoison-inject.c

Version: ~ [ linux-5.5-rc1 ] ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.78 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* Inject a hwpoison memory failure on a arbitrary pfn */
  2 #include <linux/module.h>
  3 #include <linux/debugfs.h>
  4 #include <linux/kernel.h>
  5 #include <linux/mm.h>
  6 #include <linux/swap.h>
  7 #include <linux/pagemap.h>
  8 #include <linux/hugetlb.h>
  9 #include "internal.h"
 10 
 11 static struct dentry *hwpoison_dir;
 12 
 13 static int hwpoison_inject(void *data, u64 val)
 14 {
 15         unsigned long pfn = val;
 16         struct page *p;
 17         struct page *hpage;
 18         int err;
 19 
 20         if (!capable(CAP_SYS_ADMIN))
 21                 return -EPERM;
 22 
 23         if (!pfn_valid(pfn))
 24                 return -ENXIO;
 25 
 26         p = pfn_to_page(pfn);
 27         hpage = compound_head(p);
 28         /*
 29          * This implies unable to support free buddy pages.
 30          */
 31         if (!get_hwpoison_page(p))
 32                 return 0;
 33 
 34         if (!hwpoison_filter_enable)
 35                 goto inject;
 36 
 37         if (!PageLRU(hpage) && !PageHuge(p))
 38                 shake_page(hpage, 0);
 39         /*
 40          * This implies unable to support non-LRU pages.
 41          */
 42         if (!PageLRU(hpage) && !PageHuge(p))
 43                 goto put_out;
 44 
 45         /*
 46          * do a racy check with elevated page count, to make sure PG_hwpoison
 47          * will only be set for the targeted owner (or on a free page).
 48          * memory_failure() will redo the check reliably inside page lock.
 49          */
 50         err = hwpoison_filter(hpage);
 51         if (err)
 52                 goto put_out;
 53 
 54 inject:
 55         pr_info("Injecting memory failure at pfn %#lx\n", pfn);
 56         return memory_failure(pfn, 18, MF_COUNT_INCREASED);
 57 put_out:
 58         put_hwpoison_page(p);
 59         return 0;
 60 }
 61 
 62 static int hwpoison_unpoison(void *data, u64 val)
 63 {
 64         if (!capable(CAP_SYS_ADMIN))
 65                 return -EPERM;
 66 
 67         return unpoison_memory(val);
 68 }
 69 
 70 DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n");
 71 DEFINE_SIMPLE_ATTRIBUTE(unpoison_fops, NULL, hwpoison_unpoison, "%lli\n");
 72 
 73 static void pfn_inject_exit(void)
 74 {
 75         debugfs_remove_recursive(hwpoison_dir);
 76 }
 77 
 78 static int pfn_inject_init(void)
 79 {
 80         struct dentry *dentry;
 81 
 82         hwpoison_dir = debugfs_create_dir("hwpoison", NULL);
 83         if (hwpoison_dir == NULL)
 84                 return -ENOMEM;
 85 
 86         /*
 87          * Note that the below poison/unpoison interfaces do not involve
 88          * hardware status change, hence do not require hardware support.
 89          * They are mainly for testing hwpoison in software level.
 90          */
 91         dentry = debugfs_create_file("corrupt-pfn", 0200, hwpoison_dir,
 92                                           NULL, &hwpoison_fops);
 93         if (!dentry)
 94                 goto fail;
 95 
 96         dentry = debugfs_create_file("unpoison-pfn", 0200, hwpoison_dir,
 97                                      NULL, &unpoison_fops);
 98         if (!dentry)
 99                 goto fail;
100 
101         dentry = debugfs_create_u32("corrupt-filter-enable", 0600,
102                                     hwpoison_dir, &hwpoison_filter_enable);
103         if (!dentry)
104                 goto fail;
105 
106         dentry = debugfs_create_u32("corrupt-filter-dev-major", 0600,
107                                     hwpoison_dir, &hwpoison_filter_dev_major);
108         if (!dentry)
109                 goto fail;
110 
111         dentry = debugfs_create_u32("corrupt-filter-dev-minor", 0600,
112                                     hwpoison_dir, &hwpoison_filter_dev_minor);
113         if (!dentry)
114                 goto fail;
115 
116         dentry = debugfs_create_u64("corrupt-filter-flags-mask", 0600,
117                                     hwpoison_dir, &hwpoison_filter_flags_mask);
118         if (!dentry)
119                 goto fail;
120 
121         dentry = debugfs_create_u64("corrupt-filter-flags-value", 0600,
122                                     hwpoison_dir, &hwpoison_filter_flags_value);
123         if (!dentry)
124                 goto fail;
125 
126 #ifdef CONFIG_MEMCG
127         dentry = debugfs_create_u64("corrupt-filter-memcg", 0600,
128                                     hwpoison_dir, &hwpoison_filter_memcg);
129         if (!dentry)
130                 goto fail;
131 #endif
132 
133         return 0;
134 fail:
135         pfn_inject_exit();
136         return -ENOMEM;
137 }
138 
139 module_init(pfn_inject_init);
140 module_exit(pfn_inject_exit);
141 MODULE_LICENSE("GPL");
142 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp