• Wu Fengguang's avatar
    HWPOISON: add fs/device filters · 7c116f2b
    Wu Fengguang authored
    
    Filesystem data/metadata present the most tricky-to-isolate pages.
    It requires careful code review and stress testing to get them right.
    
    The fs/device filter helps to target the stress tests to some specific
    filesystem pages. The filter condition is block device's major/minor
    numbers:
            - corrupt-filter-dev-major
            - corrupt-filter-dev-minor
    When specified (non -1), only page cache pages that belong to that
    device will be poisoned.
    
    The filters are checked reliably on the locked and refcounted page.
    
    Haicheng: clear PG_hwpoison and drop bad page count if filter not OK
    AK: Add documentation
    
    CC: Haicheng Li <haicheng.li@intel.com>
    CC: Nick Piggin <npiggin@suse.de>
    Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
    Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
    7c116f2b
hwpoison-inject.c 1.79 KB
/* Inject a hwpoison memory failure on a arbitary pfn */
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include "internal.h"

static struct dentry *hwpoison_dir;

static int hwpoison_inject(void *data, u64 val)
{
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	printk(KERN_INFO "Injecting memory failure at pfn %Lx\n", val);
	return __memory_failure(val, 18, 0);
}

static int hwpoison_unpoison(void *data, u64 val)
{
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	return unpoison_memory(val);
}

DEFINE_SIMPLE_ATTRIBUTE(hwpoison_fops, NULL, hwpoison_inject, "%lli\n");
DEFINE_SIMPLE_ATTRIBUTE(unpoison_fops, NULL, hwpoison_unpoison, "%lli\n");

static void pfn_inject_exit(void)
{
	if (hwpoison_dir)
		debugfs_remove_recursive(hwpoison_dir);
}

static int pfn_inject_init(void)
{
	struct dentry *dentry;

	hwpoison_dir = debugfs_create_dir("hwpoison", NULL);
	if (hwpoison_dir == NULL)
		return -ENOMEM;

	/*
	 * Note that the below poison/unpoison interfaces do not involve
	 * hardware status change, hence do not require hardware support.
	 * They are mainly for testing hwpoison in software level.
	 */
	dentry = debugfs_create_file("corrupt-pfn", 0600, hwpoison_dir,
					  NULL, &hwpoison_fops);
	if (!dentry)
		goto fail;

	dentry = debugfs_create_file("unpoison-pfn", 0600, hwpoison_dir,
				     NULL, &unpoison_fops);
	if (!dentry)
		goto fail;

	dentry = debugfs_create_u32("corrupt-filter-dev-major", 0600,
				    hwpoison_dir, &hwpoison_filter_dev_major);
	if (!dentry)
		goto fail;

	dentry = debugfs_create_u32("corrupt-filter-dev-minor", 0600,
				    hwpoison_dir, &hwpoison_filter_dev_minor);
	if (!dentry)
		goto fail;

	return 0;
fail:
	pfn_inject_exit();
	return -ENOMEM;
}

module_init(pfn_inject_init);
module_exit(pfn_inject_exit);
MODULE_LICENSE("GPL");