diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
| commit | 7731b8bc94e599c9a79e428f3359ff2c34b7576a (patch) | |
| tree | 879f18ccbe274122f2d4f095b43cbc7f953e0ada /arch/parisc/mm/fault.c | |
| parent | 48e315618dc4dc8904182cd221e3d395d5d97005 (diff) | |
| parent | 9ffc59d57228d74809700be6f7ecb1db10292f05 (diff) | |
Merge branch 'linus' into x86/urgent
Required to queue a dependent fix.
Diffstat (limited to 'arch/parisc/mm/fault.c')
| -rw-r--r-- | arch/parisc/mm/fault.c | 54 | 
1 files changed, 25 insertions, 29 deletions
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index e247edbca68e..a80117980fc2 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -353,23 +353,22 @@ bad_area:  	up_read(&mm->mmap_sem);  	if (user_mode(regs)) { -		struct siginfo si; -		unsigned int lsb = 0; +		int signo, si_code;  		switch (code) {  		case 15:	/* Data TLB miss fault/Data page fault */  			/* send SIGSEGV when outside of vma */  			if (!vma ||  			    address < vma->vm_start || address >= vma->vm_end) { -				si.si_signo = SIGSEGV; -				si.si_code = SEGV_MAPERR; +				signo = SIGSEGV; +				si_code = SEGV_MAPERR;  				break;  			}  			/* send SIGSEGV for wrong permissions */  			if ((vma->vm_flags & acc_type) != acc_type) { -				si.si_signo = SIGSEGV; -				si.si_code = SEGV_ACCERR; +				signo = SIGSEGV; +				si_code = SEGV_ACCERR;  				break;  			} @@ -377,43 +376,40 @@ bad_area:  			/* fall through */  		case 17:	/* NA data TLB miss / page fault */  		case 18:	/* Unaligned access - PCXS only */ -			si.si_signo = SIGBUS; -			si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR; +			signo = SIGBUS; +			si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;  			break;  		case 16:	/* Non-access instruction TLB miss fault */  		case 26:	/* PCXL: Data memory access rights trap */  		default: -			si.si_signo = SIGSEGV; -			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; +			signo = SIGSEGV; +			si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;  			break;  		} -  #ifdef CONFIG_MEMORY_FAILURE  		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { +			unsigned int lsb = 0;  			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; +			/* +			 * 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; + +			force_sig_mceerr(BUS_MCEERR_AR, (void __user *) address, +					 lsb, current); +			return;  		}  #endif +		show_signal_msg(regs, code, address, tsk, vma); -		/* -		 * 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); +		force_sig_fault(signo, si_code, (void __user *) address, current);  		return;  	}  | 
