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/arm/mm/cache-v4.S | |
| 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/arm/mm/cache-v4.S')
| -rw-r--r-- | arch/arm/mm/cache-v4.S | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S new file mode 100644 index 000000000..001d7042b --- /dev/null +++ b/arch/arm/mm/cache-v4.S @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * linux/arch/arm/mm/cache-v4.S + * + * Copyright (C) 1997-2002 Russell king + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <linux/cfi_types.h> +#include <asm/assembler.h> +#include <asm/page.h> +#include "proc-macros.S" + +/* + * flush_icache_all() + * + * Unconditionally clean and invalidate the entire icache. + */ +SYM_TYPED_FUNC_START(v4_flush_icache_all) + ret lr +SYM_FUNC_END(v4_flush_icache_all) + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + * + * - mm - mm_struct describing address space + */ +SYM_FUNC_ALIAS(v4_flush_user_cache_all, v4_flush_kern_cache_all) + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +SYM_TYPED_FUNC_START(v4_flush_kern_cache_all) +#ifdef CONFIG_CPU_CP15 + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ flush ID cache + ret lr +#else + ret lr +#endif +SYM_FUNC_END(v4_flush_kern_cache_all) + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vma_area_struct flags describing address space + */ +SYM_TYPED_FUNC_START(v4_flush_user_cache_range) +#ifdef CONFIG_CPU_CP15 + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ flush ID cache + ret lr +#else + ret lr +#endif +SYM_FUNC_END(v4_flush_user_cache_range) + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +SYM_TYPED_FUNC_START(v4_coherent_kern_range) + ret lr +SYM_FUNC_END(v4_coherent_kern_range) + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +SYM_TYPED_FUNC_START(v4_coherent_user_range) + mov r0, #0 + ret lr +SYM_FUNC_END(v4_coherent_user_range) + +/* + * flush_kern_dcache_area(void *addr, size_t size) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - kernel address + * - size - region size + */ +SYM_TYPED_FUNC_START(v4_flush_kern_dcache_area) +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ + b v4_dma_flush_range +#endif +SYM_FUNC_END(v4_flush_kern_dcache_area) + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +SYM_TYPED_FUNC_START(v4_dma_flush_range) +#ifdef CONFIG_CPU_CP15 + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ flush ID cache +#endif + ret lr +SYM_FUNC_END(v4_dma_flush_range) + +/* + * dma_unmap_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +SYM_TYPED_FUNC_START(v4_dma_unmap_area) + teq r2, #DMA_TO_DEVICE + bne v4_dma_flush_range + ret lr +SYM_FUNC_END(v4_dma_unmap_area) + +/* + * dma_map_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +SYM_TYPED_FUNC_START(v4_dma_map_area) + ret lr +SYM_FUNC_END(v4_dma_map_area) |
