Skip to content

Commit f985fc3

Browse files
MiaoheLinakpm00
authored andcommitted
mm/swapfile: fix wrong swap entry type for hwpoisoned swapcache page
Patch series "A few fixup patches for mm", v2. This series contains a few fixup patches to fix potential unexpected return value, fix wrong swap entry type for hwpoisoned swapcache page and so on. More details can be found in the respective changelogs. This patch (of 3): Hwpoisoned dirty swap cache page is kept in the swap cache and there's simple interception code in do_swap_page() to catch it. But when trying to swapoff, unuse_pte() will wrongly install a general sense of "future accesses are invalid" swap entry for hwpoisoned swap cache page due to unaware of such type of page. The user will receive SIGBUS signal without expected BUS_MCEERR_AR payload. BTW, typo 'hwposioned' is fixed. Link: https://lkml.kernel.org/r/20230727115643.639741-1-linmiaohe@huawei.com Link: https://lkml.kernel.org/r/20230727115643.639741-2-linmiaohe@huawei.com Fixes: 6b97059 ("mm: hwpoison: support recovery from ksm_might_need_to_copy()") Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> Cc: Kefeng Wang <wangkefeng.wang@huawei.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Naoya Horiguchi <naoya.horiguchi@nec.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent cac7ea5 commit f985fc3

2 files changed

Lines changed: 6 additions & 4 deletions

File tree

mm/ksm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2784,6 +2784,8 @@ struct page *ksm_might_need_to_copy(struct page *page,
27842784
anon_vma->root == vma->anon_vma->root) {
27852785
return page; /* still no need to copy it */
27862786
}
2787+
if (PageHWPoison(page))
2788+
return ERR_PTR(-EHWPOISON);
27872789
if (!PageUptodate(page))
27882790
return page; /* let do_swap_page report the error */
27892791

mm/swapfile.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,15 +1746,15 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
17461746
struct page *swapcache;
17471747
spinlock_t *ptl;
17481748
pte_t *pte, new_pte, old_pte;
1749-
bool hwposioned = false;
1749+
bool hwpoisoned = PageHWPoison(page);
17501750
int ret = 1;
17511751

17521752
swapcache = page;
17531753
page = ksm_might_need_to_copy(page, vma, addr);
17541754
if (unlikely(!page))
17551755
return -ENOMEM;
17561756
else if (unlikely(PTR_ERR(page) == -EHWPOISON))
1757-
hwposioned = true;
1757+
hwpoisoned = true;
17581758

17591759
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
17601760
if (unlikely(!pte || !pte_same_as_swp(ptep_get(pte),
@@ -1765,11 +1765,11 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
17651765

17661766
old_pte = ptep_get(pte);
17671767

1768-
if (unlikely(hwposioned || !PageUptodate(page))) {
1768+
if (unlikely(hwpoisoned || !PageUptodate(page))) {
17691769
swp_entry_t swp_entry;
17701770

17711771
dec_mm_counter(vma->vm_mm, MM_SWAPENTS);
1772-
if (hwposioned) {
1772+
if (hwpoisoned) {
17731773
swp_entry = make_hwpoison_entry(swapcache);
17741774
page = swapcache;
17751775
} else {

0 commit comments

Comments
 (0)