public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Catalin Marinas <catalin.marinas@arm.com>
To: Mark Brown <broonie@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org,
	Will Deacon <will@kernel.org>,
	David Hildenbrand <david@kernel.org>,
	Emanuele Rocca <emanuele.rocca@arm.com>,
	Mark Rutland <mark.rutland@arm.com>
Subject: Re: [PATCH 3/3] arm64: gcs: Do not map the guarded control stack as THP
Date: Fri, 20 Feb 2026 15:13:51 +0000	[thread overview]
Message-ID: <aZh6LzXGY1MfASlo@arm.com> (raw)
In-Reply-To: <18352353-8760-404b-a981-b0a5ac067b6c@sirena.org.uk>

On Fri, Feb 20, 2026 at 02:34:08PM +0000, Mark Brown wrote:
> On Fri, Feb 20, 2026 at 02:05:31PM +0000, Catalin Marinas wrote:
> > The default GCS 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. 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 as 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 GCS. 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.
> 
> I agree that this is sensible however I'm fairly sure this will also
> apply to the other shadow stack implementations so I think it would be
> better to either do it cross architecture (ideally factoring this out of
> the arch code entirely) or put a note in the commit log that it's likely 
> going to apply to other architectures.  There's a bunch of stuff that we
> should start factoring out into common code now that RISC-V landed and
> it looks like the clone3() stuff ran it's course, we should make it as
> easy as possible to understand why any divergences we're adding.

Something like below (not tested yet and not addressing riscv, waiting
for -rc1):

diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c
index bbdb62ae47cd..21ed78d129de 100644
--- a/arch/arm64/mm/gcs.c
+++ b/arch/arm64/mm/gcs.c
@@ -12,23 +12,7 @@

 static unsigned long alloc_gcs(unsigned long addr, unsigned long size)
 {
-	int flags = MAP_ANONYMOUS | MAP_PRIVATE;
-	vm_flags_t vm_flags = VM_SHADOW_STACK;
-	struct mm_struct *mm = current->mm;
-	unsigned long mapped_addr, unused;
-
-	if (addr)
-		flags |= MAP_FIXED_NOREPLACE;
-
-	if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
-		vm_flags |= VM_NOHUGEPAGE;
-
-	mmap_write_lock(mm);
-	mapped_addr = do_mmap(NULL, addr, size, PROT_READ | PROT_WRITE,
-			      flags, vm_flags, 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)
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;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f0d5be9dc736..4bde7539adc8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3711,6 +3711,8 @@ static inline void mm_populate(unsigned long addr, unsigned long len) {}
 /* This takes the mm semaphore itself */
 extern int __must_check vm_brk_flags(unsigned long, unsigned long, unsigned long);
 extern int vm_munmap(unsigned long, size_t);
+extern unsigned long __must_check vm_mmap_shadow_stack(unsigned long addr,
+	unsigned long len, unsigned long flags);
 extern unsigned long __must_check vm_mmap(struct file *, unsigned long,
         unsigned long, unsigned long,
         unsigned long, unsigned long);
diff --git a/mm/util.c b/mm/util.c
index 97cae40c0209..5c0d92f52157 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -588,6 +588,24 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr,
 	return ret;
 }

+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 | VM_NOHUGEPAGE, 0, &unused, NULL);
+	mmap_write_unlock(mm);
+
+	return ret;
+}
+
 /*
  * Perform a userland memory mapping into the current process address space. See
  * the comment for do_mmap() for more details on this operation in general.

-- 
Catalin


  reply	other threads:[~2026-02-20 15:14 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-20 14:05 [PATCH 0/3] arm64: Assorted GCS fixes Catalin Marinas
2026-02-20 14:05 ` [PATCH 1/3] arm64: gcs: Do not set PTE_SHARED on GCS mappings if FEAT_LPA2 is enabled Catalin Marinas
2026-02-20 15:56   ` David Hildenbrand (Arm)
2026-02-20 16:45     ` Catalin Marinas
2026-02-20 16:47       ` Catalin Marinas
2026-02-20 14:05 ` [PATCH 2/3] arm64: gcs: Allow PAGE_NONE mappings for NUMA balancing Catalin Marinas
2026-02-20 16:16   ` David Hildenbrand (Arm)
2026-02-20 19:52     ` Catalin Marinas
2026-02-20 14:05 ` [PATCH 3/3] arm64: gcs: Do not map the guarded control stack as THP Catalin Marinas
2026-02-20 14:34   ` Mark Brown
2026-02-20 15:13     ` Catalin Marinas [this message]
2026-02-20 16:17       ` Mark Brown
2026-02-20 15:33   ` David Hildenbrand (Arm)
2026-02-20 15:36     ` Mark Brown

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=aZh6LzXGY1MfASlo@arm.com \
    --to=catalin.marinas@arm.com \
    --cc=broonie@kernel.org \
    --cc=david@kernel.org \
    --cc=emanuele.rocca@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=will@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox