diff options
Diffstat (limited to 'arch/parisc/mm')
| -rw-r--r-- | arch/parisc/mm/fault.c | 33 | ||||
| -rw-r--r-- | arch/parisc/mm/hugetlbpage.c | 1 | ||||
| -rw-r--r-- | arch/parisc/mm/init.c | 1 | ||||
| -rw-r--r-- | arch/parisc/mm/ioremap.c | 1 | 
4 files changed, 32 insertions, 4 deletions
| diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 5b101f6a5607..e247edbca68e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -17,6 +17,7 @@  #include <linux/interrupt.h>  #include <linux/extable.h>  #include <linux/uaccess.h> +#include <linux/hugetlb.h>  #include <asm/traps.h> @@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,  	struct task_struct *tsk;  	struct mm_struct *mm;  	unsigned long acc_type; -	int fault; +	int fault = 0;  	unsigned int flags;  	if (faulthandler_disabled()) @@ -315,7 +316,8 @@ good_area:  			goto out_of_memory;  		else if (fault & VM_FAULT_SIGSEGV)  			goto bad_area; -		else if (fault & VM_FAULT_SIGBUS) +		else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| +				  VM_FAULT_HWPOISON_LARGE))  			goto bad_area;  		BUG();  	} @@ -352,8 +354,7 @@ bad_area:  	if (user_mode(regs)) {  		struct siginfo si; - -		show_signal_msg(regs, code, address, tsk, vma); +		unsigned int lsb = 0;  		switch (code) {  		case 15:	/* Data TLB miss fault/Data page fault */ @@ -386,6 +387,30 @@ bad_area:  			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;  			break;  		} + +#ifdef CONFIG_MEMORY_FAILURE +		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { +			printk(KERN_ERR +	"MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n", +			tsk->comm, tsk->pid, address); +			si.si_signo = SIGBUS; +			si.si_code = BUS_MCEERR_AR; +		} +#endif + +		/* +		 * Either small page or large page may be poisoned. +		 * In other words, VM_FAULT_HWPOISON_LARGE and +		 * VM_FAULT_HWPOISON are mutually exclusive. +		 */ +		if (fault & VM_FAULT_HWPOISON_LARGE) +			lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); +		else if (fault & VM_FAULT_HWPOISON) +			lsb = PAGE_SHIFT; +		else +			show_signal_msg(regs, code, address, tsk, vma); +		si.si_addr_lsb = lsb; +  		si.si_errno = 0;  		si.si_addr = (void __user *) address;  		force_sig_info(si.si_signo, &si, current); diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c index 5eb8f633b282..d77479ae3af2 100644 --- a/arch/parisc/mm/hugetlbpage.c +++ b/arch/parisc/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * PARISC64 Huge TLB page support.   * diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1ca9a2b4239f..13f7854e0d49 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   *  linux/arch/parisc/mm/init.c   * diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index 838d0259cd27..92a9b5f12f98 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * arch/parisc/mm/ioremap.c   * |