summaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2024-10-22 14:02:38 +0200
committerJohannes Berg <johannes.berg@intel.com>2024-10-23 09:04:59 +0200
commit14d4a7b516e993cf3926758a7ede569d8e119855 (patch)
tree73944a9852888a5207123438899c8aa684d39a0b /arch/um
parent8508a5e0e9db3932ca43651f86ba1042a1e9f4ca (diff)
um: make stub_exe _start() pure inline asm
Since __attribute__((naked)) cannot be used with functions containing C statements, just generate the few instructions it needs in assembly directly. While at it, fix the stack usage ("1 + 2*x - 1" is odd) and document what it must do, and why it must adjust the stack. Fixes: 8508a5e0e9db ("um: Fix misaligned stack in stub_exe") Link: https://lore.kernel.org/linux-um/CABVgOSntH-uoOFMP5HwMXjx_f1osMnVdhgKRKm4uz6DFm2Lb8Q@mail.gmail.com/ Reviewed-by: David Gow <davidgow@google.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/kernel/skas/stub_exe.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/um/kernel/skas/stub_exe.c b/arch/um/kernel/skas/stub_exe.c
index 722ce6267476..23c99b285e82 100644
--- a/arch/um/kernel/skas/stub_exe.c
+++ b/arch/um/kernel/skas/stub_exe.c
@@ -81,11 +81,15 @@ noinline static void real_init(void)
__attribute__((naked)) void _start(void)
{
- char *alloc;
-
- /* Make enough space for the stub (including space for alignment) */
- alloc = __builtin_alloca((1 + 2 * STUB_DATA_PAGES - 1) * UM_KERN_PAGE_SIZE);
- asm volatile("" : "+r,m"(alloc) : : "memory");
-
- real_init();
+ /*
+ * Since the stack after exec() starts at the top-most address,
+ * but that's exactly where we also want to map the stub data
+ * and code, this must:
+ * - push the stack by 1 code and STUB_DATA_PAGES data pages
+ * - call real_init()
+ * This way, real_init() can use the stack normally, while the
+ * original stack further down (higher address) will become
+ * inaccessible after the mmap() calls above.
+ */
+ stub_start(real_init);
}