mm/memory-failure: teach kill_accessing_process to accept hugetlb tail page pfn

When a hugetlb folio is being poisoned again, try_memory_failure_hugetlb()
passed head pfn to kill_accessing_process(), that is not right. The
precise pfn of the poisoned page should be used in order to determine the
precise vaddr as the SIGBUS payload.

This issue has already been taken care of in the normal path, that is,
hwpoison_user_mappings(), see [1][2]. Further more, for [3] to work
correctly in the hugetlb repoisoning case, it's essential to inform VM the
precise poisoned page, not the head page.

[1] https://lkml.kernel.org/r/20231218135837.3310403-1-willy@infradead.org
[2] https://lkml.kernel.org/r/20250224211445.2663312-1-jane.chu@oracle.com
[3] https://lore.kernel.org/lkml/20251116013223.1557158-1-jiaqiyan@google.com/

Link: https://lkml.kernel.org/r/20260120232234.3462258-2-jane.chu@oracle.com
Signed-off-by: Jane Chu <jane.chu@oracle.com>
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Acked-by: Miaohe Lin <linmiaohe@huawei.com>
Cc: Chris Mason <clm@meta.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Jiaqi Yan <jiaqiyan@google.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: William Roche <william.roche@oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Jane Chu and committed by
Andrew Morton
057a6f26 a148a204

+8 -6
+8 -6
mm/memory-failure.c
··· 692 692 unsigned long poisoned_pfn, struct to_kill *tk) 693 693 { 694 694 unsigned long pfn = 0; 695 + unsigned long hwpoison_vaddr; 696 + unsigned long mask; 695 697 696 698 if (pte_present(pte)) { 697 699 pfn = pte_pfn(pte); ··· 704 702 pfn = softleaf_to_pfn(entry); 705 703 } 706 704 707 - if (!pfn || pfn != poisoned_pfn) 705 + mask = ~((1UL << (shift - PAGE_SHIFT)) - 1); 706 + if (!pfn || pfn != (poisoned_pfn & mask)) 708 707 return 0; 709 708 710 - set_to_kill(tk, addr, shift); 709 + hwpoison_vaddr = addr + ((poisoned_pfn - pfn) << PAGE_SHIFT); 710 + set_to_kill(tk, hwpoison_vaddr, shift); 711 711 return 1; 712 712 } 713 713 ··· 2056 2052 case MF_HUGETLB_FOLIO_PRE_POISONED: 2057 2053 case MF_HUGETLB_PAGE_PRE_POISONED: 2058 2054 rv = -EHWPOISON; 2059 - if (flags & MF_ACTION_REQUIRED) { 2060 - folio = page_folio(p); 2061 - rv = kill_accessing_process(current, folio_pfn(folio), flags); 2062 - } 2055 + if (flags & MF_ACTION_REQUIRED) 2056 + rv = kill_accessing_process(current, pfn, flags); 2063 2057 if (res == MF_HUGETLB_PAGE_PRE_POISONED) 2064 2058 action_result(pfn, MF_MSG_ALREADY_POISONED, MF_FAILED); 2065 2059 else