1962 lines · 53.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* * Copyright (C) 2008, 2009 Intel Corporation * Authors: Andi Kleen, Fengguang Wu * * High level machine check handler. Handles pages reported by the * hardware as being corrupted usually due to a multi-bit ECC memory or cache * failure. *  * In addition there is a "soft offline" entry point that allows stop using * not-yet-corrupted-by-suspicious pages without killing anything. * * Handles page cache pages in various states.	The tricky part * here is that we can access any page asynchronously in respect to  * other VM users, because memory failures could happen anytime and  * anywhere. This could violate some of their assumptions. This is why  * this code has to be extremely careful. Generally it tries to use  * normal locking rules, as in get the standard locks, even if that means  * the error handling takes potentially a long time. * * It can be very tempting to add handling for obscure cases here. * In general any code for handling new cases should only be added iff: * - You know how to test it. * - You have a test that can be added to mce-test *   https://git.kernel.org/cgit/utils/cpu/mce/mce-test.git/ * - The case actually shows up as a frequent (top 10) page state in *   tools/vm/page-types when running a real workload. *  * There are several operations here with exponential complexity because * of unsuitable VM data structures. For example the operation to map back  * from RMAP chains to processes has to walk the complete process list and  * has non linear complexity with the number. But since memory corruptions * are rare we hope to get away with this. This avoids impacting the core  * VM. */#include <linux/kernel.h>#include <linux/mm.h>#include <linux/page-flags.h>#include <linux/kernel-page-flags.h>#include <linux/sched/signal.h>#include <linux/sched/task.h>#include <linux/ksm.h>#include <linux/rmap.h>#include <linux/export.h>#include <linux/pagemap.h>#include <linux/swap.h>#include <linux/backing-dev.h>#include <linux/migrate.h>#include <linux/suspend.h>#include <linux/slab.h>#include <linux/swapops.h>#include <linux/hugetlb.h>#include <linux/memory_hotplug.h>#include <linux/mm_inline.h>#include <linux/memremap.h>#include <linux/kfifo.h>#include <linux/ratelimit.h>#include <linux/page-isolation.h>#include "internal.h"#include "ras/ras_event.h" int sysctl_memory_failure_early_kill __read_mostly = 0; int sysctl_memory_failure_recovery __read_mostly = 1; atomic_long_t num_poisoned_pages __read_mostly = ATOMIC_LONG_INIT(0); #if defined(CONFIG_HWPOISON_INJECT) || defined(CONFIG_HWPOISON_INJECT_MODULE) u32 hwpoison_filter_enable = 0;u32 hwpoison_filter_dev_major = ~0U;u32 hwpoison_filter_dev_minor = ~0U;u64 hwpoison_filter_flags_mask;u64 hwpoison_filter_flags_value;EXPORT_SYMBOL_GPL(hwpoison_filter_enable);EXPORT_SYMBOL_GPL(hwpoison_filter_dev_major);EXPORT_SYMBOL_GPL(hwpoison_filter_dev_minor);EXPORT_SYMBOL_GPL(hwpoison_filter_flags_mask);EXPORT_SYMBOL_GPL(hwpoison_filter_flags_value); static int hwpoison_filter_dev(struct page *p){	struct address_space *mapping;	dev_t dev; 	if (hwpoison_filter_dev_major == ~0U &&	    hwpoison_filter_dev_minor == ~0U)		return 0; 	/*	 * page_mapping() does not accept slab pages.	 */	if (PageSlab(p))		return -EINVAL; 	mapping = page_mapping(p);	if (mapping == NULL || mapping->host == NULL)		return -EINVAL; 	dev = mapping->host->i_sb->s_dev;	if (hwpoison_filter_dev_major != ~0U &&	    hwpoison_filter_dev_major != MAJOR(dev))		return -EINVAL;	if (hwpoison_filter_dev_minor != ~0U &&	    hwpoison_filter_dev_minor != MINOR(dev))		return -EINVAL; 	return 0;} static int hwpoison_filter_flags(struct page *p){	if (!hwpoison_filter_flags_mask)		return 0; 	if ((stable_page_flags(p) & hwpoison_filter_flags_mask) ==				    hwpoison_filter_flags_value)		return 0;	else		return -EINVAL;} /* * This allows stress tests to limit test scope to a collection of tasks * by putting them under some memcg. This prevents killing unrelated/important * processes such as /sbin/init. Note that the target task may share clean * pages with init (eg. libc text), which is harmless. If the target task * share _dirty_ pages with another task B, the test scheme must make sure B * is also included in the memcg. At last, due to race conditions this filter * can only guarantee that the page either belongs to the memcg tasks, or is * a freed page. */#ifdef CONFIG_MEMCGu64 hwpoison_filter_memcg;EXPORT_SYMBOL_GPL(hwpoison_filter_memcg);static int hwpoison_filter_task(struct page *p){	if (!hwpoison_filter_memcg)		return 0; 	if (page_cgroup_ino(p) != hwpoison_filter_memcg)		return -EINVAL; 	return 0;}#elsestatic int hwpoison_filter_task(struct page *p) { return 0; }#endif int hwpoison_filter(struct page *p){	if (!hwpoison_filter_enable)		return 0; 	if (hwpoison_filter_dev(p))		return -EINVAL; 	if (hwpoison_filter_flags(p))		return -EINVAL; 	if (hwpoison_filter_task(p))		return -EINVAL; 	return 0;}#elseint hwpoison_filter(struct page *p){	return 0;}#endif EXPORT_SYMBOL_GPL(hwpoison_filter); /* * Kill all processes that have a poisoned page mapped and then isolate * the page. * * General strategy: * Find all processes having the page mapped and kill them. * But we keep a page reference around so that the page is not * actually freed yet. * Then stash the page away * * There's no convenient way to get back to mapped processes * from the VMAs. So do a brute-force search over all * running processes. * * Remember that machine checks are not common (or rather * if they are common you have other problems), so this shouldn't * be a performance issue. * * Also there are some races possible while we get from the * error detection to actually handle it. */ struct to_kill {	struct list_head nd;	struct task_struct *tsk;	unsigned long addr;	short size_shift;}; /* * Send all the processes who have the page mapped a signal. * ``action optional'' if they are not immediately affected by the error * ``action required'' if error happened in current execution context */static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags){	struct task_struct *t = tk->tsk;	short addr_lsb = tk->size_shift;	int ret = 0; 	pr_err("Memory failure: %#lx: Sending SIGBUS to %s:%d due to hardware memory corruption\n",			pfn, t->comm, t->pid); 	if (flags & MF_ACTION_REQUIRED) {		WARN_ON_ONCE(t != current);		ret = force_sig_mceerr(BUS_MCEERR_AR,					 (void __user *)tk->addr, addr_lsb);	} else {		/*		 * Don't use force here, it's convenient if the signal		 * can be temporarily blocked.		 * This could cause a loop when the user sets SIGBUS		 * to SIG_IGN, but hopefully no one will do that?		 */		ret = send_sig_mceerr(BUS_MCEERR_AO, (void __user *)tk->addr,				      addr_lsb, t);  /* synchronous? */	}	if (ret < 0)		pr_info("Memory failure: Error sending signal to %s:%d: %d\n",			t->comm, t->pid, ret);	return ret;} /* * When a unknown page type is encountered drain as many buffers as possible * in the hope to turn the page into a LRU or free page, which we can handle. */void shake_page(struct page *p, int access){	if (PageHuge(p))		return; 	if (!PageSlab(p)) {		lru_add_drain_all();		if (PageLRU(p))			return;		drain_all_pages(page_zone(p));		if (PageLRU(p) || is_free_buddy_page(p))			return;	} 	/*	 * Only call shrink_node_slabs here (which would also shrink	 * other caches) if access is not potentially fatal.	 */	if (access)		drop_slab_node(page_to_nid(p));}EXPORT_SYMBOL_GPL(shake_page); static unsigned long dev_pagemap_mapping_shift(struct page *page,		struct vm_area_struct *vma){	unsigned long address = vma_address(page, vma);	pgd_t *pgd;	p4d_t *p4d;	pud_t *pud;	pmd_t *pmd;	pte_t *pte; 	pgd = pgd_offset(vma->vm_mm, address);	if (!pgd_present(*pgd))		return 0;	p4d = p4d_offset(pgd, address);	if (!p4d_present(*p4d))		return 0;	pud = pud_offset(p4d, address);	if (!pud_present(*pud))		return 0;	if (pud_devmap(*pud))		return PUD_SHIFT;	pmd = pmd_offset(pud, address);	if (!pmd_present(*pmd))		return 0;	if (pmd_devmap(*pmd))		return PMD_SHIFT;	pte = pte_offset_map(pmd, address);	if (!pte_present(*pte))		return 0;	if (pte_devmap(*pte))		return PAGE_SHIFT;	return 0;} /* * Failure handling: if we can't find or can't kill a process there's * not much we can do.	We just print a message and ignore otherwise. */ /* * Schedule a process for later kill. * Uses GFP_ATOMIC allocations to avoid potential recursions in the VM. */static void add_to_kill(struct task_struct *tsk, struct page *p,		       struct vm_area_struct *vma,		       struct list_head *to_kill){	struct to_kill *tk; 	tk = kmalloc(sizeof(struct to_kill), GFP_ATOMIC);	if (!tk) {		pr_err("Memory failure: Out of memory while machine check handling\n");		return;	} 	tk->addr = page_address_in_vma(p, vma);	if (is_zone_device_page(p))		tk->size_shift = dev_pagemap_mapping_shift(p, vma);	else		tk->size_shift = page_shift(compound_head(p)); 	/*	 * Send SIGKILL if "tk->addr == -EFAULT". Also, as	 * "tk->size_shift" is always non-zero for !is_zone_device_page(),	 * so "tk->size_shift == 0" effectively checks no mapping on	 * ZONE_DEVICE. Indeed, when a devdax page is mmapped N times	 * to a process' address space, it's possible not all N VMAs	 * contain mappings for the page, but at least one VMA does.	 * Only deliver SIGBUS with payload derived from the VMA that	 * has a mapping for the page.	 */	if (tk->addr == -EFAULT) {		pr_info("Memory failure: Unable to find user space address %lx in %s\n",			page_to_pfn(p), tsk->comm);	} else if (tk->size_shift == 0) {		kfree(tk);		return;	} 	get_task_struct(tsk);	tk->tsk = tsk;	list_add_tail(&tk->nd, to_kill);} /* * Kill the processes that have been collected earlier. * * Only do anything when DOIT is set, otherwise just free the list * (this is used for clean pages which do not need killing) * Also when FAIL is set do a force kill because something went * wrong earlier. */static void kill_procs(struct list_head *to_kill, int forcekill, bool fail,		unsigned long pfn, int flags){	struct to_kill *tk, *next; 	list_for_each_entry_safe (tk, next, to_kill, nd) {		if (forcekill) {			/*			 * In case something went wrong with munmapping			 * make sure the process doesn't catch the			 * signal and then access the memory. Just kill it.			 */			if (fail || tk->addr == -EFAULT) {				pr_err("Memory failure: %#lx: forcibly killing %s:%d because of failure to unmap corrupted page\n",				       pfn, tk->tsk->comm, tk->tsk->pid);				do_send_sig_info(SIGKILL, SEND_SIG_PRIV,						 tk->tsk, PIDTYPE_PID);			} 			/*			 * In theory the process could have mapped			 * something else on the address in-between. We could			 * check for that, but we need to tell the			 * process anyways.			 */			else if (kill_proc(tk, pfn, flags) < 0)				pr_err("Memory failure: %#lx: Cannot send advisory machine check signal to %s:%d\n",				       pfn, tk->tsk->comm, tk->tsk->pid);		}		put_task_struct(tk->tsk);		kfree(tk);	}} /* * Find a dedicated thread which is supposed to handle SIGBUS(BUS_MCEERR_AO) * on behalf of the thread group. Return task_struct of the (first found) * dedicated thread if found, and return NULL otherwise. * * We already hold read_lock(&tasklist_lock) in the caller, so we don't * have to call rcu_read_lock/unlock() in this function. */static struct task_struct *find_early_kill_thread(struct task_struct *tsk){	struct task_struct *t; 	for_each_thread(tsk, t) {		if (t->flags & PF_MCE_PROCESS) {			if (t->flags & PF_MCE_EARLY)				return t;		} else {			if (sysctl_memory_failure_early_kill)				return t;		}	}	return NULL;} /* * Determine whether a given process is "early kill" process which expects * to be signaled when some page under the process is hwpoisoned. * Return task_struct of the dedicated thread (main thread unless explicitly * specified) if the process is "early kill," and otherwise returns NULL. * * Note that the above is true for Action Optional case, but not for Action * Required case where SIGBUS should sent only to the current thread. */static struct task_struct *task_early_kill(struct task_struct *tsk,					   int force_early){	if (!tsk->mm)		return NULL;	if (force_early) {		/*		 * Comparing ->mm here because current task might represent		 * a subthread, while tsk always points to the main thread.		 */		if (tsk->mm == current->mm)			return current;		else			return NULL;	}	return find_early_kill_thread(tsk);} /* * Collect processes when the error hit an anonymous page. */static void collect_procs_anon(struct page *page, struct list_head *to_kill,				int force_early){	struct vm_area_struct *vma;	struct task_struct *tsk;	struct anon_vma *av;	pgoff_t pgoff; 	av = page_lock_anon_vma_read(page);	if (av == NULL)	/* Not actually mapped anymore */		return; 	pgoff = page_to_pgoff(page);	read_lock(&tasklist_lock);	for_each_process (tsk) {		struct anon_vma_chain *vmac;		struct task_struct *t = task_early_kill(tsk, force_early); 		if (!t)			continue;		anon_vma_interval_tree_foreach(vmac, &av->rb_root,					       pgoff, pgoff) {			vma = vmac->vma;			if (!page_mapped_in_vma(page, vma))				continue;			if (vma->vm_mm == t->mm)				add_to_kill(t, page, vma, to_kill);		}	}	read_unlock(&tasklist_lock);	page_unlock_anon_vma_read(av);} /* * Collect processes when the error hit a file mapped page. */static void collect_procs_file(struct page *page, struct list_head *to_kill,				int force_early){	struct vm_area_struct *vma;	struct task_struct *tsk;	struct address_space *mapping = page->mapping; 	i_mmap_lock_read(mapping);	read_lock(&tasklist_lock);	for_each_process(tsk) {		pgoff_t pgoff = page_to_pgoff(page);		struct task_struct *t = task_early_kill(tsk, force_early); 		if (!t)			continue;		vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff,				      pgoff) {			/*			 * Send early kill signal to tasks where a vma covers			 * the page but the corrupted page is not necessarily

Lines 1–500 of 1962.