]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Nov 2021 08:06:34 +0000 (09:06 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Nov 2021 08:06:34 +0000 (09:06 +0100)
added patches:
mm-filemap-check-if-thp-has-hwpoisoned-subpage-for-pmd-page-fault.patch
mm-hwpoison-remove-the-unnecessary-thp-check.patch

queue-5.10/mm-filemap-check-if-thp-has-hwpoisoned-subpage-for-pmd-page-fault.patch [new file with mode: 0644]
queue-5.10/mm-hwpoison-remove-the-unnecessary-thp-check.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/mm-filemap-check-if-thp-has-hwpoisoned-subpage-for-pmd-page-fault.patch b/queue-5.10/mm-filemap-check-if-thp-has-hwpoisoned-subpage-for-pmd-page-fault.patch
new file mode 100644 (file)
index 0000000..8190dca
--- /dev/null
@@ -0,0 +1,166 @@
+From eac96c3efdb593df1a57bb5b95dbe037bfa9a522 Mon Sep 17 00:00:00 2001
+From: Yang Shi <shy828301@gmail.com>
+Date: Thu, 28 Oct 2021 14:36:11 -0700
+Subject: mm: filemap: check if THP has hwpoisoned subpage for PMD page fault
+
+From: Yang Shi <shy828301@gmail.com>
+
+commit eac96c3efdb593df1a57bb5b95dbe037bfa9a522 upstream.
+
+When handling shmem page fault the THP with corrupted subpage could be
+PMD mapped if certain conditions are satisfied.  But kernel is supposed
+to send SIGBUS when trying to map hwpoisoned page.
+
+There are two paths which may do PMD map: fault around and regular
+fault.
+
+Before commit f9ce0be71d1f ("mm: Cleanup faultaround and finish_fault()
+codepaths") the thing was even worse in fault around path.  The THP
+could be PMD mapped as long as the VMA fits regardless what subpage is
+accessed and corrupted.  After this commit as long as head page is not
+corrupted the THP could be PMD mapped.
+
+In the regular fault path the THP could be PMD mapped as long as the
+corrupted page is not accessed and the VMA fits.
+
+This loophole could be fixed by iterating every subpage to check if any
+of them is hwpoisoned or not, but it is somewhat costly in page fault
+path.
+
+So introduce a new page flag called HasHWPoisoned on the first tail
+page.  It indicates the THP has hwpoisoned subpage(s).  It is set if any
+subpage of THP is found hwpoisoned by memory failure and after the
+refcount is bumped successfully, then cleared when the THP is freed or
+split.
+
+The soft offline path doesn't need this since soft offline handler just
+marks a subpage hwpoisoned when the subpage is migrated successfully.
+But shmem THP didn't get split then migrated at all.
+
+Link: https://lkml.kernel.org/r/20211020210755.23964-3-shy828301@gmail.com
+Fixes: 800d8c63b2e9 ("shmem: add huge pages support")
+Signed-off-by: Yang Shi <shy828301@gmail.com>
+Reviewed-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
+Suggested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/page-flags.h |   23 +++++++++++++++++++++++
+ mm/huge_memory.c           |    2 ++
+ mm/memory-failure.c        |   14 ++++++++++++++
+ mm/memory.c                |    9 +++++++++
+ mm/page_alloc.c            |    4 +++-
+ 5 files changed, 51 insertions(+), 1 deletion(-)
+
+--- a/include/linux/page-flags.h
++++ b/include/linux/page-flags.h
+@@ -169,6 +169,15 @@ enum pageflags {
+       /* Compound pages. Stored in first tail page's flags */
+       PG_double_map = PG_workingset,
++#ifdef CONFIG_MEMORY_FAILURE
++      /*
++       * Compound pages. Stored in first tail page's flags.
++       * Indicates that at least one subpage is hwpoisoned in the
++       * THP.
++       */
++      PG_has_hwpoisoned = PG_mappedtodisk,
++#endif
++
+       /* non-lru isolated movable page */
+       PG_isolated = PG_reclaim,
+@@ -701,6 +710,20 @@ PAGEFLAG_FALSE(DoubleMap)
+       TESTSCFLAG_FALSE(DoubleMap)
+ #endif
++#if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
++/*
++ * PageHasHWPoisoned indicates that at least one subpage is hwpoisoned in the
++ * compound page.
++ *
++ * This flag is set by hwpoison handler.  Cleared by THP split or free page.
++ */
++PAGEFLAG(HasHWPoisoned, has_hwpoisoned, PF_SECOND)
++      TESTSCFLAG(HasHWPoisoned, has_hwpoisoned, PF_SECOND)
++#else
++PAGEFLAG_FALSE(HasHWPoisoned)
++      TESTSCFLAG_FALSE(HasHWPoisoned)
++#endif
++
+ /*
+  * For pages that are never mapped to userspace (and aren't PageSlab),
+  * page_type may be used.  Because it is initialised to -1, we invert the
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2464,6 +2464,8 @@ static void __split_huge_page(struct pag
+               xa_lock(&swap_cache->i_pages);
+       }
++      ClearPageHasHWPoisoned(head);
++
+       for (i = nr - 1; i >= 1; i--) {
+               __split_huge_page_tail(head, i, lruvec, list);
+               /* Some pages can be beyond i_size: drop them from page cache */
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1367,6 +1367,20 @@ int memory_failure(unsigned long pfn, in
+       }
+       if (PageTransHuge(hpage)) {
++              /*
++               * The flag must be set after the refcount is bumped
++               * otherwise it may race with THP split.
++               * And the flag can't be set in get_hwpoison_page() since
++               * it is called by soft offline too and it is just called
++               * for !MF_COUNT_INCREASE.  So here seems to be the best
++               * place.
++               *
++               * Don't need care about the above error handling paths for
++               * get_hwpoison_page() since they handle either free page
++               * or unhandlable page.  The refcount is bumped iff the
++               * page is a valid handlable page.
++               */
++              SetPageHasHWPoisoned(hpage);
+               if (try_to_split_thp_page(p, "Memory Failure") < 0) {
+                       action_result(pfn, MF_MSG_UNSPLIT_THP, MF_IGNORED);
+                       return -EBUSY;
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3921,6 +3921,15 @@ vm_fault_t finish_fault(struct vm_fault
+               page = vmf->page;
+       /*
++       * Just backoff if any subpage of a THP is corrupted otherwise
++       * the corrupted page may mapped by PMD silently to escape the
++       * check.  This kind of THP just can be PTE mapped.  Access to
++       * the corrupted subpage should trigger SIGBUS as expected.
++       */
++      if (unlikely(PageHasHWPoisoned(page)))
++              return ret;
++
++      /*
+        * check even for read faults because we might have lost our CoWed
+        * page
+        */
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1232,8 +1232,10 @@ static __always_inline bool free_pages_p
+               VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
+-              if (compound)
++              if (compound) {
+                       ClearPageDoubleMap(page);
++                      ClearPageHasHWPoisoned(page);
++              }
+               for (i = 1; i < (1 << order); i++) {
+                       if (compound)
+                               bad += free_tail_pages_check(page, page + i);
diff --git a/queue-5.10/mm-hwpoison-remove-the-unnecessary-thp-check.patch b/queue-5.10/mm-hwpoison-remove-the-unnecessary-thp-check.patch
new file mode 100644 (file)
index 0000000..361af16
--- /dev/null
@@ -0,0 +1,63 @@
+From c7cb42e94473aafe553c0f2a3d8ca904599399ed Mon Sep 17 00:00:00 2001
+From: Yang Shi <shy828301@gmail.com>
+Date: Thu, 28 Oct 2021 14:36:07 -0700
+Subject: mm: hwpoison: remove the unnecessary THP check
+
+From: Yang Shi <shy828301@gmail.com>
+
+commit c7cb42e94473aafe553c0f2a3d8ca904599399ed upstream.
+
+When handling THP hwpoison checked if the THP is in allocation or free
+stage since hwpoison may mistreat it as hugetlb page.  After commit
+415c64c1453a ("mm/memory-failure: split thp earlier in memory error
+handling") the problem has been fixed, so this check is no longer
+needed.  Remove it.  The side effect of the removal is hwpoison may
+report unsplit THP instead of unknown error for shmem THP.  It seems not
+like a big deal.
+
+The following patch "mm: filemap: check if THP has hwpoisoned subpage
+for PMD page fault" depends on this, which fixes shmem THP with
+hwpoisoned subpage(s) are mapped PMD wrongly.  So this patch needs to be
+backported to -stable as well.
+
+Link: https://lkml.kernel.org/r/20211020210755.23964-2-shy828301@gmail.com
+Signed-off-by: Yang Shi <shy828301@gmail.com>
+Suggested-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
+Acked-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory-failure.c |   14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -956,20 +956,6 @@ static int get_hwpoison_page(struct page
+ {
+       struct page *head = compound_head(page);
+-      if (!PageHuge(head) && PageTransHuge(head)) {
+-              /*
+-               * Non anonymous thp exists only in allocation/free time. We
+-               * can't handle such a case correctly, so let's give it up.
+-               * This should be better than triggering BUG_ON when kernel
+-               * tries to touch the "partially handled" page.
+-               */
+-              if (!PageAnon(head)) {
+-                      pr_err("Memory failure: %#lx: non anonymous thp\n",
+-                              page_to_pfn(page));
+-                      return 0;
+-              }
+-      }
+-
+       if (get_page_unless_zero(head)) {
+               if (head == compound_head(page))
+                       return 1;
index cedac7bfc5bce013ff9406d18fab6b14de752419..eb055a5ff6653f9ec9586f1213030c2c6a088fa9 100644 (file)
@@ -1,3 +1,5 @@
 kvm-x86-avoid-warning-with-wbitwise-instead-of-logical.patch
 revert-x86-kvm-fix-vcpu-id-indexed-array-sizes.patch
 usb-ehci-handshake-cmd_run-instead-of-sts_halt.patch
+mm-hwpoison-remove-the-unnecessary-thp-check.patch
+mm-filemap-check-if-thp-has-hwpoisoned-subpage-for-pmd-page-fault.patch