aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/mm/memory.c b/mm/memory.c
index ebcd3decac89..7e91b5f9f690 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1326,7 +1326,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1326 if (ret & VM_FAULT_ERROR) { 1326 if (ret & VM_FAULT_ERROR) {
1327 if (ret & VM_FAULT_OOM) 1327 if (ret & VM_FAULT_OOM)
1328 return i ? i : -ENOMEM; 1328 return i ? i : -ENOMEM;
1329 else if (ret & VM_FAULT_SIGBUS) 1329 if (ret &
1330 (VM_FAULT_HWPOISON|VM_FAULT_SIGBUS))
1330 return i ? i : -EFAULT; 1331 return i ? i : -EFAULT;
1331 BUG(); 1332 BUG();
1332 } 1333 }
@@ -2503,8 +2504,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2503 goto out; 2504 goto out;
2504 2505
2505 entry = pte_to_swp_entry(orig_pte); 2506 entry = pte_to_swp_entry(orig_pte);
2506 if (is_migration_entry(entry)) { 2507 if (unlikely(non_swap_entry(entry))) {
2507 migration_entry_wait(mm, pmd, address); 2508 if (is_migration_entry(entry)) {
2509 migration_entry_wait(mm, pmd, address);
2510 } else if (is_hwpoison_entry(entry)) {
2511 ret = VM_FAULT_HWPOISON;
2512 } else {
2513 print_bad_pte(vma, address, orig_pte, NULL);
2514 ret = VM_FAULT_OOM;
2515 }
2508 goto out; 2516 goto out;
2509 } 2517 }
2510 delayacct_set_flag(DELAYACCT_PF_SWAPIN); 2518 delayacct_set_flag(DELAYACCT_PF_SWAPIN);
@@ -2528,6 +2536,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2528 /* Had to read the page from swap area: Major fault */ 2536 /* Had to read the page from swap area: Major fault */
2529 ret = VM_FAULT_MAJOR; 2537 ret = VM_FAULT_MAJOR;
2530 count_vm_event(PGMAJFAULT); 2538 count_vm_event(PGMAJFAULT);
2539 } else if (PageHWPoison(page)) {
2540 ret = VM_FAULT_HWPOISON;
2541 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
2542 goto out;
2531 } 2543 }
2532 2544
2533 lock_page(page); 2545 lock_page(page);
@@ -2704,6 +2716,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2704 if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) 2716 if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE)))
2705 return ret; 2717 return ret;
2706 2718
2719 if (unlikely(PageHWPoison(vmf.page))) {
2720 if (ret & VM_FAULT_LOCKED)
2721 unlock_page(vmf.page);
2722 return VM_FAULT_HWPOISON;
2723 }
2724
2707 /* 2725 /*
2708 * For consistency in subsequent calls, make the faulted page always 2726 * For consistency in subsequent calls, make the faulted page always
2709 * locked. 2727 * locked.