diff options
Diffstat (limited to 'mm/hugetlb.c')
| -rw-r--r-- | mm/hugetlb.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a73dbdcb89eb..0fa9de8361bd 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -2217,6 +2217,19 @@ nomem: | |||
| 2217 | return -ENOMEM; | 2217 | return -ENOMEM; |
| 2218 | } | 2218 | } |
| 2219 | 2219 | ||
| 2220 | static int is_hugetlb_entry_migration(pte_t pte) | ||
| 2221 | { | ||
| 2222 | swp_entry_t swp; | ||
| 2223 | |||
| 2224 | if (huge_pte_none(pte) || pte_present(pte)) | ||
| 2225 | return 0; | ||
| 2226 | swp = pte_to_swp_entry(pte); | ||
| 2227 | if (non_swap_entry(swp) && is_migration_entry(swp)) { | ||
| 2228 | return 1; | ||
| 2229 | } else | ||
| 2230 | return 0; | ||
| 2231 | } | ||
| 2232 | |||
| 2220 | static int is_hugetlb_entry_hwpoisoned(pte_t pte) | 2233 | static int is_hugetlb_entry_hwpoisoned(pte_t pte) |
| 2221 | { | 2234 | { |
| 2222 | swp_entry_t swp; | 2235 | swp_entry_t swp; |
| @@ -2648,7 +2661,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2648 | ptep = huge_pte_offset(mm, address); | 2661 | ptep = huge_pte_offset(mm, address); |
| 2649 | if (ptep) { | 2662 | if (ptep) { |
| 2650 | entry = huge_ptep_get(ptep); | 2663 | entry = huge_ptep_get(ptep); |
| 2651 | if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | 2664 | if (unlikely(is_hugetlb_entry_migration(entry))) { |
| 2665 | migration_entry_wait(mm, (pmd_t *)ptep, address); | ||
| 2666 | return 0; | ||
| 2667 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | ||
| 2652 | return VM_FAULT_HWPOISON; | 2668 | return VM_FAULT_HWPOISON; |
| 2653 | } | 2669 | } |
| 2654 | 2670 | ||
