All of lore.kernel.org
 help / color / mirror / Atom feed
From: "David Hildenbrand (Arm)" <david@kernel.org>
To: Longlong Xia <xialonglong2025@163.com>,
	akpm@linux-foundation.org,
	"Lorenzo Stoakes (Arm)" <ljs@kernel.org>
Cc: xu.xin16@zte.com.cn, chengming.zhou@linux.dev,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Longlong Xia <xialonglong@kylinos.cn>
Subject: Re: [PATCH 1/1] mm/ksm: validate KSM rmap items before hwpoison kill
Date: Wed, 5 Aug 2026 14:19:49 +0200	[thread overview]
Message-ID: <72f017f2-89c5-4e4a-9ce3-ab79f70b04a0@kernel.org> (raw)
In-Reply-To: <20260803151151.3472893-1-xialonglong2025@163.com>

On 8/3/26 17:11, Longlong Xia wrote:
> From: Longlong Xia <xialonglong@kylinos.cn>
> 
> 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.
> 
> Check that the saved address still belongs to the VMA and that
> page_vma_mapped_walk() still finds the poisoned page there before
> adding the task to the kill list.
> 
> Fixes: 4248d0083ec5 ("mm: ksm: support hwpoison for ksm page")
> Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
> ---
>  mm/ksm.c | 27 +++++++++++++++++++++++++--
>  1 file changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/ksm.c b/mm/ksm.c
> index 7d5b76478f0b..bc4b2dd894d8 100644
> --- a/mm/ksm.c
> +++ b/mm/ksm.c
> @@ -3222,6 +3222,27 @@ void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc)
>  }
>  
>  #ifdef CONFIG_MEMORY_FAILURE
> +static bool ksm_rmap_item_mapped(const struct page *page,
> +				 struct vm_area_struct *vma,
> +				 unsigned long addr)

Two tab indent on second parameter line

	struct vm_area_struct *vma, unsigned long addr)

> +{
> +	struct page_vma_mapped_walk pvmw = {
> +		.pfn = page_to_pfn(page),
> +		.nr_pages = 1,
> +		.vma = vma,
> +		.address = addr,
> +		.flags = PVMW_SYNC,
> +	};
> +
> +	if (addr < vma->vm_start || addr >= vma->vm_end)
> +		return false;
> +	if (!page_vma_mapped_walk(&pvmw))
> +		return false;
> +	page_vma_mapped_walk_done(&pvmw);
> +

We have page_mapped_in_vma(). So I wonder whether we can find a way to

1) Modify to just work with KSM (CCing Lorenzo)

Maybe it already does. I'm confused as so often.

Looking at the existing caller collect_procs_anon(), it's really only called
on anon folios. Could it already be called on KSM folios? What would happen
in that case? (does it just work because folio->index is still what we expect)

2) Do the following

diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index d7670ba4147bf..7eeb3c336cfe9 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -342,6 +342,27 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 }
 
 #ifdef CONFIG_MEMORY_FAILURE
+static unsigned long page_mapped_in_vma_at_address(const struct page *page,
+               struct vm_area_struct *vma, unsigned long addr)
+{
+       const struct folio *folio = page_folio(page);
+       struct page_vma_mapped_walk pvmw = {
+               .pfn = page_to_pfn(page),
+               .nr_pages = 1,
+               .vma = vma,
+               .address = addr,
+               .flags = PVMW_SYNC,
+       };
+
+       if (addr < vma->vm_start || addr >= vma->vm_end)
+               return -EFAULT;
+       if (!page_vma_mapped_walk(&pvmw))
+               return -EFAULT;
+       page_vma_mapped_walk_done(&pvmw);
+out:
+       return pvmw.address;
+}
+
 /**
  * page_mapped_in_vma - check whether a page is really mapped in a VMA
  * @page: the page to test
@@ -355,21 +376,10 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
 unsigned long page_mapped_in_vma(const struct page *page,
                struct vm_area_struct *vma)
 {
-       const struct folio *folio = page_folio(page);
-       struct page_vma_mapped_walk pvmw = {
-               .pfn = page_to_pfn(page),
-               .nr_pages = 1,
-               .vma = vma,
-               .flags = PVMW_SYNC,
-       };
+       const unsigned long addr = vma_address(vma, page_pgoff(folio, page), 1);
 
-       pvmw.address = vma_address(vma, page_pgoff(folio, page), 1);
-       if (pvmw.address == -EFAULT)
-               goto out;
-       if (!page_vma_mapped_walk(&pvmw))
+       if (addr == -EFAULT)
                return -EFAULT;
-       page_vma_mapped_walk_done(&pvmw);
-out:
-       return pvmw.address;
+       return page_mapped_in_vma_at_address(page, vma, addr);
 }
 #endif


> +	return true;
> +}
> +
>  /*
>   * Collect processes when the error hit an ksm page.
>   */
> @@ -3237,13 +3258,13 @@ void collect_procs_ksm(const struct folio *folio, const struct page *page,
>  	if (!stable_node)
>  		return;
>  	hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
> +		unsigned long addr = rmap_item->address & PAGE_MASK;

Can be const.

>  		struct anon_vma *av = rmap_item->anon_vma;
>  
>  		anon_vma_lock_read(av);
>  		rcu_read_lock();
>  		for_each_process(tsk) {
>  			struct anon_vma_chain *vmac;
> -			unsigned long addr;
>  			struct task_struct *t =
>  				task_early_kill(tsk, force_early);
>  			if (!t)
> @@ -3253,7 +3274,9 @@ void collect_procs_ksm(const struct folio *folio, const struct page *page,
>  			{
>  				vma = vmac->vma;
>  				if (vma->vm_mm == t->mm) {
> -					addr = rmap_item->address & PAGE_MASK;
> +					if (!ksm_rmap_item_mapped(page, vma,
> +								  addr))

jut put that onto a single line, please: easier to read.

> +						continue;
>  					add_to_kill_ksm(t, page, vma, to_kill,
>  							addr);
>  				}


-- 
Cheers,

David


  reply	other threads:[~2026-08-05 12:19 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-03 15:11 [PATCH 1/1] mm/ksm: validate KSM rmap items before hwpoison kill Longlong Xia
2026-08-05 12:19 ` David Hildenbrand (Arm) [this message]
2026-08-05 16:21   ` Longlong Xia
2026-08-05 16:27     ` Lorenzo Stoakes (ARM)
2026-08-05 16:29 ` [PATCH v2] " Longlong Xia
2026-08-05 16:47   ` Lorenzo Stoakes (ARM)
2026-08-06  7:48     ` Longlong Xia
2026-08-06  9:16       ` Lorenzo Stoakes (ARM)
2026-08-06  9:19         ` Longlong Xia
2026-08-06  8:35     ` David Hildenbrand (Arm)

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=72f017f2-89c5-4e4a-9ce3-ab79f70b04a0@kernel.org \
    --to=david@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=chengming.zhou@linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=xialonglong2025@163.com \
    --cc=xialonglong@kylinos.cn \
    --cc=xu.xin16@zte.com.cn \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.