From: Mike Rapoport <rppt@kernel.org>
To: Vivian Wang <wangruikang@iscas.ac.cn>
Cc: Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Alexandre Ghiti <alex@ghiti.fr>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
Vlastimil Babka <vbabka@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org
Subject: Re: [PATCH] riscv: mm: Call mark_new_valid_map() after hotplugging vmemmap
Date: Mon, 1 Jun 2026 10:13:49 +0300 [thread overview]
Message-ID: <ah0xLeD1_6oRKDkx@kernel.org> (raw)
In-Reply-To: <20260525-mark-after-vmemmap-populate-v1-1-e698d859ba16@iscas.ac.cn>
Hi,
On Mon, May 25, 2026 at 12:23:29PM +0800, Vivian Wang wrote:
> section_activate() creates new mappings in the vmemmap range without
> flushing TLB, which may cause faults on some RISC-V implementations that
> cache non-present PTEs and crashes.
>
> This seems to be most easily reproduced with DEBUG_VM=y and
> PAGE_POISONING=y, which causes these newly mapped struct pages to be
> poisoned i.e. written to immediately after mapping.
>
> Add a hook vmemmap_populate_finalize() in __populate_section_memmap(),
> and implement it as calling mark_new_valid_map() on RISC-V, which
> arranges for the exception handler to deal with these faults if they
> happen.
>
> Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
> ---
> I'm not sure if this is the right place to add this hook. I didn't add
> it to vmemmap_populate because it doesn't seem to be called in all
> cases. Please advise.
Indeed it looks like we'd need a new hook to let architectures run
post-populate actions.
The explanation that says why a new hook is needed should be a part of the
changelog.
> Depends on my earlier kfence fixes for mark_new_valid_map() [1].
>
> Found while testing AMD_HSA/ZONE_DEVICE on SpacemiT K3. Using
> ZONE_DEVICE requires another fix [2].
>
> [1]: https://lore.kernel.org/linux-riscv/20260303-handle-kfence-protect-spurious-fault-v2-0-f80d8354d79d@iscas.ac.cn
> [2]: https://lore.kernel.org/linux-riscv/20260309-riscv-sparsemem-vmemmap-limits-v1-2-f40efe18e3cd@iscas.ac.cn
> ---
> arch/riscv/mm/init.c | 6 ++++++
> include/linux/mm.h | 1 +
> mm/sparse-vmemmap.c | 6 ++++++
> 3 files changed, 13 insertions(+)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 706f43523935..cf9ae4099f82 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -1360,6 +1360,12 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> */
> return vmemmap_populate_hugepages(start, end, node, altmap);
> }
> +
> +void __meminit vmemmap_populate_finalize(void)
> +{
> + /* Avoid faults on cached non-present TLB entries. */
> + mark_new_valid_map();
> +}
> #endif
>
> #if defined(CONFIG_MMU) && defined(CONFIG_64BIT)
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 0b776907152e..65deccbd7e31 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -4882,6 +4882,7 @@ int vmemmap_populate_hugepages(unsigned long start, unsigned long end,
> int node, struct vmem_altmap *altmap);
> int vmemmap_populate(unsigned long start, unsigned long end, int node,
> struct vmem_altmap *altmap);
> +void vmemmap_populate_finalize(void);
> int vmemmap_populate_hvo(unsigned long start, unsigned long end,
> unsigned int order, struct zone *zone,
> unsigned long headsize);
> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
> index 6eadb9d116e4..2b860d2b1703 100644
> --- a/mm/sparse-vmemmap.c
> +++ b/mm/sparse-vmemmap.c
> @@ -544,6 +544,10 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
>
> #endif
>
> +void __weak __meminit vmemmap_populate_finalize(void)
> +{
> +}
> +
The existing hooks in sparse-vmemmap use #ifdef <hook> rather than __weak
functions. Take a look at vmemmap_can_optimize() and
vmemmap_populate_compound_pages().
Let's keep it consistent.
> struct page * __meminit __populate_section_memmap(unsigned long pfn,
> unsigned long nr_pages, int nid, struct vmem_altmap *altmap,
> struct dev_pagemap *pgmap)
> @@ -561,6 +565,8 @@ struct page * __meminit __populate_section_memmap(unsigned long pfn,
> else
> r = vmemmap_populate(start, end, nid, altmap);
>
> + vmemmap_populate_finalize();
> +
> if (r < 0)
> return NULL;
>
>
> ---
> base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
> change-id: 20260525-mark-after-vmemmap-populate-68bd790839c9
> prerequisite-message-id: <20260303-handle-kfence-protect-spurious-fault-v2-0-f80d8354d79d@iscas.ac.cn>
> prerequisite-patch-id: fdc42f2647e21d111f44a6532887a6705cd470a9
> prerequisite-patch-id: 096fa339c84c36643ae4311fd8362dc63e23d950
> prerequisite-patch-id: 305c876a5f4a23a840a8142aea79b796ed297545
> prerequisite-patch-id: d78cb55d6a616b1170f06a401c8fd44acd11e5d5
> prerequisite-patch-id: b02b4a76e94f3e2821291d4c23b46f6e5ecf5203
>
> Best regards,
> --
> Vivian Wang <wangruikang@iscas.ac.cn>
>
--
Sincerely yours,
Mike.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@kernel.org>
To: Vivian Wang <wangruikang@iscas.ac.cn>
Cc: Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Alexandre Ghiti <alex@ghiti.fr>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
Vlastimil Babka <vbabka@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org
Subject: Re: [PATCH] riscv: mm: Call mark_new_valid_map() after hotplugging vmemmap
Date: Mon, 1 Jun 2026 10:13:49 +0300 [thread overview]
Message-ID: <ah0xLeD1_6oRKDkx@kernel.org> (raw)
In-Reply-To: <20260525-mark-after-vmemmap-populate-v1-1-e698d859ba16@iscas.ac.cn>
Hi,
On Mon, May 25, 2026 at 12:23:29PM +0800, Vivian Wang wrote:
> section_activate() creates new mappings in the vmemmap range without
> flushing TLB, which may cause faults on some RISC-V implementations that
> cache non-present PTEs and crashes.
>
> This seems to be most easily reproduced with DEBUG_VM=y and
> PAGE_POISONING=y, which causes these newly mapped struct pages to be
> poisoned i.e. written to immediately after mapping.
>
> Add a hook vmemmap_populate_finalize() in __populate_section_memmap(),
> and implement it as calling mark_new_valid_map() on RISC-V, which
> arranges for the exception handler to deal with these faults if they
> happen.
>
> Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
> ---
> I'm not sure if this is the right place to add this hook. I didn't add
> it to vmemmap_populate because it doesn't seem to be called in all
> cases. Please advise.
Indeed it looks like we'd need a new hook to let architectures run
post-populate actions.
The explanation that says why a new hook is needed should be a part of the
changelog.
> Depends on my earlier kfence fixes for mark_new_valid_map() [1].
>
> Found while testing AMD_HSA/ZONE_DEVICE on SpacemiT K3. Using
> ZONE_DEVICE requires another fix [2].
>
> [1]: https://lore.kernel.org/linux-riscv/20260303-handle-kfence-protect-spurious-fault-v2-0-f80d8354d79d@iscas.ac.cn
> [2]: https://lore.kernel.org/linux-riscv/20260309-riscv-sparsemem-vmemmap-limits-v1-2-f40efe18e3cd@iscas.ac.cn
> ---
> arch/riscv/mm/init.c | 6 ++++++
> include/linux/mm.h | 1 +
> mm/sparse-vmemmap.c | 6 ++++++
> 3 files changed, 13 insertions(+)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 706f43523935..cf9ae4099f82 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -1360,6 +1360,12 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> */
> return vmemmap_populate_hugepages(start, end, node, altmap);
> }
> +
> +void __meminit vmemmap_populate_finalize(void)
> +{
> + /* Avoid faults on cached non-present TLB entries. */
> + mark_new_valid_map();
> +}
> #endif
>
> #if defined(CONFIG_MMU) && defined(CONFIG_64BIT)
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 0b776907152e..65deccbd7e31 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -4882,6 +4882,7 @@ int vmemmap_populate_hugepages(unsigned long start, unsigned long end,
> int node, struct vmem_altmap *altmap);
> int vmemmap_populate(unsigned long start, unsigned long end, int node,
> struct vmem_altmap *altmap);
> +void vmemmap_populate_finalize(void);
> int vmemmap_populate_hvo(unsigned long start, unsigned long end,
> unsigned int order, struct zone *zone,
> unsigned long headsize);
> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
> index 6eadb9d116e4..2b860d2b1703 100644
> --- a/mm/sparse-vmemmap.c
> +++ b/mm/sparse-vmemmap.c
> @@ -544,6 +544,10 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
>
> #endif
>
> +void __weak __meminit vmemmap_populate_finalize(void)
> +{
> +}
> +
The existing hooks in sparse-vmemmap use #ifdef <hook> rather than __weak
functions. Take a look at vmemmap_can_optimize() and
vmemmap_populate_compound_pages().
Let's keep it consistent.
> struct page * __meminit __populate_section_memmap(unsigned long pfn,
> unsigned long nr_pages, int nid, struct vmem_altmap *altmap,
> struct dev_pagemap *pgmap)
> @@ -561,6 +565,8 @@ struct page * __meminit __populate_section_memmap(unsigned long pfn,
> else
> r = vmemmap_populate(start, end, nid, altmap);
>
> + vmemmap_populate_finalize();
> +
> if (r < 0)
> return NULL;
>
>
> ---
> base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
> change-id: 20260525-mark-after-vmemmap-populate-68bd790839c9
> prerequisite-message-id: <20260303-handle-kfence-protect-spurious-fault-v2-0-f80d8354d79d@iscas.ac.cn>
> prerequisite-patch-id: fdc42f2647e21d111f44a6532887a6705cd470a9
> prerequisite-patch-id: 096fa339c84c36643ae4311fd8362dc63e23d950
> prerequisite-patch-id: 305c876a5f4a23a840a8142aea79b796ed297545
> prerequisite-patch-id: d78cb55d6a616b1170f06a401c8fd44acd11e5d5
> prerequisite-patch-id: b02b4a76e94f3e2821291d4c23b46f6e5ecf5203
>
> Best regards,
> --
> Vivian Wang <wangruikang@iscas.ac.cn>
>
--
Sincerely yours,
Mike.
next prev parent reply other threads:[~2026-06-01 7:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 4:23 [PATCH] riscv: mm: Call mark_new_valid_map() after hotplugging vmemmap Vivian Wang
2026-05-25 4:23 ` Vivian Wang
2026-06-01 7:13 ` Mike Rapoport [this message]
2026-06-01 7:13 ` Mike Rapoport
2026-06-01 8:26 ` Vivian Wang
2026-06-01 8:26 ` Vivian Wang
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=ah0xLeD1_6oRKDkx@kernel.org \
--to=rppt@kernel.org \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=david@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=wangruikang@iscas.ac.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.