All of lore.kernel.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 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.