* [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE
@ 2026-02-25 16:13 Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 1/5] mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK mappings Catalin Marinas
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:13 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
This is v2 of the series extracting the common shadow stack mmap into a
separate helper for arm64, riscv and x86. Thanks for the review.
Andrew, if you are happy with this, I think taking the patches through
the mm tree makes most sense.
Minor changes since v1:
- Removed #ifdef from the helper function declaration
- Used two tabs for the alignment of multi-line function arguments
- Added "There is no functional change" to the arch patches log
- Collected ack/review/test tags
v1:
https://lore.kernel.org/r/20260224175800.2500729-1-catalin.marinas@arm.com
Catalin Marinas (5):
mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK
mappings
arm64: gcs: Use the new common vm_mmap_shadow_stack() helper
riscv: shstk: Use the new common vm_mmap_shadow_stack() helper
x86: shstk: Use the new common vm_mmap_shadow_stack() helper
mm: Do not map the shadow stack as THP
arch/arm64/mm/gcs.c | 14 +-------------
arch/riscv/kernel/usercfi.c | 12 +-----------
arch/x86/kernel/shstk.c | 12 ++----------
include/linux/mm.h | 2 ++
mm/util.c | 29 +++++++++++++++++++++++++++++
5 files changed, 35 insertions(+), 34 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/5] mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK mappings
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
@ 2026-02-25 16:13 ` Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 2/5] arm64: gcs: Use the new common vm_mmap_shadow_stack() helper Catalin Marinas
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:13 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
arm64, riscv and x86 use a similar pattern for mapping the user shadow
stack (cloned from x86). Extract this into a helper to facilitate code
reuse.
The call to do_mmap() from the new helper uses PROT_READ|PROT_WRITE prot
bits instead of the PROT_READ with an explicit VM_WRITE vm_flag. The
x86 intent was to avoid PROT_WRITE implying normal write since the
shadow stack is not writable by normal stores. However, from a kernel
perspective, the vma is writeable. Functionally there is no difference.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
include/linux/mm.h | 2 ++
mm/util.c | 25 +++++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5be3d8a8f806..61071dd72eb6 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3908,6 +3908,8 @@ extern int vm_munmap(unsigned long, size_t);
extern unsigned long __must_check vm_mmap(struct file *, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
+extern unsigned long __must_check vm_mmap_shadow_stack(unsigned long addr,
+ unsigned long len, unsigned long flags);
struct vm_unmapped_area_info {
#define VM_UNMAPPED_AREA_TOPDOWN 1
diff --git a/mm/util.c b/mm/util.c
index b05ab6f97e11..51f7f417e91f 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -618,6 +618,31 @@ unsigned long vm_mmap(struct file *file, unsigned long addr,
}
EXPORT_SYMBOL(vm_mmap);
+#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK
+/*
+ * Perform a userland memory mapping for a shadow stack into the current
+ * process address space. This is intended to be used by architectures that
+ * support user shadow stacks.
+ */
+unsigned long vm_mmap_shadow_stack(unsigned long addr, unsigned long len,
+ unsigned long flags)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long ret, unused;
+
+ flags |= MAP_ANONYMOUS | MAP_PRIVATE;
+ if (addr)
+ flags |= MAP_FIXED_NOREPLACE;
+
+ mmap_write_lock(mm);
+ ret = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE, flags,
+ VM_SHADOW_STACK, 0, &unused, NULL);
+ mmap_write_unlock(mm);
+
+ return ret;
+}
+#endif /* CONFIG_ARCH_HAS_USER_SHADOW_STACK */
+
/**
* __vmalloc_array - allocate memory for a virtually contiguous array.
* @n: number of elements.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/5] arm64: gcs: Use the new common vm_mmap_shadow_stack() helper
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 1/5] mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK mappings Catalin Marinas
@ 2026-02-25 16:13 ` Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 3/5] riscv: shstk: " Catalin Marinas
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:13 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
Replace the arm64 map_shadow_stack() content with a call to
vm_mmap_shadow_stack(). There is no functional change.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Cc: Will Deacon <will@kernel.org>
---
arch/arm64/mm/gcs.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index 04a23a497f20..680749611a9a 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -12,19 +12,7 @@
static unsigned long alloc_gcs(unsigned long addr, unsigned long size)
{
- int flags = MAP_ANONYMOUS | MAP_PRIVATE;
- struct mm_struct *mm = current->mm;
- unsigned long mapped_addr, unused;
-
- if (addr)
- flags |= MAP_FIXED_NOREPLACE;
-
- mmap_write_lock(mm);
- mapped_addr = do_mmap(NULL, addr, size, PROT_READ, flags,
- VM_SHADOW_STACK | VM_WRITE, 0, &unused, NULL);
- mmap_write_unlock(mm);
-
- return mapped_addr;
+ return vm_mmap_shadow_stack(addr, size, 0);
}
static unsigned long gcs_size(unsigned long size)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 3/5] riscv: shstk: Use the new common vm_mmap_shadow_stack() helper
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 1/5] mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK mappings Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 2/5] arm64: gcs: Use the new common vm_mmap_shadow_stack() helper Catalin Marinas
@ 2026-02-25 16:14 ` Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 4/5] x86: " Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 5/5] mm: Do not map the shadow stack as THP Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:14 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
Replace part of the allocate_shadow_stack() content with a call to
vm_mmap_shadow_stack(). There is no functional change.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
---
arch/riscv/kernel/usercfi.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
index 1adba746f164..7e57f54dc5b2 100644
--- a/arch/riscv/kernel/usercfi.c
+++ b/arch/riscv/kernel/usercfi.c
@@ -230,17 +230,7 @@ int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr)
static unsigned long allocate_shadow_stack(unsigned long addr, unsigned long size,
unsigned long token_offset, bool set_tok)
{
- int flags = MAP_ANONYMOUS | MAP_PRIVATE;
- struct mm_struct *mm = current->mm;
- unsigned long populate;
-
- if (addr)
- flags |= MAP_FIXED_NOREPLACE;
-
- mmap_write_lock(mm);
- addr = do_mmap(NULL, addr, size, PROT_READ, flags,
- VM_SHADOW_STACK | VM_WRITE, 0, &populate, NULL);
- mmap_write_unlock(mm);
+ addr = vm_mmap_shadow_stack(addr, size, 0);
if (!set_tok || IS_ERR_VALUE(addr))
goto out;
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 4/5] x86: shstk: Use the new common vm_mmap_shadow_stack() helper
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
` (2 preceding siblings ...)
2026-02-25 16:14 ` [PATCH v2 3/5] riscv: shstk: " Catalin Marinas
@ 2026-02-25 16:14 ` Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 5/5] mm: Do not map the shadow stack as THP Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:14 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
Replace part of the x86 alloc_shstk() content with a call to
vm_mmap_shadow_stack(). There is no functional change.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Tested-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
---
arch/x86/kernel/shstk.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c
index 978232b6d48d..9725e7d89b1e 100644
--- a/arch/x86/kernel/shstk.c
+++ b/arch/x86/kernel/shstk.c
@@ -100,17 +100,9 @@ static int create_rstor_token(unsigned long ssp, unsigned long *token_addr)
static unsigned long alloc_shstk(unsigned long addr, unsigned long size,
unsigned long token_offset, bool set_res_tok)
{
- int flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_ABOVE4G;
- struct mm_struct *mm = current->mm;
- unsigned long mapped_addr, unused;
+ unsigned long mapped_addr;
- if (addr)
- flags |= MAP_FIXED_NOREPLACE;
-
- mmap_write_lock(mm);
- mapped_addr = do_mmap(NULL, addr, size, PROT_READ, flags,
- VM_SHADOW_STACK | VM_WRITE, 0, &unused, NULL);
- mmap_write_unlock(mm);
+ mapped_addr = vm_mmap_shadow_stack(addr, size, MAP_ABOVE4G);
if (!set_res_tok || IS_ERR_VALUE(mapped_addr))
goto out;
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 5/5] mm: Do not map the shadow stack as THP
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
` (3 preceding siblings ...)
2026-02-25 16:14 ` [PATCH v2 4/5] x86: " Catalin Marinas
@ 2026-02-25 16:14 ` Catalin Marinas
4 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2026-02-25 16:14 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe
Cc: Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, linux-arm-kernel, linux-kernel,
linux-riscv, linux-mm
The default shadow stack size allocated on first prctl() for the main
thread or subsequently on clone() is either half of RLIMIT_STACK or half
of a thread's stack size (for arm64). Both of these are likely to be
suitable for a THP allocation and the kernel is more aggressive in
creating such mappings. However, it does not make much sense to use a
huge page. It didn't make sense for the normal stacks either, see commit
c4608d1bf7c6 ("mm: mmap: map MAP_STACK to VM_NOHUGEPAGE").
Force VM_NOHUGEPAGE when allocating/mapping the shadow stack. As per
commit 7190b3c8bd2b ("mm: mmap: map MAP_STACK to VM_NOHUGEPAGE only if
THP is enabled"), only pass this flag if TRANSPARENT_HUGEPAGE is enabled
as not to confuse CRIU tools.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
mm/util.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mm/util.c b/mm/util.c
index 51f7f417e91f..419cb81ab353 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -629,14 +629,18 @@ unsigned long vm_mmap_shadow_stack(unsigned long addr, unsigned long len,
{
struct mm_struct *mm = current->mm;
unsigned long ret, unused;
+ vm_flags_t vm_flags = VM_SHADOW_STACK;
flags |= MAP_ANONYMOUS | MAP_PRIVATE;
if (addr)
flags |= MAP_FIXED_NOREPLACE;
+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
+ vm_flags |= VM_NOHUGEPAGE;
+
mmap_write_lock(mm);
ret = do_mmap(NULL, addr, len, PROT_READ | PROT_WRITE, flags,
- VM_SHADOW_STACK, 0, &unused, NULL);
+ vm_flags, 0, &unused, NULL);
mmap_write_unlock(mm);
return ret;
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-25 16:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 1/5] mm: Introduce vm_mmap_shadow_stack() as a helper for VM_SHADOW_STACK mappings Catalin Marinas
2026-02-25 16:13 ` [PATCH v2 2/5] arm64: gcs: Use the new common vm_mmap_shadow_stack() helper Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 3/5] riscv: shstk: " Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 4/5] x86: " Catalin Marinas
2026-02-25 16:14 ` [PATCH v2 5/5] mm: Do not map the shadow stack as THP Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox