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/i3c/internals.h | |
| 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/i3c/internals.h')
| -rw-r--r-- | drivers/i3c/internals.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/i3c/internals.h b/drivers/i3c/internals.h new file mode 100644 index 000000000..86a36b951 --- /dev/null +++ b/drivers/i3c/internals.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Cadence Design Systems Inc. + * + * Author: Boris Brezillon <boris.brezillon@bootlin.com> + */ + +#ifndef I3C_INTERNALS_H +#define I3C_INTERNALS_H + +#include <linux/i3c/master.h> +#include <linux/io.h> + +int __must_check i3c_bus_rpm_get(struct i3c_bus *bus); +void i3c_bus_rpm_put(struct i3c_bus *bus); +bool i3c_bus_rpm_ibi_allowed(struct i3c_bus *bus); + +void i3c_bus_normaluse_lock(struct i3c_bus *bus); +void i3c_bus_normaluse_unlock(struct i3c_bus *bus); + +int i3c_dev_setdasa_locked(struct i3c_dev_desc *dev); +int i3c_dev_do_xfers_locked(struct i3c_dev_desc *dev, + struct i3c_xfer *xfers, + int nxfers, enum i3c_xfer_mode mode); +int i3c_dev_disable_ibi_locked(struct i3c_dev_desc *dev); +int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev); +int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev, + const struct i3c_ibi_setup *req); +void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev); + +/** + * i3c_writel_fifo - Write data buffer to 32bit FIFO + * @addr: FIFO Address to write to + * @buf: Pointer to the data bytes to write + * @nbytes: Number of bytes to write + */ +static inline void i3c_writel_fifo(void __iomem *addr, const void *buf, + int nbytes) +{ + writesl(addr, buf, nbytes / 4); + if (nbytes & 3) { + u32 tmp = 0; + + memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3); + /* + * writesl() instead of writel() to keep FIFO + * byteorder on big-endian targets + */ + writesl(addr, &tmp, 1); + } +} + +/** + * i3c_readl_fifo - Read data buffer from 32bit FIFO + * @addr: FIFO Address to read from + * @buf: Pointer to the buffer to store read bytes + * @nbytes: Number of bytes to read + */ +static inline void i3c_readl_fifo(const void __iomem *addr, void *buf, + int nbytes) +{ + readsl(addr, buf, nbytes / 4); + if (nbytes & 3) { + u32 tmp; + + /* + * readsl() instead of readl() to keep FIFO + * byteorder on big-endian targets + */ + readsl(addr, &tmp, 1); + memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3); + } +} + +static inline struct i3c_master_controller *i3c_bus_to_i3c_master(struct i3c_bus *i3cbus) +{ + return container_of(i3cbus, struct i3c_master_controller, bus); +} + +#endif /* I3C_INTERNAL_H */ |
