diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 10:53:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 10:53:22 -0400 |
commit | db16826367fefcb0ddb93d76b66adc52eb4e6339 (patch) | |
tree | 626224c1eb1eb79c522714591f208b4fdbdcd9d4 /mm/memory.c | |
parent | cd6045138ed1bb5d8773e940d51c34318eef3ef2 (diff) | |
parent | 465fdd97cbe16ef8727221857e96ef62dd352017 (diff) |
Merge branch 'hwpoison' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6
* 'hwpoison' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6: (21 commits)
HWPOISON: Enable error_remove_page on btrfs
HWPOISON: Add simple debugfs interface to inject hwpoison on arbitary PFNs
HWPOISON: Add madvise() based injector for hardware poisoned pages v4
HWPOISON: Enable error_remove_page for NFS
HWPOISON: Enable .remove_error_page for migration aware file systems
HWPOISON: The high level memory error handler in the VM v7
HWPOISON: Add PR_MCE_KILL prctl to control early kill behaviour per process
HWPOISON: shmem: call set_page_dirty() with locked page
HWPOISON: Define a new error_remove_page address space op for async truncation
HWPOISON: Add invalidate_inode_page
HWPOISON: Refactor truncate to allow direct truncating of page v2
HWPOISON: check and isolate corrupted free pages v2
HWPOISON: Handle hardware poisoned pages in try_to_unmap
HWPOISON: Use bitmask/action code for try_to_unmap behaviour
HWPOISON: x86: Add VM_FAULT_HWPOISON handling to x86 page fault handler v2
HWPOISON: Add poison check to page fault handling
HWPOISON: Add basic support for poisoned pages in fault handler v3
HWPOISON: Add new SIGBUS error codes for hardware poison signals
HWPOISON: Add support for poison swap entries v2
HWPOISON: Export some rmap vma locking to outside world
...
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/mm/memory.c b/mm/memory.c index b1443ac07c00..987389a809e7 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1325,7 +1325,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1325 | if (ret & VM_FAULT_ERROR) { | 1325 | if (ret & VM_FAULT_ERROR) { |
1326 | if (ret & VM_FAULT_OOM) | 1326 | if (ret & VM_FAULT_OOM) |
1327 | return i ? i : -ENOMEM; | 1327 | return i ? i : -ENOMEM; |
1328 | else if (ret & VM_FAULT_SIGBUS) | 1328 | if (ret & |
1329 | (VM_FAULT_HWPOISON|VM_FAULT_SIGBUS)) | ||
1329 | return i ? i : -EFAULT; | 1330 | return i ? i : -EFAULT; |
1330 | BUG(); | 1331 | BUG(); |
1331 | } | 1332 | } |
@@ -2559,8 +2560,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2559 | goto out; | 2560 | goto out; |
2560 | 2561 | ||
2561 | entry = pte_to_swp_entry(orig_pte); | 2562 | entry = pte_to_swp_entry(orig_pte); |
2562 | if (is_migration_entry(entry)) { | 2563 | if (unlikely(non_swap_entry(entry))) { |
2563 | migration_entry_wait(mm, pmd, address); | 2564 | if (is_migration_entry(entry)) { |
2565 | migration_entry_wait(mm, pmd, address); | ||
2566 | } else if (is_hwpoison_entry(entry)) { | ||
2567 | ret = VM_FAULT_HWPOISON; | ||
2568 | } else { | ||
2569 | print_bad_pte(vma, address, orig_pte, NULL); | ||
2570 | ret = VM_FAULT_OOM; | ||
2571 | } | ||
2564 | goto out; | 2572 | goto out; |
2565 | } | 2573 | } |
2566 | delayacct_set_flag(DELAYACCT_PF_SWAPIN); | 2574 | delayacct_set_flag(DELAYACCT_PF_SWAPIN); |
@@ -2584,6 +2592,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2584 | /* Had to read the page from swap area: Major fault */ | 2592 | /* Had to read the page from swap area: Major fault */ |
2585 | ret = VM_FAULT_MAJOR; | 2593 | ret = VM_FAULT_MAJOR; |
2586 | count_vm_event(PGMAJFAULT); | 2594 | count_vm_event(PGMAJFAULT); |
2595 | } else if (PageHWPoison(page)) { | ||
2596 | ret = VM_FAULT_HWPOISON; | ||
2597 | delayacct_clear_flag(DELAYACCT_PF_SWAPIN); | ||
2598 | goto out; | ||
2587 | } | 2599 | } |
2588 | 2600 | ||
2589 | lock_page(page); | 2601 | lock_page(page); |
@@ -2760,6 +2772,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2760 | if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) | 2772 | if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) |
2761 | return ret; | 2773 | return ret; |
2762 | 2774 | ||
2775 | if (unlikely(PageHWPoison(vmf.page))) { | ||
2776 | if (ret & VM_FAULT_LOCKED) | ||
2777 | unlock_page(vmf.page); | ||
2778 | return VM_FAULT_HWPOISON; | ||
2779 | } | ||
2780 | |||
2763 | /* | 2781 | /* |
2764 | * For consistency in subsequent calls, make the faulted page always | 2782 | * For consistency in subsequent calls, make the faulted page always |
2765 | * locked. | 2783 | * locked. |