* [RFC PATCH 0/9] arm64: Allocate .text and .init.text together
@ 2026-08-22 13:53 Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 1/9] mm: execmem: Add API to split an existing execmem cache allocation Ard Biesheuvel
` (8 more replies)
0 siblings, 9 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
The arm64 module loader has to deal with a couple of corner cases that
may occur when .init.text is placed out of direct branch range of .text:
- ordinary direct branches from .init.text into .text may require the
use of a PLT entry (i.e., a trampoline aka veneer), which means not
only that additional PLT entries need to be allocated for
cross-section calls, but also that .init.text needs its own PLT
reservation, as the one in .text will be out of range as well;
- dynamic patching of the ftrace handler into .init.text code needs its
own dedicated trampoline as the one in .text may be too far away.
- recent compilers may omit BTI veneers for static functions that never
have their address taken, and so additional veneers will need to be
added to .text in case cross-section direct branches from .init.text
require a PLT entry (and therefore a landing pad at the target end).
This is unfortunate, because it is actually somewhat unusual for .text
and .init.text to be so far away from each other: only when allocating
either of them (but not both) exhausts the 'near' (PLT-less) module
region, the other will be allocated from the spillover region, which is
not in direct branching range, and therefore requires PLT entries for
cross-section calls.
This series addresses this wart by allocating both of them as a single
chunk, and freeing the .init.text part along with the other init
sections at the appropriate time. This ensures that the two regions will
never require veneers for cross-section calls, allowing the arm64 module
loader to be simplified.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Petr Pavlu <petr.pavlu@suse.com>
Cc: Daniel Gomez <da.gomez@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Aaron Tomlin <atomlin@atomlin.com>
Cc: "Adrian Barnaś" <abarnas@google.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-trace-kernel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-modules@vger.kernel.org
Ard Biesheuvel (9):
mm: execmem: Add API to split an existing execmem cache allocation
mm: execmem: Allow huge vmappings to be avoided for execmem caches
module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration
module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation
arm64: mm: Permit permissions changes on huge vmappings
arm64: Enable the execmem ROX cache for module text
arm64: ftrace: Revert "fix unreachable PLT for ftrace_caller ..."
arm64: module: Combine init and core PLT entries again
arm64: ftrace: Simplify PLT handling
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/module.h | 2 -
arch/arm64/include/asm/module.lds.h | 3 -
arch/arm64/kernel/ftrace.c | 13 +---
arch/arm64/kernel/module-plts.c | 63 +++++---------------
arch/arm64/kernel/module.c | 20 +------
arch/arm64/mm/init.c | 19 +++++-
arch/arm64/mm/pageattr.c | 13 +++-
include/linux/execmem.h | 11 ++++
include/linux/module.h | 4 +-
kernel/module/main.c | 22 +++++--
mm/execmem.c | 47 ++++++++++++++-
12 files changed, 124 insertions(+), 94 deletions(-)
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply [flat|nested] 17+ messages in thread
* [RFC PATCH 1/9] mm: execmem: Add API to split an existing execmem cache allocation
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches Ard Biesheuvel
` (7 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
In order to permit the module loader to allocate MOD_TEXT and
MOD_INIT_TEXT from the same chunk of memory, add an API function to
execmem that splits an existing execmem cache allocation in two.
This will be used on arm64 to avoid .text and .init.text being placed
far away from each other.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/linux/execmem.h | 9 ++++
mm/execmem.c | 44 ++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/include/linux/execmem.h b/include/linux/execmem.h
index 7de229134e30..59bd862cb061 100644
--- a/include/linux/execmem.h
+++ b/include/linux/execmem.h
@@ -178,6 +178,15 @@ void execmem_free(void *ptr);
DEFINE_FREE(execmem, void *, if (_T) execmem_free(_T));
+/**
+ * execmem_split - allocate space from an existing execmem cache allocation
+ * @ptr - the existing execmem cache allocation
+ * @size - the size to carve out from the existing allocation
+ *
+ * Return: the address of the carved out allocation, or %NULL on failure.
+ */
+void *execmem_split(void *ptr, size_t size);
+
#ifdef CONFIG_MMU
/**
* execmem_vmap - create virtual mapping for EXECMEM_MODULE_DATA memory
diff --git a/mm/execmem.c b/mm/execmem.c
index 084a207e4278..6db0c1d82a9d 100644
--- a/mm/execmem.c
+++ b/mm/execmem.c
@@ -439,6 +439,33 @@ static bool execmem_cache_free(void *ptr)
return true;
}
+static void *execmem_cache_split(void *ptr, size_t size)
+{
+ struct maple_tree *busy_areas = &execmem_cache.busy_areas;
+ unsigned long addr = (unsigned long)ptr;
+ MA_STATE(mas, busy_areas, addr, addr);
+ void *area;
+ int err;
+
+ guard(mutex)(&execmem_cache.mutex);
+
+ area = mas_walk(&mas);
+ if (!area)
+ return ERR_PTR(-ENOENT);
+
+ if (size >= mas_range_len(&mas))
+ return ERR_PTR(-EINVAL);
+
+ addr += mas_range_len(&mas) - size;
+ mas_set_range(&mas, addr, mas.last);
+
+ err = mas_store_gfp(&mas, (void *)addr, GFP_KERNEL);
+ if (err)
+ return ERR_PTR(err);
+
+ return (void *)addr;
+}
+
#else /* CONFIG_ARCH_HAS_EXECMEM_ROX */
/*
* when ROX cache is not used the permissions defined by architectures for
@@ -459,6 +486,11 @@ static bool execmem_cache_free(void *ptr)
{
return false;
}
+
+static void *execmem_cache_split(void *ptr, size_t size)
+{
+ return ERR_PTR(-ENOENT);
+}
#endif /* CONFIG_ARCH_HAS_EXECMEM_ROX */
void *execmem_alloc(enum execmem_type type, size_t size)
@@ -511,6 +543,18 @@ bool execmem_is_rox(enum execmem_type type)
return !!(execmem_info->ranges[type].flags & EXECMEM_ROX_CACHE);
}
+void *execmem_split(void *ptr, size_t size)
+{
+ if (!ptr || !size)
+ return NULL;
+
+ ptr = execmem_cache_split(ptr, size);
+ if (!IS_ERR(ptr))
+ return ptr;
+ VM_WARN_ON(ptr != ERR_PTR(-ENOMEM));
+ return NULL;
+}
+
static bool execmem_validate(struct execmem_info *info)
{
struct execmem_range *r = &info->ranges[EXECMEM_DEFAULT];
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 1/9] mm: execmem: Add API to split an existing execmem cache allocation Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 14:10 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration Ard Biesheuvel
` (6 subsequent siblings)
8 siblings, 1 reply; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
Only recent arm64 systems are guaranteed to be able to manipulate the
permissions on live kernel mappings that may use huge mappings. Older
ones can only do so on live mappings that are mapped down to pages.
In order to make execmem caches work on arm64 despite this distinction,
allow huge vmappings to be omitted when allocating the caches.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/linux/execmem.h | 2 ++
mm/execmem.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/execmem.h b/include/linux/execmem.h
index 59bd862cb061..b04926f3fff2 100644
--- a/include/linux/execmem.h
+++ b/include/linux/execmem.h
@@ -48,10 +48,12 @@ enum execmem_type {
* enum execmem_range_flags - options for executable memory allocations
* @EXECMEM_KASAN_SHADOW: allocate kasan shadow
* @EXECMEM_ROX_CACHE: allocations should use ROX cache of huge pages
+ * @EXECMEM_NO_HUGE_VMAP: cache allocations must avoid huge vmappings
*/
enum execmem_range_flags {
EXECMEM_KASAN_SHADOW = (1 << 0),
EXECMEM_ROX_CACHE = (1 << 1),
+ EXECMEM_NO_HUGE_VMAP = (1 << 2),
};
#ifdef CONFIG_ARCH_HAS_EXECMEM_ROX
diff --git a/mm/execmem.c b/mm/execmem.c
index 6db0c1d82a9d..5790d4a8532a 100644
--- a/mm/execmem.c
+++ b/mm/execmem.c
@@ -276,7 +276,8 @@ static void *__execmem_cache_alloc(struct execmem_range *range, size_t size)
static void *execmem_cache_populate_alloc(struct execmem_range *range, size_t size)
{
- unsigned long vm_flags = VM_ALLOW_HUGE_VMAP;
+ unsigned long vm_flags = (range->flags & EXECMEM_NO_HUGE_VMAP)
+ ? 0 : VM_ALLOW_HUGE_VMAP;
struct mutex *mutex = &execmem_cache.mutex;
struct vm_struct *vm;
size_t alloc_size;
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 1/9] mm: execmem: Add API to split an existing execmem cache allocation Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 14:05 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 4/9] module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation Ard Biesheuvel
` (5 subsequent siblings)
8 siblings, 1 reply; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
Reorder enum mod_mem_type so that MOD_TEXT appears right before
MOD_INIT_TEXT. This will result in MOD_INIT_TEXT being allocated right
after MOD_TEXT when the allocation logic iterates over the memory types
in enum declaration order.
In a subsequent patch, this will be taken advantage of, by allocating
.text and .init.text together, and freeing .init.text by truncating the
allocation. Doing so without this reordering would likely result in more
fragmentation, as the truncated .text allocation would be followed by
.rodata and .data/.bss of the same module.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
include/linux/module.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/module.h b/include/linux/module.h
index 7566815fabbe..0336a46733dd 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -316,10 +316,10 @@ struct mod_tree_node {
};
enum mod_mem_type {
- MOD_TEXT = 0,
- MOD_DATA,
+ MOD_DATA = 0,
MOD_RODATA,
MOD_RO_AFTER_INIT,
+ MOD_TEXT,
MOD_INIT_TEXT,
MOD_INIT_DATA,
MOD_INIT_RODATA,
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 4/9] module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (2 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings Ard Biesheuvel
` (4 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
When execmem ROX caches are used for module text and inittext, place
them adjacently in memory, by allocating space for both initially, and
splitting off the space for MOD_INIT_TEXT as needed.
This avoids the corner case on arm64, where .init.text being placed far
from .text results in a lot of complexity wrt indirect branches and PLTs
that we'd prefer to avoid.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
kernel/module/main.c | 22 ++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 46dd8d25a605..2d6213496359 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -1342,7 +1342,7 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
{
unsigned int size = PAGE_ALIGN(mod->mem[type].size);
enum execmem_type execmem_type;
- void *ptr;
+ void *ptr = NULL;
mod->mem[type].size = size;
@@ -1351,11 +1351,25 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
else
execmem_type = EXECMEM_MODULE_TEXT;
- ptr = execmem_alloc_rw(execmem_type, size);
+ bool is_rox = execmem_is_rox(execmem_type);
+ if (is_rox) {
+ /*
+ * Special case for MOD_TEXT / MOD_INIT_TEXT: allocate the
+ * latter by splitting off required space from the former
+ * so that they are always placed close together.
+ */
+ if (type == MOD_TEXT)
+ size += PAGE_ALIGN(mod->mem[MOD_INIT_TEXT].size);
+ else if (type == MOD_INIT_TEXT)
+ ptr = execmem_split(mod->mem[MOD_TEXT].base, size);
+ }
+
+ if (!ptr)
+ ptr = execmem_alloc_rw(execmem_type, size);
if (!ptr)
return -ENOMEM;
- mod->mem[type].is_rox = execmem_is_rox(execmem_type);
+ mod->mem[type].is_rox = is_rox;
/*
* The pointer to these blocks of memory are stored on the module
@@ -1368,7 +1382,7 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
* *do* eventually get freed, but let's just keep things simple
* and avoid *any* false positives.
*/
- if (!mod->mem[type].is_rox)
+ if (!is_rox)
kmemleak_not_leak(ptr);
memset(ptr, 0, size);
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (3 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 4/9] module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 14:10 ` sashiko-bot
2026-08-23 16:52 ` Adrian Barnaś
2026-08-22 13:53 ` [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text Ard Biesheuvel
` (3 subsequent siblings)
8 siblings, 2 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
Allow permission changes on huge vmappings in cases where no splitting
is needed (i.e., the region is aligned sufficiently), or when the system
has support for splitting live mappings.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/mm/pageattr.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index bbe98ac9ad8c..20ff9cb273c1 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -169,8 +169,6 @@ static int change_memory_common(unsigned long addr, int numpages,
* we are operating on does not result in such splitting.
*
* Let's restrict ourselves to mappings created by vmalloc (or vmap).
- * Disallow VM_ALLOW_HUGE_VMAP mappings to guarantee that only page
- * mappings are updated and splitting is never needed.
*
* So check whether the [addr, addr + size) interval is entirely
* covered by precisely one VM area that has the VM_ALLOC flag set.
@@ -179,7 +177,16 @@ static int change_memory_common(unsigned long addr, int numpages,
if (!area ||
((unsigned long)kasan_reset_tag((void *)end) >
(unsigned long)kasan_reset_tag(area->addr) + area->size) ||
- ((area->flags & (VM_ALLOC | VM_ALLOW_HUGE_VMAP)) != VM_ALLOC))
+ !(area->flags & VM_ALLOC))
+ return -EINVAL;
+
+ /*
+ * Disallow VM_ALLOW_HUGE_VMAP mappings unless the region is PMD
+ * aligned, or splitting live huge mappings is supported.
+ */
+ if ((area->flags & VM_ALLOW_HUGE_VMAP) &&
+ ((start % PMD_SIZE) || (size % PMD_SIZE)) &&
+ WARN_ON_ONCE(!system_supports_bbml2_noabort()))
return -EINVAL;
if (!numpages)
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (4 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 14:13 ` sashiko-bot
2026-08-23 16:46 ` Adrian Barnaś
2026-08-22 13:53 ` [RFC PATCH 7/9] arm64: ftrace: Revert "fix unreachable PLT for ftrace_caller ..." Ard Biesheuvel
` (2 subsequent siblings)
8 siblings, 2 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
Wire up the existing support for the execmem ROX cache on arm64, so that
it will be used for module .text and .init.text regions. This will be
relied upon by a subsequent patch in order to allocate those regions
from a single chunk of memory.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/Kconfig | 1 +
arch/arm64/mm/init.c | 19 ++++++++++++++++++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b3afe0688919..080b97b0bbd5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -27,6 +27,7 @@ config ARM64
select ARCH_HAS_DMA_OPS if XEN
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
+ select ARCH_HAS_EXECMEM_ROX
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 97987f850a33..e6c98045046e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -531,7 +531,8 @@ struct execmem_info __init *execmem_arch_setup(void)
[EXECMEM_DEFAULT] = {
.start = start,
.end = end,
- .pgprot = PAGE_KERNEL,
+ .pgprot = PAGE_KERNEL_ROX,
+ .flags = EXECMEM_ROX_CACHE,
.alignment = 1,
.fallback_start = fallback_start,
.fallback_end = fallback_end,
@@ -548,9 +549,25 @@ struct execmem_info __init *execmem_arch_setup(void)
.pgprot = PAGE_KERNEL,
.alignment = 1,
},
+ [EXECMEM_MODULE_DATA] = {
+ .start = start,
+ .end = end,
+ .pgprot = PAGE_KERNEL,
+ .alignment = 1,
+ .fallback_start = fallback_start,
+ .fallback_end = fallback_end,
+ },
},
};
+ if (!system_supports_bbml2_noabort())
+ execmem_info.ranges[EXECMEM_DEFAULT].flags |= EXECMEM_NO_HUGE_VMAP;
+
return &execmem_info;
}
+
+void execmem_fill_trapping_insns(void *ptr, size_t size)
+{
+ memset32(ptr, AARCH64_BREAK_FAULT, size / sizeof(__le32));
+}
#endif /* CONFIG_EXECMEM */
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 7/9] arm64: ftrace: Revert "fix unreachable PLT for ftrace_caller ..."
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (5 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 9/9] arm64: ftrace: Simplify PLT handling Ard Biesheuvel
8 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
This reverts commit a7ed7b9d0ebb038db9963d574da0311cab0b666a, which is
no longer needed now that the corner case where .init.text is placed out
of direct branching range from .text of the same module can no longer
occur.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/module.h | 1 -
arch/arm64/include/asm/module.lds.h | 1 -
arch/arm64/kernel/ftrace.c | 13 +++----------
arch/arm64/kernel/module-plts.c | 12 +-----------
arch/arm64/kernel/module.c | 11 -----------
5 files changed, 4 insertions(+), 34 deletions(-)
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index fb9b88eebeb1..79550b22ba19 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -19,7 +19,6 @@ struct mod_arch_specific {
/* for CONFIG_DYNAMIC_FTRACE */
struct plt_entry *ftrace_trampolines;
- struct plt_entry *init_ftrace_trampolines;
};
u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
index 0b3aacd22c59..0c3aea98e116 100644
--- a/arch/arm64/include/asm/module.lds.h
+++ b/arch/arm64/include/asm/module.lds.h
@@ -2,7 +2,6 @@ SECTIONS {
.plt 0 : { BYTE(0) }
.init.plt 0 : { BYTE(0) }
.text.ftrace_trampoline 0 : { BYTE(0) }
- .init.text.ftrace_trampoline 0 : { BYTE(0) }
#ifdef CONFIG_KASAN_SW_TAGS
/*
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index 5a1554a44162..b56da24c1be4 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -258,17 +258,10 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return ftrace_modify_code(pc, 0, new, false);
}
-static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr)
+static struct plt_entry *get_ftrace_plt(struct module *mod)
{
#ifdef CONFIG_MODULES
- struct plt_entry *plt = NULL;
-
- if (within_module_mem_type(addr, mod, MOD_INIT_TEXT))
- plt = mod->arch.init_ftrace_trampolines;
- else if (within_module_mem_type(addr, mod, MOD_TEXT))
- plt = mod->arch.ftrace_trampolines;
- else
- return NULL;
+ struct plt_entry *plt = mod->arch.ftrace_trampolines;
return &plt[FTRACE_PLT_IDX];
#else
@@ -339,7 +332,7 @@ static bool ftrace_find_callable_addr(struct dyn_ftrace *rec,
if (WARN_ON(!mod))
return false;
- plt = get_ftrace_plt(mod, pc);
+ plt = get_ftrace_plt(mod);
if (!plt) {
pr_err("ftrace: no module PLT for %ps\n", (void *)*addr);
return false;
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index 7afd370da9f4..bde32979c06a 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -283,7 +283,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
unsigned long core_plts = 0;
unsigned long init_plts = 0;
Elf64_Sym *syms = NULL;
- Elf_Shdr *pltsec, *tramp = NULL, *init_tramp = NULL;
+ Elf_Shdr *pltsec, *tramp = NULL;
int i;
/*
@@ -298,9 +298,6 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
else if (!strcmp(secstrings + sechdrs[i].sh_name,
".text.ftrace_trampoline"))
tramp = sechdrs + i;
- else if (!strcmp(secstrings + sechdrs[i].sh_name,
- ".init.text.ftrace_trampoline"))
- init_tramp = sechdrs + i;
else if (sechdrs[i].sh_type == SHT_SYMTAB)
syms = (Elf64_Sym *)sechdrs[i].sh_addr;
}
@@ -366,12 +363,5 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
}
- if (init_tramp) {
- init_tramp->sh_type = SHT_NOBITS;
- init_tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- init_tramp->sh_addralign = __alignof__(struct plt_entry);
- init_tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
- }
-
return 0;
}
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 24adb581af0e..6e5b488a219e 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -466,17 +466,6 @@ static int module_init_ftrace_plt(const Elf_Ehdr *hdr,
__init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR);
mod->arch.ftrace_trampolines = plts;
-
- s = find_section(hdr, sechdrs, ".init.text.ftrace_trampoline");
- if (!s)
- return -ENOEXEC;
-
- plts = (void *)s->sh_addr;
-
- __init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR);
-
- mod->arch.init_ftrace_trampolines = plts;
-
#endif
return 0;
}
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (6 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 7/9] arm64: ftrace: Revert "fix unreachable PLT for ftrace_caller ..." Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
2026-08-22 14:12 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 9/9] arm64: ftrace: Simplify PLT handling Ard Biesheuvel
8 siblings, 1 reply; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
It is no longer possible for .init.text to end up being placed out of
direct branching range of the .text section of the same module, so the
PLT array of core and init code can be combined again.
It also means there is no longer a need to allocate PLT entries for
cross-section calls within the same module, and so the upper bound
for the number of needed entries can be lowered again as well.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/module.h | 1 -
arch/arm64/include/asm/module.lds.h | 1 -
arch/arm64/kernel/module-plts.c | 35 +++++---------------
3 files changed, 9 insertions(+), 28 deletions(-)
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index 79550b22ba19..9328fadb4a95 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -15,7 +15,6 @@ struct mod_plt_sec {
struct mod_arch_specific {
struct mod_plt_sec core;
- struct mod_plt_sec init;
/* for CONFIG_DYNAMIC_FTRACE */
struct plt_entry *ftrace_trampolines;
diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
index 0c3aea98e116..24fc9401c514 100644
--- a/arch/arm64/include/asm/module.lds.h
+++ b/arch/arm64/include/asm/module.lds.h
@@ -1,6 +1,5 @@
SECTIONS {
.plt 0 : { BYTE(0) }
- .init.plt 0 : { BYTE(0) }
.text.ftrace_trampoline 0 : { BYTE(0) }
#ifdef CONFIG_KASAN_SW_TAGS
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index bde32979c06a..e30876b90e30 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -70,8 +70,7 @@ u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
void *loc, const Elf64_Rela *rela,
Elf64_Sym *sym)
{
- struct mod_plt_sec *pltsec = !within_module_init((unsigned long)loc, mod) ?
- &mod->arch.core : &mod->arch.init;
+ struct mod_plt_sec *pltsec = &mod->arch.core;
struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr;
int i = pltsec->plt_num_entries;
int j = i - 1;
@@ -101,8 +100,7 @@ u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
u64 module_emit_veneer_for_adrp(struct module *mod, Elf64_Shdr *sechdrs,
void *loc, u64 val)
{
- struct mod_plt_sec *pltsec = !within_module_init((unsigned long)loc, mod) ?
- &mod->arch.core : &mod->arch.init;
+ struct mod_plt_sec *pltsec = &mod->arch.core;
struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr;
int i = pltsec->plt_num_entries++;
u32 br;
@@ -169,17 +167,17 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
case R_AARCH64_CALL26:
/*
* We only have to consider branch targets that resolve
- * to symbols that are defined in a different section.
+ * to symbols that are not defined in the same module.
* This is not simply a heuristic, it is a fundamental
* limitation, since there is no guaranteed way to emit
* PLT entries sufficiently close to the branch if the
* section size exceeds the range of a branch
* instruction. So ignore relocations against defined
- * symbols if they live in the same section as the
+ * symbols if they live in the same module as the
* relocation target.
*/
s = syms + ELF64_R_SYM(rela[i].r_info);
- if (s->st_shndx == dstidx)
+ if (s->st_shndx != SHN_UNDEF)
break;
/*
@@ -281,7 +279,6 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod)
{
unsigned long core_plts = 0;
- unsigned long init_plts = 0;
Elf64_Sym *syms = NULL;
Elf_Shdr *pltsec, *tramp = NULL;
int i;
@@ -293,8 +290,6 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
for (i = 0; i < ehdr->e_shnum; i++) {
if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt"))
mod->arch.core.plt_shndx = i;
- else if (!strcmp(secstrings + sechdrs[i].sh_name, ".init.plt"))
- mod->arch.init.plt_shndx = i;
else if (!strcmp(secstrings + sechdrs[i].sh_name,
".text.ftrace_trampoline"))
tramp = sechdrs + i;
@@ -302,8 +297,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
syms = (Elf64_Sym *)sechdrs[i].sh_addr;
}
- if (!mod->arch.core.plt_shndx || !mod->arch.init.plt_shndx) {
- pr_err("%s: module PLT section(s) missing\n", mod->name);
+ if (!mod->arch.core.plt_shndx) {
+ pr_err("%s: module PLT section missing\n", mod->name);
return -ENOEXEC;
}
if (!syms) {
@@ -332,12 +327,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
if (nents)
sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL);
- if (!module_init_layout_section(secstrings + dstsec->sh_name))
- core_plts += count_plts(syms, rels, numrels,
- sechdrs[i].sh_info, dstsec);
- else
- init_plts += count_plts(syms, rels, numrels,
- sechdrs[i].sh_info, dstsec);
+ core_plts += count_plts(syms, rels, numrels, sechdrs[i].sh_info,
+ dstsec);
}
pltsec = sechdrs + mod->arch.core.plt_shndx;
@@ -348,14 +339,6 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
mod->arch.core.plt_num_entries = 0;
mod->arch.core.plt_max_entries = core_plts;
- pltsec = sechdrs + mod->arch.init.plt_shndx;
- pltsec->sh_type = SHT_NOBITS;
- pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- pltsec->sh_addralign = L1_CACHE_BYTES;
- pltsec->sh_size = (init_plts + 1) * sizeof(struct plt_entry);
- mod->arch.init.plt_num_entries = 0;
- mod->arch.init.plt_max_entries = init_plts;
-
if (tramp) {
tramp->sh_type = SHT_NOBITS;
tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [RFC PATCH 9/9] arm64: ftrace: Simplify PLT handling
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
` (7 preceding siblings ...)
2026-08-22 13:53 ` [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again Ard Biesheuvel
@ 2026-08-22 13:53 ` Ard Biesheuvel
8 siblings, 0 replies; 17+ messages in thread
From: Ard Biesheuvel @ 2026-08-22 13:53 UTC (permalink / raw)
To: linux-kernel
Cc: Ard Biesheuvel, Catalin Marinas, Will Deacon, Steven Rostedt,
Masami Hiramatsu, Mark Rutland, Andrew Morton, Mike Rapoport,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Adrian Barnaś, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
From: Ard Biesheuvel <ardb@kernel.org>
Instead of emitting the ftrace trampoline PLT into a separate ELF
section, allocate them at the start of the ordinary PLT array, so
that no special sections are needed.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/module.lds.h | 1 -
arch/arm64/kernel/module-plts.c | 18 +++++-------------
arch/arm64/kernel/module.c | 9 +--------
3 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/arch/arm64/include/asm/module.lds.h b/arch/arm64/include/asm/module.lds.h
index 24fc9401c514..95540e956b41 100644
--- a/arch/arm64/include/asm/module.lds.h
+++ b/arch/arm64/include/asm/module.lds.h
@@ -1,6 +1,5 @@
SECTIONS {
.plt 0 : { BYTE(0) }
- .text.ftrace_trampoline 0 : { BYTE(0) }
#ifdef CONFIG_KASAN_SW_TAGS
/*
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index e30876b90e30..6900d2242f1b 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -275,12 +275,14 @@ static int partition_branch_plt_relas(Elf64_Sym *syms, Elf64_Rela *rela,
return i;
}
+static const int ftrace_plts = IS_ENABLED(CONFIG_DYNAMIC_FTRACE) ? NR_FTRACE_PLTS : 0;
+
int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod)
{
- unsigned long core_plts = 0;
+ unsigned long core_plts = ftrace_plts;
Elf64_Sym *syms = NULL;
- Elf_Shdr *pltsec, *tramp = NULL;
+ Elf_Shdr *pltsec;
int i;
/*
@@ -290,9 +292,6 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
for (i = 0; i < ehdr->e_shnum; i++) {
if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt"))
mod->arch.core.plt_shndx = i;
- else if (!strcmp(secstrings + sechdrs[i].sh_name,
- ".text.ftrace_trampoline"))
- tramp = sechdrs + i;
else if (sechdrs[i].sh_type == SHT_SYMTAB)
syms = (Elf64_Sym *)sechdrs[i].sh_addr;
}
@@ -336,15 +335,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
pltsec->sh_addralign = L1_CACHE_BYTES;
pltsec->sh_size = (core_plts + 1) * sizeof(struct plt_entry);
- mod->arch.core.plt_num_entries = 0;
+ mod->arch.core.plt_num_entries = ftrace_plts;
mod->arch.core.plt_max_entries = core_plts;
- if (tramp) {
- tramp->sh_type = SHT_NOBITS;
- tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- tramp->sh_addralign = __alignof__(struct plt_entry);
- tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
- }
-
return 0;
}
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 6e5b488a219e..620c2b70115e 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -454,14 +454,7 @@ static int module_init_ftrace_plt(const Elf_Ehdr *hdr,
struct module *mod)
{
#if defined(CONFIG_DYNAMIC_FTRACE)
- const Elf_Shdr *s;
- struct plt_entry *plts;
-
- s = find_section(hdr, sechdrs, ".text.ftrace_trampoline");
- if (!s)
- return -ENOEXEC;
-
- plts = (void *)s->sh_addr;
+ struct plt_entry *plts = (void *)sechdrs[mod->arch.core.plt_shndx].sh_addr;
__init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR);
--
2.55.0.860.g4b6b3295ed-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration
2026-08-22 13:53 ` [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration Ard Biesheuvel
@ 2026-08-22 14:05 ` sashiko-bot
0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-22 14:05 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-modules, linux-trace-kernel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The reordering of `enum mod_mem_type` breaks the `lx-lsmod` GDB script command, causing it to report a core module size of 0 for all loaded modules.
--
--- Patch [3]: [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration ---
commit 5a5649e85e950b908f9830e5862b49ac415dfa18
Author: Ard Biesheuvel <ardb@kernel.org>
module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration
This commit reorders enum mod_mem_type so that MOD_TEXT appears right
before MOD_INIT_TEXT. This ensures MOD_INIT_TEXT is allocated immediately
after MOD_TEXT, reducing fragmentation when truncating allocations in
subsequent patches.
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 7566815fabbe8..0336a46733dd9 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -316,10 +316,10 @@ struct mod_tree_node {
> };
>
> enum mod_mem_type {
> - MOD_TEXT = 0,
> - MOD_DATA,
> + MOD_DATA = 0,
> MOD_RODATA,
> MOD_RO_AFTER_INIT,
> + MOD_TEXT,
[Severity: Medium]
Does this reordering break the lx-lsmod GDB script command?
In scripts/gdb/linux/modules.py:LxLsmod.invoke(), the total size of a
module's core sections is computed by iterating over the memory regions:
for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1):
total_size += module['mem'][i]['size']
Because MOD_TEXT now evaluates to 3 and MOD_RO_AFTER_INIT evaluates to 2
with this change, the Python iteration evaluates to range(3, 3). This
generates an empty sequence and the total_size remains 0 for all loaded
modules.
> MOD_INIT_TEXT,
> MOD_INIT_DATA,
> MOD_INIT_RODATA,
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822135323.795946-11-ardb+git@google.com?part=3
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches
2026-08-22 13:53 ` [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches Ard Biesheuvel
@ 2026-08-22 14:10 ` sashiko-bot
0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-22 14:10 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-trace-kernel, linux-modules
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] Omitting VM_ALLOW_HUGE_VMAP breaks the ROX cache shrinker by stripping PMD_SIZE alignment, causing a permanent memory leak of cached module memory.
Pre-existing issues:
- [High] Fallback allocations in execmem_cache_populate_alloc() leak memory due to failing the PMD_SIZE alignment checks in the cache shrinker.
- [High] Ignored return value of execmem_restore_rox() allows memory to be silently returned to the ROX cache with RW permissions.
--
--- Patch [2]: [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches ---
commit 3d4b59f7ca74d71807be337626018d273686c686
Author: Ard Biesheuvel <ardb@kernel.org>
mm: execmem: Allow huge vmappings to be avoided for execmem caches
Only recent arm64 systems are guaranteed to be able to manipulate the
permissions on live kernel mappings that may use huge mappings. Older
ones can only do so on live mappings that are mapped down to pages.
In order to make execmem caches work on arm64 despite this distinction,
allow huge vmappings to be omitted when allocating the caches.
> diff --git a/mm/execmem.c b/mm/execmem.c
> index 6db0c1d82a9d6..5790d4a8532af 100644
> --- a/mm/execmem.c
> +++ b/mm/execmem.c
> @@ -276,7 +276,8 @@ static void *__execmem_cache_alloc(struct execmem_range *range, size_t size)
>
> static void *execmem_cache_populate_alloc(struct execmem_range *range, size_t size)
> {
> - unsigned long vm_flags = VM_ALLOW_HUGE_VMAP;
> + unsigned long vm_flags = (range->flags & EXECMEM_NO_HUGE_VMAP)
> + ? 0 : VM_ALLOW_HUGE_VMAP;
[Severity: High]
Does dropping VM_ALLOW_HUGE_VMAP here cause a permanent memory leak in the
ROX cache?
When VM_ALLOW_HUGE_VMAP is omitted, the allocation may fall back to the
standard alignment (typically PAGE_SIZE) instead of being PMD_SIZE aligned.
However, the shrinker in execmem_cache_clean() strictly requires PMD_SIZE
alignment to free the memory:
mm/execmem.c:execmem_cache_clean() {
...
mas_for_each(&mas, area, ULONG_MAX) {
size_t size = mas_range_len(&mas);
if (IS_ALIGNED(size, PMD_SIZE) &&
IS_ALIGNED(mas.index, PMD_SIZE)) {
struct vm_struct *vm = find_vm_area(area);
...
}
If the starting address (mas.index) of the chunk allocated without
VM_ALLOW_HUGE_VMAP is not PMD_SIZE aligned, the shrinker will skip it,
never returning it to the vmalloc subsystem.
> struct mutex *mutex = &execmem_cache.mutex;
> struct vm_struct *vm;
> size_t alloc_size;
> int err = -ENOMEM;
> void *p;
>
> alloc_size = round_up(size, PMD_SIZE);
> p = execmem_vmalloc(range, alloc_size, PAGE_KERNEL, vm_flags);
> if (!p) {
> alloc_size = size;
> p = execmem_vmalloc(range, alloc_size, PAGE_KERNEL, vm_flags);
[Severity: High]
This is a pre-existing issue, but does this exact-size fallback allocation
leak memory for the same reason?
If the PMD_SIZE rounded allocation fails under pressure, the fallback
allocates the exact requested size. Since this fallback size is not
guaranteed to be PMD_SIZE aligned, it will also permanently fail the
IS_ALIGNED(size, PMD_SIZE) check in execmem_cache_clean(), leaking the
vmalloc space.
[ ... ]
> static int __execmem_cache_free(struct ma_state *mas, void *ptr, gfp_t gfp_mask)
> {
> size_t size = mas_range_len(mas);
> int err;
>
> err = execmem_force_rw(ptr, size);
> if (err)
> return err;
>
> execmem_fill_trapping_insns(ptr, size);
> execmem_restore_rox(ptr, size);
>
> err = execmem_cache_add_locked(ptr, size, gfp_mask);
[Severity: High]
This isn't a bug introduced by this patch, but is it safe to ignore the
return value of execmem_restore_rox() here?
If restoring the ROX permissions fails (for example, if set_memory_rox() fails
internally), the chunk is still added back to the free_areas tree. Subsequent
allocations could then receive memory that is still writable, silently breaking
the W^X security guarantee.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822135323.795946-11-ardb+git@google.com?part=2
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings
2026-08-22 13:53 ` [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings Ard Biesheuvel
@ 2026-08-22 14:10 ` sashiko-bot
2026-08-23 16:52 ` Adrian Barnaś
1 sibling, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-22 14:10 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-trace-kernel, linux-modules
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Live splitting of huge vmalloc mappings silently fails and triggers a kernel warning.
- [High] Permission changes on small, PTE-mapped vmalloc areas are incorrectly rejected.
- [High] Improper use of `WARN_ON_ONCE` for a hardware capability check causes unwarranted kernel log spam and potential panic.
- [Low] Implicit declaration of function `system_supports_bbml2_noabort()` breaks the build.
--
--- Patch [5]: [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings ---
commit e67f32e911a059a6f372cf2818088d9fde53ee7f
Author: Ard Biesheuvel <ardb@kernel.org>
arm64: mm: Permit permissions changes on huge vmappings
This commit allows permission changes on huge vmappings without splitting
when the region is PMD-aligned or when the system supports live splitting.
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index bbe98ac9ad8c6..20ff9cb273c11 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
[ ... ]
> @@ -179,7 +177,16 @@ static int change_memory_common(unsigned long addr, int numpages,
> if (!area ||
> ((unsigned long)kasan_reset_tag((void *)end) >
> (unsigned long)kasan_reset_tag(area->addr) + area->size) ||
> - ((area->flags & (VM_ALLOC | VM_ALLOW_HUGE_VMAP)) != VM_ALLOC))
> + !(area->flags & VM_ALLOC))
> return -EINVAL;
>
> + /*
> + * Disallow VM_ALLOW_HUGE_VMAP mappings unless the region is PMD
> + * aligned, or splitting live huge mappings is supported.
> + */
> + if ((area->flags & VM_ALLOW_HUGE_VMAP) &&
> + ((start % PMD_SIZE) || (size % PMD_SIZE)) &&
> + WARN_ON_ONCE(!system_supports_bbml2_noabort()))
[Severity: Low]
Does the function system_supports_bbml2_noabort() exist in the codebase? It
appears to be missing a definition or declaration, which might cause the
kernel to fail to compile due to an implicit function declaration.
[Severity: High]
Is WARN_ON_ONCE() the right choice for a hardware capability check here?
If an unaligned permission change is requested on an older system lacking
BBML2 support, this will trigger a warning stack trace. If panic_on_warn
is enabled, an unprivileged user loading a BPF program could trigger a
kernel panic. Should this condition fail silently instead?
[Severity: High]
Does checking area->flags & VM_ALLOW_HUGE_VMAP incorrectly reject small,
PTE-mapped vmalloc areas?
Allocators like execmem use VM_ALLOW_HUGE_VMAP as an allocation hint. If
an allocation is smaller than PMD_SIZE, it falls back to PTE mappings but
retains the VM_ALLOW_HUGE_VMAP flag in area->flags.
When change_memory_common() processes this on older hardware without
BBML2, it sees the flag alongside an unaligned size, and rejects the
request with -EINVAL, even though the page table is already PTE-mapped
and requires no splitting.
Should we check the actual page table granularity, such as inspecting
area->page_order, instead of just the allocation flag?
[Severity: High]
If this condition passes because system_supports_bbml2_noabort() is true,
will the PMD actually be split later?
change_memory_common() delegates to __change_memory_common() which
calls update_range_prot() and eventually split_kernel_leaf_mapping().
Looking at split_kernel_leaf_mapping() in arch/arm64/mm/mmu.c:
if (!linear_map_requires_bbml3 || is_kfence_address((void *)start))
return 0;
if (!system_supports_bbml3()) {
...
return 0;
}
This evaluates system_supports_bbml3() and linear_map_requires_bbml3,
ignoring both the BBML2 capability and the vmalloc context. If those are
false (for example, if rodata is off), it returns 0 without splitting the
PMD.
The subsequent lockless page table walk would then encounter an unsplit PMD
spanning a larger range than requested, resulting in a warning and a
failure.
> + return -EINVAL;
>
> if (!numpages)
> return 0;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822135323.795946-11-ardb+git@google.com?part=5
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again
2026-08-22 13:53 ` [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again Ard Biesheuvel
@ 2026-08-22 14:12 ` sashiko-bot
0 siblings, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-22 14:12 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-trace-kernel, linux-modules
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The check `s->st_shndx != SHN_UNDEF` incorrectly skips PLT counting for special symbols like `SHN_LIVEPATCH` and `SHN_ABS`, breaking livepatching.
- [High] Combining core and init PLTs breaks module loading if `execmem_split` fails and falls back to an independent memory allocation.
--
--- Patch [8]: [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again ---
commit 9e8ee18408a9e3b59ec81f693240a4dd9c7669a3
Author: Ard Biesheuvel <ardb@kernel.org>
arm64: module: Combine init and core PLT entries again
This patch consolidates the core and init PLT sections into a single array,
operating on the assumption that .init.text and .text are now always placed
within direct branching range of each other. It also eliminates the need
to allocate PLT entries for intra-module cross-section calls.
> diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
> index bde32979c06af..e30876b90e306 100644
> --- a/arch/arm64/kernel/module-plts.c
> +++ b/arch/arm64/kernel/module-plts.c
[ ... ]
> @@ -169,17 +167,17 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num,
> case R_AARCH64_CALL26:
> /*
> * We only have to consider branch targets that resolve
> - * to symbols that are defined in a different section.
> + * to symbols that are not defined in the same module.
> * This is not simply a heuristic, it is a fundamental
> * limitation, since there is no guaranteed way to emit
> * PLT entries sufficiently close to the branch if the
> * section size exceeds the range of a branch
> * instruction. So ignore relocations against defined
> - * symbols if they live in the same section as the
> + * symbols if they live in the same module as the
> * relocation target.
> */
[Severity: High]
Does this safely account for memory pressure during module loading?
While this patch expects .init.text and .text to be placed within direct
branching range, kernel/module/main.c:module_memory_alloc() attempts to
enforce this by using execmem_split().
If execmem_split() fails, such as a mas_store_gfp() failure under memory
pressure, module_memory_alloc() falls back to an independent
execmem_alloc_rw() allocation. Because MODULES_VSIZE on ARM64 is 2GB,
couldn't this fallback place the init section more than 128MB away from
the core section?
If that happens, intra-module calls would exceed the architectural range.
Since this patch removes the PLT entries for them, wouldn't the module
load fail with a WARN_ON in module_emit_plt_entry() and abort the load?
> s = syms + ELF64_R_SYM(rela[i].r_info);
> - if (s->st_shndx == dstidx)
> + if (s->st_shndx != SHN_UNDEF)
> break;
[Severity: High]
Will this skip PLT allocations for special symbols like SHN_LIVEPATCH and
SHN_ABS?
When a livepatch module is loaded, its symbols are marked with SHN_LIVEPATCH
(0xff20) by objtool. Since SHN_LIVEPATCH is not SHN_UNDEF, this check evaluates
to true, breaking the loop and skipping PLT allocation for these symbols.
Later, when klp_apply_section_relocs() attempts to apply the .klp.rela.*
relocations against vmlinux, out-of-range branches will need a PLT entry.
Since none were allocated, won't module_emit_plt_entry() hit the WARN_ON
for exceeding pltsec->plt_max_entries and abort the load with -ENOEXEC?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822135323.795946-11-ardb+git@google.com?part=8
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text
2026-08-22 13:53 ` [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text Ard Biesheuvel
@ 2026-08-22 14:13 ` sashiko-bot
2026-08-23 16:46 ` Adrian Barnaś
1 sibling, 0 replies; 17+ messages in thread
From: sashiko-bot @ 2026-08-22 14:13 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-trace-kernel, linux-modules
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] `execmem_fill_trapping_insns()` writes trapping instructions using `memset32()` with a host-endian constant, producing incorrect/unallocated instructions on big-endian ARM64 kernels.
- [High] `execmem_fill_trapping_insns()` fails to synchronize D/I caches to the Point of Unification (PoU), potentially causing execution of random uninitialized garbage.
- [Low] The function `system_supports_bbml2_noabort()` is called but is completely undefined in the kernel tree.
--
--- Patch [6]: [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text ---
commit 9f2855ae0653215694678b01c1ed088b2dce033c
Author: Ard Biesheuvel <ardb@kernel.org>
arm64: Enable the execmem ROX cache for module text
This commit wires up execmem ROX cache support on arm64 for module text and
init.text regions. This allows these regions to be allocated from a single
chunk of memory in subsequent changes.
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 3b9e1b8de6cbd..40088d362f6c7 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
[ ... ]
> @@ -557,9 +558,25 @@ struct execmem_info __init *execmem_arch_setup(void)
[ ... ]
> };
>
> + if (!system_supports_bbml2_noabort())
[Severity: Low]
Does system_supports_bbml2_noabort() exist in the kernel tree? It appears
this might cause a compilation error due to an undefined reference.
> + execmem_info.ranges[EXECMEM_DEFAULT].flags |= EXECMEM_NO_HUGE_VMAP;
> +
> return &execmem_info;
> }
> +
> +void execmem_fill_trapping_insns(void *ptr, size_t size)
> +{
> + memset32(ptr, AARCH64_BREAK_FAULT, size / sizeof(__le32));
[Severity: High]
Does this correctly handle big-endian ARM64 kernels?
Since AARCH64_BREAK_FAULT is a host-endian constant and instruction fetches
are strictly little-endian, it looks like this might write an incorrect byte
pattern and execute unallocated instructions instead of the intended trap if
cpu_to_le32() isn't used.
[Severity: High]
Does this missing cache synchronization allow the CPU to fetch stale
instructions?
Writing instructions as data requires cleaning the D-cache and invalidating
the I-cache to the Point of Unification (PoU) (e.g., using
flush_icache_range()). Otherwise, the CPU might bypass the newly written trap
instructions and fetch garbage from physical memory or the I-cache.
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822135323.795946-11-ardb+git@google.com?part=6
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text
2026-08-22 13:53 ` [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text Ard Biesheuvel
2026-08-22 14:13 ` sashiko-bot
@ 2026-08-23 16:46 ` Adrian Barnaś
1 sibling, 0 replies; 17+ messages in thread
From: Adrian Barnaś @ 2026-08-23 16:46 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-kernel, Ard Biesheuvel, Catalin Marinas, Will Deacon,
Steven Rostedt, Masami Hiramatsu, Mark Rutland, Andrew Morton,
Mike Rapoport, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
Sami Tolvanen, Aaron Tomlin, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
On Sat, Aug 22, 2026 at 03:53:28PM +0200, Ard Biesheuvel wrote:
>From: Ard Biesheuvel <ardb@kernel.org>
>
>Wire up the existing support for the execmem ROX cache on arm64, so that
>it will be used for module .text and .init.text regions. This will be
>relied upon by a subsequent patch in order to allocate those regions
>from a single chunk of memory.
>
Until Mike lands his changes [1] on set_direct_map, enabling ROX_CACHE on
ARM64 would cause a permission fault when the same part of the direct map is
used again (the RO flag is not properly stripped off after an execmem cache
clean).
[1]: https://lore.kernel.org/all/20260823-execmem-set-vm-perms-v0-2-v2-0-b013a37d84b3@kernel.org/
Best regards,
Adrian
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings
2026-08-22 13:53 ` [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings Ard Biesheuvel
2026-08-22 14:10 ` sashiko-bot
@ 2026-08-23 16:52 ` Adrian Barnaś
1 sibling, 0 replies; 17+ messages in thread
From: Adrian Barnaś @ 2026-08-23 16:52 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-kernel, Ard Biesheuvel, Catalin Marinas, Will Deacon,
Steven Rostedt, Masami Hiramatsu, Mark Rutland, Andrew Morton,
Mike Rapoport, Luis Chamberlain, Petr Pavlu, Daniel Gomez,
Sami Tolvanen, Aaron Tomlin, Ryan Roberts, Kevin Brodsky,
linux-arm-kernel, linux-trace-kernel, linux-mm, linux-modules
Hi Ard
On Sat, Aug 22, 2026 at 03:53:27PM +0200, Ard Biesheuvel wrote:
>From: Ard Biesheuvel <ardb@kernel.org>
>
>Allow permission changes on huge vmappings in cases where no splitting
>is needed (i.e., the region is aligned sufficiently), or when the system
>has support for splitting live mappings.
>
>Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>---
> arch/arm64/mm/pageattr.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
>diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
>index bbe98ac9ad8c..20ff9cb273c1 100644
>--- a/arch/arm64/mm/pageattr.c
>+++ b/arch/arm64/mm/pageattr.c
>@@ -169,8 +169,6 @@ static int change_memory_common(unsigned long addr, int numpages,
> * we are operating on does not result in such splitting.
> *
> * Let's restrict ourselves to mappings created by vmalloc (or vmap).
>- * Disallow VM_ALLOW_HUGE_VMAP mappings to guarantee that only page
>- * mappings are updated and splitting is never needed.
> *
> * So check whether the [addr, addr + size) interval is entirely
> * covered by precisely one VM area that has the VM_ALLOC flag set.
>@@ -179,7 +177,16 @@ static int change_memory_common(unsigned long addr, int numpages,
> if (!area ||
> ((unsigned long)kasan_reset_tag((void *)end) >
> (unsigned long)kasan_reset_tag(area->addr) + area->size) ||
>- ((area->flags & (VM_ALLOC | VM_ALLOW_HUGE_VMAP)) != VM_ALLOC))
>+ !(area->flags & VM_ALLOC))
>+ return -EINVAL;
>+
>+ /*
>+ * Disallow VM_ALLOW_HUGE_VMAP mappings unless the region is PMD
>+ * aligned, or splitting live huge mappings is supported.
>+ */
>+ if ((area->flags & VM_ALLOW_HUGE_VMAP) &&
>+ ((start % PMD_SIZE) || (size % PMD_SIZE)) &&
If I understand the intention here correctly, I don't think it is valid. Even
if it is PMD-sized and PMD-aligned, it would still cause a split because
the loop below is not using page order, but performs attribute changes
page by page.
Best regards,
Adrian
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-08-23 16:52 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-22 13:53 [RFC PATCH 0/9] arm64: Allocate .text and .init.text together Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 1/9] mm: execmem: Add API to split an existing execmem cache allocation Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 2/9] mm: execmem: Allow huge vmappings to be avoided for execmem caches Ard Biesheuvel
2026-08-22 14:10 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 3/9] module: Place MOD_TEXT before MOD_INIT_TEXT in enumeration Ard Biesheuvel
2026-08-22 14:05 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 4/9] module: Allocate MOD_INIT_TEXT from the MOD_TEXT ROX allocation Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 5/9] arm64: mm: Permit permissions changes on huge vmappings Ard Biesheuvel
2026-08-22 14:10 ` sashiko-bot
2026-08-23 16:52 ` Adrian Barnaś
2026-08-22 13:53 ` [RFC PATCH 6/9] arm64: Enable the execmem ROX cache for module text Ard Biesheuvel
2026-08-22 14:13 ` sashiko-bot
2026-08-23 16:46 ` Adrian Barnaś
2026-08-22 13:53 ` [RFC PATCH 7/9] arm64: ftrace: Revert "fix unreachable PLT for ftrace_caller ..." Ard Biesheuvel
2026-08-22 13:53 ` [RFC PATCH 8/9] arm64: module: Combine init and core PLT entries again Ard Biesheuvel
2026-08-22 14:12 ` sashiko-bot
2026-08-22 13:53 ` [RFC PATCH 9/9] arm64: ftrace: Simplify PLT handling Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox