* [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
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ 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] 7+ 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
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ 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] 7+ 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
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ 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] 7+ 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
2026-02-25 20:12 ` [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Mike Rapoport
5 siblings, 0 replies; 7+ 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] 7+ 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
2026-02-25 20:12 ` [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Mike Rapoport
5 siblings, 0 replies; 7+ 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] 7+ messages in thread* Re: [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE
2026-02-25 16:13 [PATCH v2 0/5] mm: arch/shstk: Common shadow stack mapping helper and VM_NOHUGEPAGE Catalin Marinas
` (4 preceding siblings ...)
2026-02-25 16:14 ` [PATCH v2 5/5] mm: Do not map the shadow stack as THP Catalin Marinas
@ 2026-02-25 20:12 ` Mike Rapoport
5 siblings, 0 replies; 7+ messages in thread
From: Mike Rapoport @ 2026-02-25 20:12 UTC (permalink / raw)
To: Catalin Marinas
Cc: Andrew Morton, David Hildenbrand, Mark Brown, Deepak Gupta,
Rick Edgecombe, 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
On Wed, Feb 25, 2026 at 04:13:57PM +0000, Catalin Marinas wrote:
> 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
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> 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(-)
>
>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 7+ messages in thread