diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
commit | 1236d6bb6e19fc72ffc6bbcdeb1bfefe450e54ee (patch) | |
tree | 47da3feee8e263e8c9352c85cf518e624be3c211 /arch/parisc/mm/fault.c | |
parent | 750b1a6894ecc9b178c6e3d0a1170122971b2036 (diff) | |
parent | 8a5776a5f49812d29fe4b2d0a2d71675c3facf3f (diff) |
Merge 4.14-rc4 into staging-next
We want the staging/iio fixes in here as well to handle merge issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/parisc/mm/fault.c')
-rw-r--r-- | arch/parisc/mm/fault.c | 33 |
1 files changed, 29 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 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/extable.h> | 18 | #include <linux/extable.h> |
19 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
20 | #include <linux/hugetlb.h> | ||
20 | 21 | ||
21 | #include <asm/traps.h> | 22 | #include <asm/traps.h> |
22 | 23 | ||
@@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, | |||
261 | struct task_struct *tsk; | 262 | struct task_struct *tsk; |
262 | struct mm_struct *mm; | 263 | struct mm_struct *mm; |
263 | unsigned long acc_type; | 264 | unsigned long acc_type; |
264 | int fault; | 265 | int fault = 0; |
265 | unsigned int flags; | 266 | unsigned int flags; |
266 | 267 | ||
267 | if (faulthandler_disabled()) | 268 | if (faulthandler_disabled()) |
@@ -315,7 +316,8 @@ good_area: | |||
315 | goto out_of_memory; | 316 | goto out_of_memory; |
316 | else if (fault & VM_FAULT_SIGSEGV) | 317 | else if (fault & VM_FAULT_SIGSEGV) |
317 | goto bad_area; | 318 | goto bad_area; |
318 | else if (fault & VM_FAULT_SIGBUS) | 319 | else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| |
320 | VM_FAULT_HWPOISON_LARGE)) | ||
319 | goto bad_area; | 321 | goto bad_area; |
320 | BUG(); | 322 | BUG(); |
321 | } | 323 | } |
@@ -352,8 +354,7 @@ bad_area: | |||
352 | 354 | ||
353 | if (user_mode(regs)) { | 355 | if (user_mode(regs)) { |
354 | struct siginfo si; | 356 | struct siginfo si; |
355 | 357 | unsigned int lsb = 0; | |
356 | show_signal_msg(regs, code, address, tsk, vma); | ||
357 | 358 | ||
358 | switch (code) { | 359 | switch (code) { |
359 | case 15: /* Data TLB miss fault/Data page fault */ | 360 | case 15: /* Data TLB miss fault/Data page fault */ |
@@ -386,6 +387,30 @@ bad_area: | |||
386 | si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; | 387 | si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; |
387 | break; | 388 | break; |
388 | } | 389 | } |
390 | |||
391 | #ifdef CONFIG_MEMORY_FAILURE | ||
392 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { | ||
393 | printk(KERN_ERR | ||
394 | "MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n", | ||
395 | tsk->comm, tsk->pid, address); | ||
396 | si.si_signo = SIGBUS; | ||
397 | si.si_code = BUS_MCEERR_AR; | ||
398 | } | ||
399 | #endif | ||
400 | |||
401 | /* | ||
402 | * Either small page or large page may be poisoned. | ||
403 | * In other words, VM_FAULT_HWPOISON_LARGE and | ||
404 | * VM_FAULT_HWPOISON are mutually exclusive. | ||
405 | */ | ||
406 | if (fault & VM_FAULT_HWPOISON_LARGE) | ||
407 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | ||
408 | else if (fault & VM_FAULT_HWPOISON) | ||
409 | lsb = PAGE_SHIFT; | ||
410 | else | ||
411 | show_signal_msg(regs, code, address, tsk, vma); | ||
412 | si.si_addr_lsb = lsb; | ||
413 | |||
389 | si.si_errno = 0; | 414 | si.si_errno = 0; |
390 | si.si_addr = (void __user *) address; | 415 | si.si_addr = (void __user *) address; |
391 | force_sig_info(si.si_signo, &si, current); | 416 | force_sig_info(si.si_signo, &si, current); |