|
34 | 34 | #include <linux/nospec.h> |
35 | 35 | #include <linux/delayacct.h> |
36 | 36 | #include <linux/memory.h> |
| 37 | +#include <linux/mm_inline.h> |
37 | 38 |
|
38 | 39 | #include <asm/page.h> |
39 | 40 | #include <asm/pgalloc.h> |
@@ -5101,15 +5102,12 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, |
5101 | 5102 | entry = huge_pte_clear_uffd_wp(entry); |
5102 | 5103 | set_huge_pte_at(dst, addr, dst_pte, entry); |
5103 | 5104 | } else if (unlikely(is_pte_marker(entry))) { |
5104 | | - /* No swap on hugetlb */ |
5105 | | - WARN_ON_ONCE( |
5106 | | - is_swapin_error_entry(pte_to_swp_entry(entry))); |
5107 | | - /* |
5108 | | - * We copy the pte marker only if the dst vma has |
5109 | | - * uffd-wp enabled. |
5110 | | - */ |
5111 | | - if (userfaultfd_wp(dst_vma)) |
5112 | | - set_huge_pte_at(dst, addr, dst_pte, entry); |
| 5105 | + pte_marker marker = copy_pte_marker( |
| 5106 | + pte_to_swp_entry(entry), dst_vma); |
| 5107 | + |
| 5108 | + if (marker) |
| 5109 | + set_huge_pte_at(dst, addr, dst_pte, |
| 5110 | + make_pte_marker(marker)); |
5113 | 5111 | } else { |
5114 | 5112 | entry = huge_ptep_get(src_pte); |
5115 | 5113 | pte_folio = page_folio(pte_page(entry)); |
@@ -6089,14 +6087,26 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, |
6089 | 6087 | } |
6090 | 6088 |
|
6091 | 6089 | entry = huge_ptep_get(ptep); |
6092 | | - /* PTE markers should be handled the same way as none pte */ |
6093 | | - if (huge_pte_none_mostly(entry)) |
| 6090 | + if (huge_pte_none_mostly(entry)) { |
| 6091 | + if (is_pte_marker(entry)) { |
| 6092 | + pte_marker marker = |
| 6093 | + pte_marker_get(pte_to_swp_entry(entry)); |
| 6094 | + |
| 6095 | + if (marker & PTE_MARKER_POISONED) { |
| 6096 | + ret = VM_FAULT_HWPOISON_LARGE; |
| 6097 | + goto out_mutex; |
| 6098 | + } |
| 6099 | + } |
| 6100 | + |
6094 | 6101 | /* |
| 6102 | + * Other PTE markers should be handled the same way as none PTE. |
| 6103 | + * |
6095 | 6104 | * hugetlb_no_page will drop vma lock and hugetlb fault |
6096 | 6105 | * mutex internally, which make us return immediately. |
6097 | 6106 | */ |
6098 | 6107 | return hugetlb_no_page(mm, vma, mapping, idx, address, ptep, |
6099 | 6108 | entry, flags); |
| 6109 | + } |
6100 | 6110 |
|
6101 | 6111 | ret = 0; |
6102 | 6112 |
|
|
0 commit comments