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 /drivers/soc/gemini | |
| 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 'drivers/soc/gemini')
| -rw-r--r-- | drivers/soc/gemini/Makefile | 2 | ||||
| -rw-r--r-- | drivers/soc/gemini/soc-gemini.c | 71 |
2 files changed, 73 insertions, 0 deletions
diff --git a/drivers/soc/gemini/Makefile b/drivers/soc/gemini/Makefile new file mode 100644 index 000000000..8cbd1e45d --- /dev/null +++ b/drivers/soc/gemini/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-y += soc-gemini.o diff --git a/drivers/soc/gemini/soc-gemini.c b/drivers/soc/gemini/soc-gemini.c new file mode 100644 index 000000000..642b96c91 --- /dev/null +++ b/drivers/soc/gemini/soc-gemini.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Linaro Ltd. + * + * Author: Linus Walleij <linus.walleij@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> +#include <linux/of.h> + +#define GLOBAL_WORD_ID 0x00 +#define GEMINI_GLOBAL_ARB1_CTRL 0x2c +#define GEMINI_ARB1_BURST_MASK GENMASK(21, 16) +#define GEMINI_ARB1_BURST_SHIFT 16 +/* These all define the priority on the BUS2 backplane */ +#define GEMINI_ARB1_PRIO_MASK GENMASK(9, 0) +#define GEMINI_ARB1_DMAC_HIGH_PRIO BIT(0) +#define GEMINI_ARB1_IDE_HIGH_PRIO BIT(1) +#define GEMINI_ARB1_RAID_HIGH_PRIO BIT(2) +#define GEMINI_ARB1_SECURITY_HIGH_PRIO BIT(3) +#define GEMINI_ARB1_GMAC0_HIGH_PRIO BIT(4) +#define GEMINI_ARB1_GMAC1_HIGH_PRIO BIT(5) +#define GEMINI_ARB1_USB0_HIGH_PRIO BIT(6) +#define GEMINI_ARB1_USB1_HIGH_PRIO BIT(7) +#define GEMINI_ARB1_PCI_HIGH_PRIO BIT(8) +#define GEMINI_ARB1_TVE_HIGH_PRIO BIT(9) + +#define GEMINI_DEFAULT_BURST_SIZE 0x20 +#define GEMINI_DEFAULT_PRIO (GEMINI_ARB1_GMAC0_HIGH_PRIO | \ + GEMINI_ARB1_GMAC1_HIGH_PRIO) + +static int __init gemini_soc_init(void) +{ + struct regmap *map; + u32 rev; + u32 val; + int ret; + + /* Multiplatform guard, only proceed on Gemini */ + if (!of_machine_is_compatible("cortina,gemini")) + return 0; + + map = syscon_regmap_lookup_by_compatible("cortina,gemini-syscon"); + if (IS_ERR(map)) + return PTR_ERR(map); + ret = regmap_read(map, GLOBAL_WORD_ID, &rev); + if (ret) + return ret; + + val = (GEMINI_DEFAULT_BURST_SIZE << GEMINI_ARB1_BURST_SHIFT) | + GEMINI_DEFAULT_PRIO; + + /* Set up system arbitration */ + regmap_update_bits(map, + GEMINI_GLOBAL_ARB1_CTRL, + GEMINI_ARB1_BURST_MASK | GEMINI_ARB1_PRIO_MASK, + val); + + pr_info("Gemini SoC %04x revision %02x, set arbitration %08x\n", + rev >> 8, rev & 0xff, val); + + return 0; +} +subsys_initcall(gemini_soc_init); |
