Commit d1737fdbec7f90edc52dd0c5c3767457f28e78d8
Committed by
Andi Kleen
1 parent
ad5fa91399
Exists in
master
and in
4 other branches
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>
Showing 2 changed files with 17 additions and 4 deletions Side-by-side Diff
include/linux/mm.h
... | ... | @@ -685,11 +685,12 @@ |
685 | 685 | #define VM_FAULT_SIGBUS 0x0002 |
686 | 686 | #define VM_FAULT_MAJOR 0x0004 |
687 | 687 | #define VM_FAULT_WRITE 0x0008 /* Special case for get_user_pages */ |
688 | +#define VM_FAULT_HWPOISON 0x0010 /* Hit poisoned page */ | |
688 | 689 | |
689 | 690 | #define VM_FAULT_NOPAGE 0x0100 /* ->fault installed the pte, not return page */ |
690 | 691 | #define VM_FAULT_LOCKED 0x0200 /* ->fault locked the returned page */ |
691 | 692 | |
692 | -#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS) | |
693 | +#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_HWPOISON) | |
693 | 694 | |
694 | 695 | /* |
695 | 696 | * Can be called by the pagefault handler when it gets a VM_FAULT_OOM. |
mm/memory.c
... | ... | @@ -1319,7 +1319,8 @@ |
1319 | 1319 | if (ret & VM_FAULT_ERROR) { |
1320 | 1320 | if (ret & VM_FAULT_OOM) |
1321 | 1321 | return i ? i : -ENOMEM; |
1322 | - else if (ret & VM_FAULT_SIGBUS) | |
1322 | + if (ret & | |
1323 | + (VM_FAULT_HWPOISON|VM_FAULT_SIGBUS)) | |
1323 | 1324 | return i ? i : -EFAULT; |
1324 | 1325 | BUG(); |
1325 | 1326 | } |
... | ... | @@ -2511,8 +2512,15 @@ |
2511 | 2512 | goto out; |
2512 | 2513 | |
2513 | 2514 | entry = pte_to_swp_entry(orig_pte); |
2514 | - if (is_migration_entry(entry)) { | |
2515 | - migration_entry_wait(mm, pmd, address); | |
2515 | + if (unlikely(non_swap_entry(entry))) { | |
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 | 2524 | goto out; |
2517 | 2525 | } |
2518 | 2526 | delayacct_set_flag(DELAYACCT_PF_SWAPIN); |
... | ... | @@ -2536,6 +2544,10 @@ |
2536 | 2544 | /* Had to read the page from swap area: Major fault */ |
2537 | 2545 | ret = VM_FAULT_MAJOR; |
2538 | 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 | 2553 | lock_page(page); |