arch/um/kernel/um_arch.c | 12 -- arch/x86/include/asm/alternative.h | 47 +------ arch/x86/include/asm/cmpxchg_32.h | 4 +- arch/x86/kernel/alternative.c | 190 ----------------------------- arch/x86/kernel/kprobes/core.c | 3 - arch/x86/kernel/kprobes/opt.c | 1 - arch/x86/kernel/module.c | 13 +- arch/x86/kernel/smpboot.c | 3 - arch/x86/kernel/vmlinux.lds.S | 12 -- arch/x86/tools/relocs.c | 2 +- tools/objtool/check.c | 1 - tools/objtool/klp-diff.c | 1 - 12 files changed, 9 insertions(+), 280 deletions(-)
From: "Borislav Petkov (AMD)" <bp@alien8.de>
Date: Sat, 13 Jun 2026 10:15:27 -0700
This was there to be able to patch out locking instructions when running
a SMP kernel build on a UP CPU. The times are long gone when single-CPU
x86 machines were relevant so drop that machinery and simplify the code
considerably.
LOCK_PREFIX needs to stay for when one wants to do a UP build for
whatever reason. That'll go away when CONFIG_SMP becomes unconditional.
Kill a bunch of leftover, unused prototypes while at it.
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
---
arch/um/kernel/um_arch.c | 12 --
arch/x86/include/asm/alternative.h | 47 +------
arch/x86/include/asm/cmpxchg_32.h | 4 +-
arch/x86/kernel/alternative.c | 190 -----------------------------
arch/x86/kernel/kprobes/core.c | 3 -
arch/x86/kernel/kprobes/opt.c | 1 -
arch/x86/kernel/module.c | 13 +-
arch/x86/kernel/smpboot.c | 3 -
arch/x86/kernel/vmlinux.lds.S | 12 --
arch/x86/tools/relocs.c | 2 +-
tools/objtool/check.c | 1 -
tools/objtool/klp-diff.c | 1 -
12 files changed, 9 insertions(+), 280 deletions(-)
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 2141f5f1f5a2..e4ee693961e4 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -451,18 +451,6 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
{
}
-#if IS_ENABLED(CONFIG_SMP)
-void alternatives_smp_module_add(struct module *mod, char *name,
- void *locks, void *locks_end,
- void *text, void *text_end)
-{
-}
-
-void alternatives_smp_module_del(struct module *mod)
-{
-}
-#endif
-
void *text_poke(void *addr, const void *opcode, size_t len)
{
/*
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 03364510d5fe..b1116c893345 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -42,17 +42,8 @@
*/
#ifdef CONFIG_SMP
-#define LOCK_PREFIX_HERE \
- ".pushsection .smp_locks,\"a\"\n" \
- ".balign 4\n" \
- ".long 671f - .\n" /* offset */ \
- ".popsection\n" \
- "671:"
-
-#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock "
-
-#else /* ! CONFIG_SMP */
-#define LOCK_PREFIX_HERE ""
+#define LOCK_PREFIX "lock "
+#else
#define LOCK_PREFIX ""
#endif
@@ -87,7 +78,6 @@ extern s32 __retpoline_sites[], __retpoline_sites_end[];
extern s32 __return_sites[], __return_sites_end[];
extern s32 __cfi_sites[], __cfi_sites_end[];
extern s32 __ibt_endbr_seal[], __ibt_endbr_seal_end[];
-extern s32 __smp_locks[], __smp_locks_end[];
/*
* Debug flag that can be tested to see whether alternative
@@ -162,26 +152,6 @@ static __always_inline bool cpu_wants_rethunk_at(void *addr)
}
#endif
-#ifdef CONFIG_SMP
-extern void alternatives_smp_module_add(struct module *mod, char *name,
- void *locks, void *locks_end,
- void *text, void *text_end);
-extern void alternatives_smp_module_del(struct module *mod);
-extern void alternatives_enable_smp(void);
-extern int alternatives_text_reserved(void *start, void *end);
-extern bool skip_smp_alternatives;
-#else
-static inline void alternatives_smp_module_add(struct module *mod, char *name,
- void *locks, void *locks_end,
- void *text, void *text_end) {}
-static inline void alternatives_smp_module_del(struct module *mod) {}
-static inline void alternatives_enable_smp(void) {}
-static inline int alternatives_text_reserved(void *start, void *end)
-{
- return 0;
-}
-#endif /* CONFIG_SMP */
-
#define ALT_CALL_INSTR "call BUG_func"
#define alt_slen "772b-771b"
@@ -319,18 +289,11 @@ void nop_func(void);
#else /* __ASSEMBLER__ */
+.macro LOCK_PREFIX
#ifdef CONFIG_SMP
- .macro LOCK_PREFIX
-672: lock
- .pushsection .smp_locks,"a"
- .balign 4
- .long 672b - .
- .popsection
- .endm
-#else
- .macro LOCK_PREFIX
- .endm
+ lock
#endif
+ .endm
/*
* Issue one struct alt_instr descriptor entry (need to put it into
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 1f80a62be969..e85c221ed1c9 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -104,7 +104,7 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp,
static __always_inline u64 arch_cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
{
- return __arch_cmpxchg64_emu(ptr, old, new, LOCK_PREFIX_HERE, "lock ");
+ return __arch_cmpxchg64_emu(ptr, old, new, , "lock ");
}
#define arch_cmpxchg64 arch_cmpxchg64
@@ -138,7 +138,7 @@ static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64
static __always_inline bool arch_try_cmpxchg64(volatile u64 *ptr, u64 *oldp, u64 new)
{
- return __arch_try_cmpxchg64_emu(ptr, oldp, new, LOCK_PREFIX_HERE, "lock ");
+ return __arch_try_cmpxchg64_emu(ptr, oldp, new, , "lock ");
}
#define arch_try_cmpxchg64 arch_try_cmpxchg64
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 62936a3bde19..bf717b4159ba 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -41,15 +41,6 @@ static int __init debug_alt(char *str)
}
__setup("debug-alternative", debug_alt);
-static int noreplace_smp;
-
-static int __init setup_noreplace_smp(char *str)
-{
- noreplace_smp = 1;
- return 1;
-}
-__setup("noreplace-smp", setup_noreplace_smp);
-
#define DPRINTK(type, fmt, args...) \
do { \
if (debug_alternative & DA_##type) \
@@ -2109,159 +2100,6 @@ void apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
/* .builtin = */ false);
}
-#ifdef CONFIG_SMP
-static void alternatives_smp_lock(const s32 *start, const s32 *end,
- u8 *text, u8 *text_end)
-{
- const s32 *poff;
-
- for (poff = start; poff < end; poff++) {
- u8 *ptr = (u8 *)poff + *poff;
-
- if (!*poff || ptr < text || ptr >= text_end)
- continue;
- /* turn DS segment override prefix into lock prefix */
- if (*ptr == 0x3e)
- text_poke(ptr, ((unsigned char []){0xf0}), 1);
- }
-}
-
-static void alternatives_smp_unlock(const s32 *start, const s32 *end,
- u8 *text, u8 *text_end)
-{
- const s32 *poff;
-
- for (poff = start; poff < end; poff++) {
- u8 *ptr = (u8 *)poff + *poff;
-
- if (!*poff || ptr < text || ptr >= text_end)
- continue;
- /* turn lock prefix into DS segment override prefix */
- if (*ptr == 0xf0)
- text_poke(ptr, ((unsigned char []){0x3E}), 1);
- }
-}
-
-struct smp_alt_module {
- /* what is this ??? */
- struct module *mod;
- char *name;
-
- /* ptrs to lock prefixes */
- const s32 *locks;
- const s32 *locks_end;
-
- /* .text segment, needed to avoid patching init code ;) */
- u8 *text;
- u8 *text_end;
-
- struct list_head next;
-};
-static LIST_HEAD(smp_alt_modules);
-static bool uniproc_patched = false; /* protected by text_mutex */
-
-void __init_or_module alternatives_smp_module_add(struct module *mod,
- char *name,
- void *locks, void *locks_end,
- void *text, void *text_end)
-{
- struct smp_alt_module *smp;
-
- mutex_lock(&text_mutex);
- if (!uniproc_patched)
- goto unlock;
-
- if (num_possible_cpus() == 1)
- /* Don't bother remembering, we'll never have to undo it. */
- goto smp_unlock;
-
- smp = kzalloc_obj(*smp);
- if (NULL == smp)
- /* we'll run the (safe but slow) SMP code then ... */
- goto unlock;
-
- smp->mod = mod;
- smp->name = name;
- smp->locks = locks;
- smp->locks_end = locks_end;
- smp->text = text;
- smp->text_end = text_end;
- DPRINTK(SMP, "locks %p -> %p, text %p -> %p, name %s\n",
- smp->locks, smp->locks_end,
- smp->text, smp->text_end, smp->name);
-
- list_add_tail(&smp->next, &smp_alt_modules);
-smp_unlock:
- alternatives_smp_unlock(locks, locks_end, text, text_end);
-unlock:
- mutex_unlock(&text_mutex);
-}
-
-void __init_or_module alternatives_smp_module_del(struct module *mod)
-{
- struct smp_alt_module *item;
-
- mutex_lock(&text_mutex);
- list_for_each_entry(item, &smp_alt_modules, next) {
- if (mod != item->mod)
- continue;
- list_del(&item->next);
- kfree(item);
- break;
- }
- mutex_unlock(&text_mutex);
-}
-
-void alternatives_enable_smp(void)
-{
- struct smp_alt_module *mod;
-
- /* Why bother if there are no other CPUs? */
- BUG_ON(num_possible_cpus() == 1);
-
- mutex_lock(&text_mutex);
-
- if (uniproc_patched) {
- pr_info("switching to SMP code\n");
- BUG_ON(num_online_cpus() != 1);
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP);
- clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP);
- list_for_each_entry(mod, &smp_alt_modules, next)
- alternatives_smp_lock(mod->locks, mod->locks_end,
- mod->text, mod->text_end);
- uniproc_patched = false;
- }
- mutex_unlock(&text_mutex);
-}
-
-/*
- * Return 1 if the address range is reserved for SMP-alternatives.
- * Must hold text_mutex.
- */
-int alternatives_text_reserved(void *start, void *end)
-{
- struct smp_alt_module *mod;
- const s32 *poff;
- u8 *text_start = start;
- u8 *text_end = end;
-
- lockdep_assert_held(&text_mutex);
-
- list_for_each_entry(mod, &smp_alt_modules, next) {
- if (mod->text > text_end || mod->text_end < text_start)
- continue;
- for (poff = mod->locks; poff < mod->locks_end; poff++) {
- const u8 *ptr = (const u8 *)poff + *poff;
-
- if (text_start <= ptr && text_end > ptr)
- return 1;
- }
- }
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
/*
* Self-test for the INT3 based CALL emulation code.
*
@@ -2440,40 +2278,12 @@ void __init alternative_instructions(void)
ibt_restore(ibt);
-#ifdef CONFIG_SMP
- /* Patch to UP if other cpus not imminent. */
- if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) {
- uniproc_patched = true;
- alternatives_smp_module_add(NULL, "core kernel",
- __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);
- }
-
- return 0;
-}
-arch_initcall(free_smp_locks);
-#endif
-
/**
* text_poke_early - Update instructions on a live kernel at boot time
* @addr: address to modify
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index c1fac3a9fecc..4e5f8c1736ec 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -762,9 +762,6 @@ int arch_prepare_kprobe(struct kprobe *p)
{
int ret;
- if (alternatives_text_reserved(p->addr, p->addr))
- return -EINVAL;
-
if (!can_probe((unsigned long)p->addr))
return -EILSEQ;
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index 6f826a00eca2..6e5f1b8a158c 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -213,7 +213,6 @@ static int copy_optimized_instructions(u8 *dest, u8 *src, u8 *real)
}
/* Check whether the address range is reserved */
if (ftrace_text_reserved(src, src + len - 1) ||
- alternatives_text_reserved(src, src + len - 1) ||
jump_label_text_reserved(src, src + len - 1) ||
static_call_text_reserved(src, src + len - 1))
return -EBUSY;
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 11c45ce42694..9a4b766eaf4c 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -242,7 +242,7 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- const Elf_Shdr *s, *alt = NULL, *locks = NULL,
+ const Elf_Shdr *s, *alt = NULL,
*orc = NULL, *orc_ip = NULL,
*retpolines = NULL, *returns = NULL, *ibt_endbr = NULL,
*calls = NULL, *cfi = NULL;
@@ -251,8 +251,6 @@ int module_finalize(const Elf_Ehdr *hdr,
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (!strcmp(".altinstructions", secstrings + s->sh_name))
alt = s;
- if (!strcmp(".smp_locks", secstrings + s->sh_name))
- locks = s;
if (!strcmp(".orc_unwind", secstrings + s->sh_name))
orc = s;
if (!strcmp(".orc_unwind_ip", secstrings + s->sh_name))
@@ -315,14 +313,6 @@ int module_finalize(const Elf_Ehdr *hdr,
void *iseg = (void *)ibt_endbr->sh_addr;
apply_seal_endbr(iseg, iseg + ibt_endbr->sh_size);
}
- if (locks) {
- void *lseg = (void *)locks->sh_addr;
- void *text = me->mem[MOD_TEXT].base;
- void *text_end = text + me->mem[MOD_TEXT].size;
- alternatives_smp_module_add(me, me->name,
- lseg, lseg + locks->sh_size,
- text, text_end);
- }
if (orc && orc_ip)
unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size,
@@ -333,6 +323,5 @@ int module_finalize(const Elf_Ehdr *hdr,
void module_arch_cleanup(struct module *mod)
{
- alternatives_smp_module_del(mod);
its_free_mod(mod);
}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index cb999feb66b0..ba01a9e919b7 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -991,9 +991,6 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
{
int ret;
- /* Just in case we booted with a single CPU. */
- alternatives_enable_smp();
-
per_cpu(current_task, cpu) = idle;
cpu_init_stack_canary(cpu, idle);
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 4711a35e706c..273e7845b411 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -346,18 +346,6 @@ SECTIONS
__init_end = .;
}
- /*
- * smp_locks might be freed after init
- * start/end must be page aligned
- */
- . = ALIGN(PAGE_SIZE);
- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
- __smp_locks = .;
- *(.smp_locks)
- . = ALIGN(PAGE_SIZE);
- __smp_locks_end = .;
- }
-
#ifdef CONFIG_X86_64
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
NOSAVE_DATA
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index e5a2b9a912d1..5ea9bc7eeb14 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -73,7 +73,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
"^(__init_(begin|end)|"
"__x86_cpu_dev_(start|end)|"
"__alt_instructions(_end)?|"
- "(__iommu_table|__apicdrivers|__smp_locks)(_end)?|"
+ "(__iommu_table|__apicdrivers)(_end)?|"
"__(start|end)_pci_.*|"
#if CONFIG_FW_LOADER
"__(start|end)_builtin_fw|"
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 10b18cf9c360..5f714e8b383a 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -4644,7 +4644,6 @@ static int validate_ibt(struct objtool_file *file)
!strcmp(sec->name, ".kcfi_traps") ||
!strcmp(sec->name, ".orc_unwind_ip") ||
!strcmp(sec->name, ".retpoline_sites") ||
- !strcmp(sec->name, ".smp_locks") ||
!strcmp(sec->name, ".static_call_sites") ||
!strcmp(sec->name, "_error_injection_whitelist") ||
!strcmp(sec->name, "_kprobe_blacklist") ||
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index f8787d7d1454..07b7ef34cc92 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -297,7 +297,6 @@ static bool is_special_section(struct section *sec)
static const char * const specials[] = {
".altinstructions",
".kcfi_traps",
- ".smp_locks",
"__bug_table",
"__ex_table",
"__jump_table",
--
2.53.0
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Sat, Jun 13, 2026 at 11:56:32AM -0700, Borislav Petkov wrote: > From: "Borislav Petkov (AMD)" <bp@alien8.de> > Date: Sat, 13 Jun 2026 10:15:27 -0700 > > This was there to be able to patch out locking instructions when running > a SMP kernel build on a UP CPU. The times are long gone when single-CPU > x86 machines were relevant so drop that machinery and simplify the code > considerably. > > LOCK_PREFIX needs to stay for when one wants to do a UP build for > whatever reason. That'll go away when CONFIG_SMP becomes unconditional. > > Kill a bunch of leftover, unused prototypes while at it. > > Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Good riddance Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
© 2016 - 2026 Red Hat, Inc.