From 100b3087fc0baa649179ac56a1df7a53e41de436 Mon Sep 17 00:00:00 2001 From: Tushar Mohapatra Date: Mon, 16 Feb 2026 10:50:16 +0530 Subject: [PATCH] compel/x86: probe kernel task_size at runtime Change compel_task_size() to probe the actual kernel address space limit at runtime via mmap() with MAP_FIXED_NOREPLACE flag. On systems where the CPU supports 5-level paging but the kernel doesn't have it enabled, we need to detect the actual task size the kernel is using. On x86-64, task_size is either (1UL << 47) for 4-level paging or (1UL << 56) for 5-level paging. The function probes by attempting to mmap at the 4-level boundary and if it succeeds or the address is already occupied, the kernel supports 5-level paging. Fixes: #2877 Signed-off-by: Tushar Mohapatra --- compel/arch/x86/src/lib/infect.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c index afcf2c53b..6d5602ffe 100644 --- a/compel/arch/x86/src/lib/infect.c +++ b/compel/arch/x86/src/lib/infect.c @@ -17,6 +17,7 @@ #include #include #include "common/err.h" +#include "common/page.h" #include "asm/infect-types.h" #include "ptrace.h" #include "infect.h" @@ -738,7 +739,9 @@ int ptrace_set_regs(pid_t pid, user_regs_struct_t *regs) return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov); } -#define TASK_SIZE ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_47 ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_56 ((1UL << 56) - PAGE_SIZE) + /* * Task size may be limited to 3G but we need a * higher limit, because it's backward compatible. @@ -747,7 +750,23 @@ int ptrace_set_regs(pid_t pid, user_regs_struct_t *regs) unsigned long compel_task_size(void) { - return TASK_SIZE; + void *addr; + + /* + * On x86-64, task_size is either (1UL << 47) for 4-level paging + * or (1UL << 56) for 5-level paging. + */ + addr = mmap((void *)(TASK_SIZE_47), page_size(), PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, + -1, 0); + if (addr != MAP_FAILED) { + munmap(addr, page_size()); + return TASK_SIZE_56; + } + if (errno == EEXIST) + return TASK_SIZE_56; + + return TASK_SIZE_47; } bool __compel_shstk_enabled(user_fpregs_struct_t *ext_regs)