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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php