|
@@ -2961,7 +2961,17 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (absent ||
|
|
|
+ /*
|
|
|
+ * We need call hugetlb_fault for both hugepages under migration
|
|
|
+ * (in which case hugetlb_fault waits for the migration,) and
|
|
|
+ * hwpoisoned hugepages (in which case we need to prevent the
|
|
|
+ * caller from accessing to them.) In order to do this, we use
|
|
|
+ * here is_swap_pte instead of is_hugetlb_entry_migration and
|
|
|
+ * is_hugetlb_entry_hwpoisoned. This is because it simply covers
|
|
|
+ * both cases, and because we can't follow correct pages
|
|
|
+ * directly from any kind of swap entries.
|
|
|
+ */
|
|
|
+ if (absent || is_swap_pte(huge_ptep_get(pte)) ||
|
|
|
((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) {
|
|
|
int ret;
|
|
|
|