From: Matthew Wilcox <willy@infradead.org>
To: Andrew Morton <akpm@linux-foundation.org>,
Jane Chu <jane.chu@oracle.com>,
linux-mm@kvack.org
Cc: Muchun Song <muchun.song@linux.dev>,
Oscar Salvador <osalvador@suse.de>,
David Hildenbrand <david@kernel.org>,
Miaohe Lin <linmiaohe@huawei.com>,
Naoya Horiguchi <nao.horiguchi@gmail.com>,
Jan Kara <jack@suse.cz>,
linux-fsdevel@vger.kernel.org,
Christian Brauner <christian@brauner.io>,
Jiaqi Yan <jiaqiyan@google.com>,
stable@vger.kernel.org, Naoya Horiguchi <naoya.horiguchi@nec.com>
Subject: Re: [PATCH v4 01/14] memory-failure: Fix hardware poison check in unpoison_memory() again
Date: Fri, 24 Jul 2026 13:32:22 +0100 [thread overview]
Message-ID: <amNbVpvrxRBbuGoi@casper.infradead.org> (raw)
In-Reply-To: <20260723143034.175661-2-willy@infradead.org>
Sashiko feedback:
> --- Patch [1]: [PATCH v4 01/14] memory-failure: Fix hardware poison check in unpoison_memory() again ---
> commit 5a43cce770d0c716bb5c78ee2c21e1cb711e5331
> Author: Matthew Wilcox (Oracle) <willy@infradead.org>
>
> memory-failure: Fix hardware poison check in unpoison_memory() again
>
> This commit addresses a bug in unpoison_memory() for hugetlb folios. It uses
> is_page_hwpoison() instead of checking the head page, and correctly targets
> the precise page for clearing the HWPoison flag.
>
> > diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> > index 51508a55c4055..944e6e1d49719 100644
> > --- a/mm/memory-failure.c
> > +++ b/mm/memory-failure.c
> > @@ -2695,8 +2695,8 @@ int unpoison_memory(unsigned long pfn)
> > goto unlock_mutex;
> > }
> >
> > - if (!PageHWPoison(p)) {
> > - unpoison_pr_info("%#lx: page was already unpoisoned\n",
> > + if (!is_page_hwpoison(p)) {
> > + unpoison_pr_info("%#lx: page is not poisoned\n",
> > pfn, &unpoison_rs);
> > goto unlock_mutex;
> > }
>
> This isn't a bug introduced by this patch, but can the speculative folio
> access without stabilization cause a use-after-free and reference leak?
>
> Looking at unpoison_memory(), if the PFN belongs to a THP tail page and
> the THP is concurrently split, could the folio pointer refer to a stale
> head page?
>
> unpoison_memory() {
> ...
> folio = page_folio(p);
> ...
> ghp = get_hwpoison_page(p, MF_UNPOISON);
> ...
> folio_put(folio);
> }
>
> Since get_hwpoison_page() takes a reference on the new order-0 page, does
> calling folio_put() on the stale head page drop the wrong reference and leak
> the reference on the order-0 page?
Uh. I don't know. If it does, I didn't make this problem _worse_,
so I'm not going to address it.
> This is a pre-existing issue, but does unpoison_memory() clear the
> PG_hwpoison flag on the wrong page for unsplit THPs?
>
> For THP tail pages, if get_hwpoison_page() returns 0 because their
> _refcount is 0, does the code fall into the !ghp branch and call
> folio_test_clear_hwpoison(folio)?
>
> Because PF_HEAD redirects to the head page, this clears the flag on the
> head page. Since THPs set PG_hwpoison on the exact corrupted tail page
> (PF_ANY), does the tail page remain poisoned and fail to restore?
Hm. Maybe? This code probably needs to be more careful in general.
> [ ... ]
>
> > @@ -2748,6 +2748,7 @@ int unpoison_memory(unsigned long pfn)
> > folio_put(folio);
> > goto unlock_mutex;
> > }
> > + p = &folio->page;
> > }
> >
> > folio_put(folio);
>
> This is a pre-existing issue, but does unpoison_memory() fail to clear
> the per-folio PG_has_hwpoisoned flag when unpoisoning THPs?
>
> When successfully unpoisoning a THP head page (where get_hwpoison_page
> succeeds), TestClearPageHWPoison() clears the per-page PG_hwpoison flag.
>
> However, since the per-folio fast-indicator PG_has_hwpoisoned is never
> cleared, will folio_contain_hwpoisoned_page() continue to return true,
> causing the kernel to erroneously treat the unpoisoned THP as poisoned in
> future operations?
Yes, it does fail to clear the has_hwpoisoned flag. We can have more
than one HWPoison page in a folio, so we either have to leave it set,
or scan all pages in the folio to know that it's safe to clear.
Again, I'm not making this worse for THP in this series, so I'm
not addressing it. For hugetlb pages, later on I change to use the
has_hwpoisoned flag, and that does get cleared because there's no scan
of page bits involved, just a list of poisoned pages, and it's easy to
check when that's empty.
It's mostly moot because we always try to split large folios that aren't
THP, and that usually succeeds. So all the large folio has_hwpoisoned
paths are very undertested.
next prev parent reply other threads:[~2026-07-24 12:32 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 14:30 [PATCH v4 00/14] Use generic_file_read_iter() in hugetlbfs Matthew Wilcox (Oracle)
2026-07-23 14:30 ` [PATCH v4 01/14] memory-failure: Fix hardware poison check in unpoison_memory() again Matthew Wilcox (Oracle)
2026-07-24 12:32 ` Matthew Wilcox [this message]
2026-07-23 14:30 ` [PATCH v4 02/14] memory-failure: Test the page is hwpoison before taking the mutex Matthew Wilcox (Oracle)
2026-07-24 12:34 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 03/14] mm: Rename folio_contain_hwpoison_page() to folio_has_hwpoison_page() Matthew Wilcox (Oracle)
2026-07-24 12:36 ` Matthew Wilcox
2026-07-24 12:52 ` Michael S. Tsirkin
2026-07-24 13:24 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 04/14] hugetlb: Mark some function arguments as const Matthew Wilcox (Oracle)
2026-07-24 12:38 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 05/14] guest_memfd: Use folio_has_hwpoisoned_page() Matthew Wilcox (Oracle)
2026-07-24 12:44 ` Matthew Wilcox
2026-07-24 15:16 ` Sean Christopherson
2026-07-24 16:51 ` Ackerley Tng
2026-07-24 15:16 ` Sean Christopherson
2026-07-24 16:40 ` Ackerley Tng
2026-07-23 14:30 ` [PATCH v4 06/14] memory-failure: Remove raw_hwp_list_head() Matthew Wilcox (Oracle)
2026-07-24 12:45 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 07/14] hugetlb: Use the has_hwpoisoned flag Matthew Wilcox (Oracle)
2026-07-24 13:21 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 08/14] mm: Remove locking mf_mutex in is_raw_hwpoison_page_in_hugepage() Matthew Wilcox (Oracle)
2026-07-24 13:41 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 09/14] mm: Check individual hugetlb pages for poison Matthew Wilcox (Oracle)
2026-07-24 14:00 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 10/14] filemap: Add hwpoison handling to filemap_read() Matthew Wilcox (Oracle)
2026-07-24 16:06 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 11/14] filemap: Remove checks in mapping_set_folio_order_range() Matthew Wilcox (Oracle)
2026-07-24 16:08 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 12/14] hugetlb: Set mapping folio order Matthew Wilcox (Oracle)
2026-07-24 16:16 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 13/14] filemap: Add support for authoritative mappings Matthew Wilcox (Oracle)
2026-07-24 16:15 ` Matthew Wilcox
2026-07-24 16:29 ` Matthew Wilcox
2026-07-23 14:30 ` [PATCH v4 14/14] hugetlb: replace hugetlbfs_read_iter() with generic_file_read_iter() Matthew Wilcox (Oracle)
2026-07-24 16:36 ` Matthew Wilcox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=amNbVpvrxRBbuGoi@casper.infradead.org \
--to=willy@infradead.org \
--cc=akpm@linux-foundation.org \
--cc=christian@brauner.io \
--cc=david@kernel.org \
--cc=jack@suse.cz \
--cc=jane.chu@oracle.com \
--cc=jiaqiyan@google.com \
--cc=linmiaohe@huawei.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=muchun.song@linux.dev \
--cc=nao.horiguchi@gmail.com \
--cc=naoya.horiguchi@nec.com \
--cc=osalvador@suse.de \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox