diff options
| author | Ingo Molnar <mingo@kernel.org> | 2026-07-28 10:09:39 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2026-07-28 10:09:39 +0200 |
| commit | 1f440b288b6282f33a8e2be34b38cf4776ffa69a (patch) | |
| tree | 8e8f71b1f75655d217173f55d9655ce26cf198a8 /arch/x86/kernel | |
| parent | 5bf709e5de4e0f861f5f3b2e8316984f0da8a218 (diff) | |
| parent | 4a73b93ce489a58c9a2aac4a5f5cd8cfa58ced64 (diff) | |
| download | linux-next-1f440b288b6282f33a8e2be34b38cf4776ffa69a.tar.gz linux-next-1f440b288b6282f33a8e2be34b38cf4776ffa69a.zip | |
Merge branch into tip/master: 'x86/alternatives'
# New commits in x86/alternatives:
4a73b93ce489 ("x86/alternative: Drop smp_locks glue")
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/alternative.c | 190 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/core.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/opt.c | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/module.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 12 |
6 files changed, 1 insertions, 221 deletions
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 c994b0745983..3f8fea52619f 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 b5b4de4f08e6..33080ad889b7 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -227,7 +227,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; @@ -236,8 +236,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)) @@ -300,14 +298,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, @@ -318,6 +308,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 81e113eb7c7c..e371a439deb6 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 |
