@@ -112,6 +112,7 @@ subsys_initcall(module_init_limits);
void *module_alloc(unsigned long size)
{
+ u64 module_direct_end, module_plt_end;
void *p = NULL;
/*
@@ -119,18 +120,33 @@ void *module_alloc(unsigned long size)
* kernel such that no PLTs are necessary.
*/
if (module_direct_base) {
+#ifdef CONFIG_REPLICATE_KTEXT
+ /*
+ * Kernel text replication requires an L0 page table entry to
+ * be exclusive to kernel text, so no other mappings should be
+ * shared with it.
+ */
+ module_direct_end = MODULES_END;
+#else
+ module_direct_end = module_direct_base + SZ_128M;
+#endif
p = __vmalloc_node_range(size, MODULE_ALIGN,
module_direct_base,
- module_direct_base + SZ_128M,
+ module_direct_end,
GFP_KERNEL | __GFP_NOWARN,
PAGE_KERNEL, 0, NUMA_NO_NODE,
__builtin_return_address(0));
}
if (!p && module_plt_base) {
+#ifdef CONFIG_REPLICATE_KTEXT
+ module_plt_end = MODULES_END;
+#else
+ module_plt_end = module_plt_base + SZ_2G;
+#endif
p = __vmalloc_node_range(size, MODULE_ALIGN,
module_plt_base,
- module_plt_base + SZ_2G,
+ module_plt_end,
GFP_KERNEL | __GFP_NOWARN,
PAGE_KERNEL, 0, NUMA_NO_NODE,
__builtin_return_address(0));
Kernel text replication requires maintaining a separate per-node page table for kernel text. To accomplish this without affecting other kernel memory maps, it is best to place the kernel in a location that does not share L0 page table entries with any other mappings. So, limit the module_alloc() address range so that they do not overlap. Signed-off-by: Hao Jia <jiahao.os@bytedance.com> --- arch/arm64/kernel/module.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)