From nobody Fri Oct 2 02:32:14 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C54635C19D for ; Wed, 5 Aug 2026 16:30:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785947427; cv=none; b=e7lhMlDWD1qh85M6Aqo5yHs/Izs3hXVM7eXXdatQ7e7qtMIUTzD43fyzfUWmyurVNSp9oZtMcgUYAHLKOIWeK4+pHhTY6lUIvtiyWDY8S53uKYQ6joBuADQuPBYpmoWYxDOVQOJyjaVTMPCi7U846R7VwfCsHCP22P3ueQxXoqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785947427; c=relaxed/simple; bh=OSTv1El8WVRVrR02buFuKX8QJBEEhs5/ASk4nett3pc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=vBLJRECV2MDAjWnOUc1A/FJWpQcAQqnPPGRPhX6iJEyFmNtEInJHHf/RmZLCOateBvTuVdH6e8qvZqXdxTot3jU4RFkSWzEb6p5klzaDSPVEJkh7KTacE2tTlLhUsnCFJrhhjA/8lms2MSCzy3w//Db7xErQYy+TlQwB5WCE4zs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=GKySmNby; arc=none smtp.client-ip=220.197.31.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="GKySmNby" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=ng QccyP8H4V8ozRsqq5pX92pyP8jrNPIZDv0jYhOODE=; b=GKySmNbyu3HTEwuTA6 xnvhEJhbicGxSoRripWkRC9JkyzXEey5OYOQvhrNZh8pJKcm2Wr1QxHy8NIXVw5P dS5IaqAgxGgB4CF46lDsfXw+6bg94Bgi39JAzWuFJ1qLyceYKv78HfBXLr+ALgGK 4H8CD1UcsGHegfOr4BNU3G/9I= Received: from XLL-9950X.localdomain (unknown []) by gzga-smtp-mtada-g0-2 (Coremail) with SMTP id _____wA3PsvyZHNq3_HpNQ--.23754S2; Thu, 06 Aug 2026 00:29:39 +0800 (CST) From: Longlong Xia To: akpm@linux-foundation.org, ljs@kernel.org Cc: david@kernel.org, xu.xin16@zte.com.cn, chengming.zhou@linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, xialonglong@kylinos.cn Subject: [PATCH v2] mm/ksm: validate KSM rmap items before hwpoison kill Date: Thu, 6 Aug 2026 00:29:37 +0800 Message-ID: <20260805162937.1795310-1-xialonglong2025@163.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803151151.3472893-1-xialonglong2025@163.com> References: <20260803151151.3472893-1-xialonglong2025@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wA3PsvyZHNq3_HpNQ--.23754S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxArW7GFW5tw45Gr4kJw1DZFb_yoWrZF15pa n5Gas5JrW8tw1a9r9rXw4q9r15Zwn5Ja1jyF4xAa4a93WYqw43AF4UJ3Z3Zay5Ka48Ja93 tw42vr45CFyUJrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07j53ktUUUUU= X-CM-SenderInfo: x0ldz0pqjo00rjsqjki6rwjhhfrp/xtbC9xPMxWpzZPPpcwAA35 Content-Type: text/plain; charset="utf-8" From: Longlong Xia collect_procs_ksm() walks the stable-node rmap list and queues an early kill for every task whose mm appears on the anon_vma chain. That rmap item can be stale by the time memory failure handles the poisoned KSM page. A VMA may have been split, unmapped or remapped after the rmap item was recorded, so matching only vma->vm_mm can send SIGBUS with an address that no longer maps the poisoned page. Factor page_mapped_in_vma_at_address() out of page_mapped_in_vma() so callers that already know the virtual address can validate it directly. This avoids deriving the address from page_pgoff(), which is invalid for KSM pages. Use the address saved in the KSM rmap item to check that it still belongs to the VMA and that page_vma_mapped_walk() still finds the poisoned page before adding the task to the kill list. Fixes: 4248d0083ec5 ("mm: ksm: support hwpoison for ksm page") Suggested-by: David Hildenbrand (Arm) Signed-off-by: Longlong Xia --- mm/internal.h | 2 ++ mm/ksm.c | 10 +++++++--- mm/page_vma_mapped.c | 36 +++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 181e79f1d6a2..4c9e601b2d95 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1424,6 +1424,8 @@ void add_to_kill_ksm(struct task_struct *tsk, const s= truct page *p, unsigned long ksm_addr); unsigned long page_mapped_in_vma(const struct page *page, struct vm_area_struct *vma); +unsigned long page_mapped_in_vma_at_address(const struct page *page, + struct vm_area_struct *vma, unsigned long addr); =20 #else static inline int unmap_poisoned_folio(struct folio *folio, unsigned long = pfn, bool must_kill) diff --git a/mm/ksm.c b/mm/ksm.c index 7d5b76478f0b..5104e442fcb2 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -3237,13 +3237,13 @@ void collect_procs_ksm(const struct folio *folio, c= onst struct page *page, if (!stable_node) return; hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) { + const unsigned long addr =3D rmap_item->address & PAGE_MASK; struct anon_vma *av =3D rmap_item->anon_vma; =20 anon_vma_lock_read(av); rcu_read_lock(); for_each_process(tsk) { struct anon_vma_chain *vmac; - unsigned long addr; struct task_struct *t =3D task_early_kill(tsk, force_early); if (!t) @@ -3253,9 +3253,13 @@ void collect_procs_ksm(const struct folio *folio, co= nst struct page *page, { vma =3D vmac->vma; if (vma->vm_mm =3D=3D t->mm) { - addr =3D rmap_item->address & PAGE_MASK; + const unsigned long mapped_addr =3D + page_mapped_in_vma_at_address(page, vma, addr); + + if (mapped_addr =3D=3D -EFAULT) + continue; add_to_kill_ksm(t, page, vma, to_kill, - addr); + mapped_addr); } } } diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c index bac2eb5de63d..f7c5dc9248bc 100644 --- a/mm/page_vma_mapped.c +++ b/mm/page_vma_mapped.c @@ -336,6 +336,26 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk = *pvmw) } =20 #ifdef CONFIG_MEMORY_FAILURE +unsigned long page_mapped_in_vma_at_address(const struct page *page, + struct vm_area_struct *vma, unsigned long addr) +{ + struct page_vma_mapped_walk pvmw =3D { + .pfn =3D page_to_pfn(page), + .nr_pages =3D 1, + .vma =3D vma, + .address =3D addr, + .flags =3D PVMW_SYNC, + }; + + if (addr < vma->vm_start || addr >=3D vma->vm_end) + return -EFAULT; + if (!page_vma_mapped_walk(&pvmw)) + return -EFAULT; + page_vma_mapped_walk_done(&pvmw); + + return pvmw.address; +} + /** * page_mapped_in_vma - check whether a page is really mapped in a VMA * @page: the page to test @@ -350,20 +370,10 @@ unsigned long page_mapped_in_vma(const struct page *p= age, struct vm_area_struct *vma) { const struct folio *folio =3D page_folio(page); - struct page_vma_mapped_walk pvmw =3D { - .pfn =3D page_to_pfn(page), - .nr_pages =3D 1, - .vma =3D vma, - .flags =3D PVMW_SYNC, - }; + const unsigned long addr =3D vma_address(vma, page_pgoff(folio, page), 1); =20 - pvmw.address =3D vma_address(vma, page_pgoff(folio, page), 1); - if (pvmw.address =3D=3D -EFAULT) - goto out; - if (!page_vma_mapped_walk(&pvmw)) + if (addr =3D=3D -EFAULT) return -EFAULT; - page_vma_mapped_walk_done(&pvmw); -out: - return pvmw.address; + return page_mapped_in_vma_at_address(page, vma, addr); } #endif --=20 2.43.0