[PATCH] x86/alternative: delay freeing of smp_locks section
From: Mike Rapoport
Date: Sat Mar 28 2026 - 04:17:19 EST
From: "Mike Rapoport (Microsoft)" <rppt@xxxxxxxxxx>
On UP systems alternative_instructions() frees memory occupied by smp_locks
section immediately after patching the lock instructions.
With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled this happens before the
memory map is fully initialized and the struct pages representing the freed
memory might get overwritten by deferred initialization of the memory map.
Move freeing of smp_locks section to an initcall to ensure it will happen
after the memory map is fully initialized.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
Tested-By: Bert Karwatzki <spasswolf@xxxxxx>
---
arch/x86/kernel/alternative.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index e87da25d1236..62936a3bde19 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2448,19 +2448,31 @@ void __init alternative_instructions(void)
__smp_locks, __smp_locks_end,
_text, _etext);
}
+#endif
+ restart_nmi();
+ alternatives_patched = 1;
+
+ alt_reloc_selftest();
+}
+
+#ifdef CONFIG_SMP
+/*
+ * With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled we can free_init_pages() only
+ * after the deferred initialization of the memory map is complete.
+ */
+static int __init free_smp_locks(void)
+{
if (!uniproc_patched || num_possible_cpus() == 1) {
free_init_pages("SMP alternatives",
(unsigned long)__smp_locks,
(unsigned long)__smp_locks_end);
}
-#endif
- restart_nmi();
- alternatives_patched = 1;
-
- alt_reloc_selftest();
+ return 0;
}
+arch_initcall(free_smp_locks);
+#endif
/**
* text_poke_early - Update instructions on a live kernel at boot time
base-commit: e77a5a5cfe43b4c25bd44a3818e487033287517f
--
2.53.0