aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-09-16 05:50:06 -0400
committerAndi Kleen <ak@linux.intel.com>2009-09-16 05:50:06 -0400
commitd1737fdbec7f90edc52dd0c5c3767457f28e78d8 (patch)
tree8699aabdff713a70665a9f60106ce21012376733 /mm
parentad5fa913991e9e0f122b021e882b0d50051fbdbc (diff)
HWPOISON: Add basic support for poisoned pages in fault handler v3
- Add a new VM_FAULT_HWPOISON error code to handle_mm_fault. Right now architectures have to explicitely enable poison page support, so this is forward compatible to all architectures. They only need to add it when they enable poison page support. - Add poison page handling in swap in fault code v2: Add missing delayacct_clear_flag (Hidehiro Kawai) v3: Really use delayacct_clear_flag (Hidehiro Kawai) Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/mm/memory.c b/mm/memory.c
index aede2ce3aba4..02bae2d540d4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1319,7 +1319,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1319 if (ret & VM_FAULT_ERROR) { 1319 if (ret & VM_FAULT_ERROR) {
1320 if (ret & VM_FAULT_OOM) 1320 if (ret & VM_FAULT_OOM)
1321 return i ? i : -ENOMEM; 1321 return i ? i : -ENOMEM;
1322 else if (ret & VM_FAULT_SIGBUS) 1322 if (ret &
1323 (VM_FAULT_HWPOISON|VM_FAULT_SIGBUS))
1323 return i ? i : -EFAULT; 1324 return i ? i : -EFAULT;
1324 BUG(); 1325 BUG();
1325 } 1326 }
@@ -2511,8 +2512,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2511 goto out; 2512 goto out;
2512 2513
2513 entry = pte_to_swp_entry(orig_pte); 2514 entry = pte_to_swp_entry(orig_pte);
2514 if (is_migration_entry(entry)) { 2515 if (unlikely(non_swap_entry(entry))) {
2515 migration_entry_wait(mm, pmd, address); 2516 if (is_migration_entry(entry)) {
2517 migration_entry_wait(mm, pmd, address);
2518 } else if (is_hwpoison_entry(entry)) {
2519 ret = VM_FAULT_HWPOISON;
2520 } else {
2521 print_bad_pte(vma, address, orig_pte, NULL);
2522 ret = VM_FAULT_OOM;
2523 }
2516 goto out; 2524 goto out;
2517 } 2525 }
2518 delayacct_set_flag(DELAYACCT_PF_SWAPIN); 2526 delayacct_set_flag(DELAYACCT_PF_SWAPIN);
@@ -2536,6 +2544,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2536 /* Had to read the page from swap area: Major fault */ 2544 /* Had to read the page from swap area: Major fault */
2537 ret = VM_FAULT_MAJOR; 2545 ret = VM_FAULT_MAJOR;
2538 count_vm_event(PGMAJFAULT); 2546 count_vm_event(PGMAJFAULT);
2547 } else if (PageHWPoison(page)) {
2548 ret = VM_FAULT_HWPOISON;
2549 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
2550 goto out;
2539 } 2551 }
2540 2552
2541 lock_page(page); 2553 lock_page(page);