diff options
| author | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 09:55:01 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 11:08:21 -0400 |
| commit | 4617721c502b2ddaa4e324e86da4997edf738fa5 (patch) | |
| tree | 350aa83b47da0b574a814795392b20b0bed83cbc /arch/m68k/mm/init.c | |
| download | linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.tar.gz linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.zip | |
ftrace: Synchronize the initialization of ftrace_opsgrafted
There's some internal state that ftrace_ops needs to have set, but since
it can be declared outside of the ftrace.c code, it calls
ftrace_ops_init() on the ops in every global function. The issue is that
if two tasks call it on the same ops at the same time it is possible to
have the initialization of one corrupt the initialization of the other
call.
Create a ops_mutex to use to synchronize every initialization of the
ftrace_ops. The mutex is taken within checking the ftrace_ops flag that
states it was initializied but the flag is checked again after the mutex
has been taken. Checking first outside the mutex allows it to shortcut
having to take the mutex. But then the check needs to be done again after
the mute is taken in case of races.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home
Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock")
Reported-by: sashiko-bot@kernel.org
Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'arch/m68k/mm/init.c')
| -rw-r--r-- | arch/m68k/mm/init.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c new file mode 100644 index 000000000..3b88c0dd1 --- /dev/null +++ b/arch/m68k/mm/init.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * linux/arch/m68k/mm/init.c + * + * Copyright (C) 1995 Hamish Macdonald + * + * Contains common initialization routines, specific init code moved + * to motorola.c and sun3mmu.c + */ + +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/memblock.h> +#include <linux/gfp.h> + +#include <asm/setup.h> +#include <linux/uaccess.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <asm/traps.h> +#include <asm/machdep.h> +#include <asm/io.h> +#ifdef CONFIG_ATARI +#include <asm/atari_stram.h> +#endif +#include <asm/sections.h> +#include <asm/tlb.h> + +void __init arch_zone_limits_init(unsigned long *max_zone_pfns) +{ + max_zone_pfns[ZONE_DMA] = PFN_DOWN(memblock_end_of_DRAM()); +} + +#ifdef CONFIG_MMU + +int m68k_virt_to_node_shift; + +void __init m68k_setup_node(int node) +{ + node_set_online(node); +} + +#else /* CONFIG_MMU */ + +/* + * paging_init() continues the virtual memory environment setup which + * was begun by the code in arch/head.S. + * The parameters are pointers to where to stick the starting and ending + * addresses of available kernel virtual memory. + */ +void __init paging_init(void) +{ + /* + * Make sure start_mem is page aligned, otherwise bootmem and + * page_alloc get different views of the world. + */ + unsigned long end_mem = memory_end & PAGE_MASK; + + high_memory = (void *) end_mem; +} + +#endif /* CONFIG_MMU */ + +void free_initmem(void) +{ +#ifndef CONFIG_MMU_SUN3 + free_initmem_default(-1); +#endif /* CONFIG_MMU_SUN3 */ +} + +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) +#define VECTORS &vectors[0] +#else +#define VECTORS _ramvec +#endif + +static inline void init_pointer_tables(void) +{ +#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) + int i, j; + + /* insert pointer tables allocated so far into the tablelist */ + init_pointer_table(kernel_pg_dir, TABLE_PGD); + for (i = 0; i < PTRS_PER_PGD; i++) { + pud_t *pud = (pud_t *)&kernel_pg_dir[i]; + pmd_t *pmd_dir; + + if (!pud_present(*pud)) + continue; + + pmd_dir = (pmd_t *)pgd_page_vaddr(kernel_pg_dir[i]); + init_pointer_table(pmd_dir, TABLE_PMD); + + for (j = 0; j < PTRS_PER_PMD; j++) { + pmd_t *pmd = &pmd_dir[j]; + pte_t *pte_dir; + + if (!pmd_present(*pmd)) + continue; + + pte_dir = (pte_t *)pmd_page_vaddr(*pmd); + init_pointer_table(pte_dir, TABLE_PTE); + } + } +#endif +} + +void __init mem_init(void) +{ + init_pointer_tables(); +} |
