* [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put()
@ 2026-03-10 12:13 Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 1/2] " Luca Ceresoli
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Luca Ceresoli @ 2026-03-10 12:13 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Osama Abdelkader, Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel,
linux-kernel, Luca Ceresoli
This small series introduces drm_bridge_clear_and_put(), to give a easy and
safe way to put a bridge reference and clear the pointer without leaving a
possible use-after-free window.
This is part of the work to support hotplug of DRM bridges. The grand plan
was discussed in [0].
Here's the work breakdown (➜ marks the current series):
1. … add refcounting to DRM bridges struct drm_bridge,
based on devm_drm_bridge_alloc()
A. ✔ add new alloc API and refcounting (v6.16)
B. ✔ convert all bridge drivers to new API (v6.17)
C. ✔ kunit tests (v6.17)
D. ✔ add get/put to drm_bridge_add/remove() + attach/detach()
and warn on old allocation pattern (v6.17)
E. … add get/put on drm_bridge accessors
1. ✔ drm_bridge_chain_get_first_bridge(), add cleanup action (v6.18)
2. ✔ drm_bridge_get_prev_bridge() (v6.18)
3. ✔ drm_bridge_get_next_bridge() (v6.19)
4. ✔ drm_for_each_bridge_in_chain() (v6.19)
5. ✔ drm_bridge_connector_init (v6.19)
6. … protect encoder bridge chain with a mutex
7. … of_drm_find_bridge
a. ✔ add of_drm_get_bridge() (v7.0),
convert basic direct users (v7.0-v7.1)
b. ✔ convert direct of_drm_get_bridge() users, part 2 (v7.0)
c. ✔ convert direct of_drm_get_bridge() users, part 3 (v7.0)
d. ✔… convert direct of_drm_get_bridge() users, part 4
(some v7.1, some pending)
e. convert bridge-only drm_of_find_panel_or_bridge() users
8. drm_of_find_panel_or_bridge, *_of_get_bridge
9. ✔ enforce drm_bridge_add before drm_bridge_attach (v6.19)
F. ✔ debugfs improvements
1. ✔ add top-level 'bridges' file (v6.16)
2. ✔ show refcount and list lingering bridges (v6.19)
2. ➜ handle gracefully atomic updates during bridge removal
A. ✔ Add drm_dev_enter/exit() to protect device resources (v6.20?)
B. … protect private_obj removal from list
C. ➜ Add drm_bridge_clear_and_put()
3. … DSI host-device driver interaction
4. ✔ removing the need for the "always-disconnected" connector
5. … Migrate i.MX LCDIF driver to bridge-connector
6. DRM bridge hotplug
A. Bridge hotplug management in the DRM core
B. Device tree description
[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-0-9d6f2c9c3058@bootlin.com/#t
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Changes in v2:
- Rebased on current drm-misc-next fixing trivial conflict
- Link to v1: https://lore.kernel.org/r/20260206-drm-bridge-atomic-vs-remove-clear_and_put-v1-0-6f1a7d03c45f@bootlin.com
---
Luca Ceresoli (2):
drm/bridge: add drm_bridge_clear_and_put()
drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
drivers/gpu/drm/bridge/samsung-dsim.c | 7 ++-----
drivers/gpu/drm/drm_bridge.c | 34 ++++++++++++++++++++++++++++++++++
include/drm/drm_bridge.h | 1 +
3 files changed, 37 insertions(+), 5 deletions(-)
---
base-commit: 08c6a9b501d2fdf161094a98e1febec41f566c8f
change-id: 20260206-drm-bridge-atomic-vs-remove-clear_and_put-a424c752a061
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] drm/bridge: add drm_bridge_clear_and_put()
2026-03-10 12:13 [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
@ 2026-03-10 12:13 ` Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Luca Ceresoli @ 2026-03-10 12:13 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Osama Abdelkader, Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel,
linux-kernel, Luca Ceresoli
Drivers having a struct drm_bridge pointer pointing to a bridge in many
cases hold that reference until the owning device is removed. In those
cases the reference to the bridge can be put in the .remove callback
(possibly using devm actions) or in the .destroy func (possibly with the
help of struct drm_bridge::next_bridge). At those moments the driver should
not be operating anymore and won't dereference the bridge pointer after it
is put.
However there are cases when drivers need to stop holding a reference to a
bridge even when their device is not being removed. This is the case for
bridge hot-unplug, when a bridge is removed but the previous entity (bridge
or encoder) is staying. In such case the "previous entity" needs to put it
but cannot do it via devm or .destroy, because it is not being removed.
The easy way to dispose of such pointer is:
drm_bridge_put(my_priv->some_bridge);
my_priv->some_bridge = NULL;
However this is risky because there is a time window between the two lines
where the reference is put, and thus the bridge could be deallocated, but
the pointer is still assigned. If other functions of the same driver were
invoked concurrently they might dereference my_priv->some_bridge during
that window, resulting in use-after-free.
A correct solution is to clear the pointer before putting the reference,
but that needs a temporary variable:
struct drm_bridge *temp = my_priv->some_bridge;
my_priv->some_bridge = NULL;
drm_bridge_put(temp);
This solution is however annoying to write, so the incorrect version might
still sneak in.
Add a simple, easy to use function to put a bridge after setting its
pointer to NULL in the correct way.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
This is a renamed version of drm_bridge_put_and_clear() which was sent as
part of a larger patch [0] but with largely rewritten documentation and a
detailed commit message.
[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-14-9d6f2c9c3058@bootlin.com/
---
drivers/gpu/drm/drm_bridge.c | 34 ++++++++++++++++++++++++++++++++++
include/drm/drm_bridge.h | 1 +
2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index f8b0333a0a3b..0260b16cb47d 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -304,6 +304,9 @@ EXPORT_SYMBOL(drm_bridge_get);
*
* This function decrements the bridge's reference count and frees the
* object if the reference count drops to zero.
+ *
+ * See also drm_bridge_clear_and_put() if you also need to set the pointer
+ * to NULL
*/
void drm_bridge_put(struct drm_bridge *bridge)
{
@@ -312,6 +315,37 @@ void drm_bridge_put(struct drm_bridge *bridge)
}
EXPORT_SYMBOL(drm_bridge_put);
+/**
+ * drm_bridge_clear_and_put - Given a bridge pointer, clear the pointer
+ * then put the bridge
+ * @bridge_pp: pointer to pointer to a struct drm_bridge; ``bridge_pp``
+ * must be non-NULL; if ``*bridge_pp`` is NULL this function
+ * does nothing
+ *
+ * Helper to put a DRM bridge, but only after setting its pointer to
+ * NULL. Useful when a struct drm_bridge reference must be dropped without
+ * leaving a use-after-free window where the pointed bridge might have been
+ * freed while still holding a pointer to it.
+ *
+ * For struct ``drm_bridge *some_bridge``, this code::
+ *
+ * drm_bridge_clear_and_put(&some_bridge);
+ *
+ * is equivalent to the more complex::
+ *
+ * struct drm_bridge *temp = some_bridge;
+ * some_bridge = NULL;
+ * drm_bridge_put(temp);
+ */
+void drm_bridge_clear_and_put(struct drm_bridge **bridge_pp)
+{
+ struct drm_bridge *bridge = *bridge_pp;
+
+ *bridge_pp = NULL;
+ drm_bridge_put(bridge);
+}
+EXPORT_SYMBOL(drm_bridge_clear_and_put);
+
/**
* drm_bridge_put_void - wrapper to drm_bridge_put() taking a void pointer
*
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 4f19f7064ee3..66ab89cf48aa 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1290,6 +1290,7 @@ void drm_bridge_unplug(struct drm_bridge *bridge);
struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge);
void drm_bridge_put(struct drm_bridge *bridge);
+void drm_bridge_clear_and_put(struct drm_bridge **bridge_pp);
/* Cleanup action for use with __free() */
DEFINE_FREE(drm_bridge_put, struct drm_bridge *, if (_T) drm_bridge_put(_T))
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
2026-03-10 12:13 [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 1/2] " Luca Ceresoli
@ 2026-03-10 12:13 ` Luca Ceresoli
2026-03-11 8:28 ` Marek Szyprowski
2026-03-11 8:19 ` [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Maxime Ripard
2026-03-20 10:18 ` Luca Ceresoli
3 siblings, 1 reply; 6+ messages in thread
From: Luca Ceresoli @ 2026-03-10 12:13 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski
Cc: Osama Abdelkader, Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel,
linux-kernel, Luca Ceresoli
drm_bridge_clear_and_put() is simpler to write and it prevents any
potential future use-after-free.
Reviewed-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/bridge/samsung-dsim.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index ec632f268644..c3eb437ef1b0 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1988,9 +1988,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
return 0;
err_release_next_bridge:
- drm_bridge_put(dsi->bridge.next_bridge);
- dsi->bridge.next_bridge = NULL;
-
+ drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
samsung_dsim_unregister_te_irq(dsi);
err_remove_bridge:
@@ -2007,8 +2005,7 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
if (pdata->host_ops && pdata->host_ops->detach)
pdata->host_ops->detach(dsi, device);
- drm_bridge_put(dsi->bridge.next_bridge);
- dsi->bridge.next_bridge = NULL;
+ drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
samsung_dsim_unregister_te_irq(dsi);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put()
2026-03-10 12:13 [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 1/2] " Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
@ 2026-03-11 8:19 ` Maxime Ripard
2026-03-20 10:18 ` Luca Ceresoli
3 siblings, 0 replies; 6+ messages in thread
From: Maxime Ripard @ 2026-03-11 8:19 UTC (permalink / raw)
To: Luca Ceresoli
Cc: dri-devel, linux-kernel, Andrzej Hajda, David Airlie, Hui Pu,
Ian Ray, Inki Dae, Jagan Teki, Jernej Skrabec, Jonas Karlman,
Laurent Pinchart, Maarten Lankhorst, Marek Szyprowski,
Maxime Ripard, Neil Armstrong, Osama Abdelkader, Robert Foss,
Simona Vetter, Thomas Petazzoni, Thomas Zimmermann
On Tue, 10 Mar 2026 13:13:22 +0100, Luca Ceresoli wrote:
> This small series introduces drm_bridge_clear_and_put(), to give a easy and
> safe way to put a bridge reference and clear the pointer without leaving a
> possible use-after-free window.
>
> This is part of the work to support hotplug of DRM bridges. The grand plan
>
> [ ... ]
Acked-by: Maxime Ripard <mripard@kernel.org>
Thanks!
Maxime
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
2026-03-10 12:13 ` [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
@ 2026-03-11 8:28 ` Marek Szyprowski
0 siblings, 0 replies; 6+ messages in thread
From: Marek Szyprowski @ 2026-03-11 8:28 UTC (permalink / raw)
To: Luca Ceresoli, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Inki Dae, Jagan Teki
Cc: Osama Abdelkader, Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel,
linux-kernel
On 10.03.2026 13:13, Luca Ceresoli wrote:
> drm_bridge_clear_and_put() is simpler to write and it prevents any
> potential future use-after-free.
>
> Reviewed-by: Osama Abdelkader <osama.abdelkader@gmail.com>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/gpu/drm/bridge/samsung-dsim.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
> index ec632f268644..c3eb437ef1b0 100644
> --- a/drivers/gpu/drm/bridge/samsung-dsim.c
> +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
> @@ -1988,9 +1988,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
> return 0;
>
> err_release_next_bridge:
> - drm_bridge_put(dsi->bridge.next_bridge);
> - dsi->bridge.next_bridge = NULL;
> -
> + drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
> if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
> samsung_dsim_unregister_te_irq(dsi);
> err_remove_bridge:
> @@ -2007,8 +2005,7 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
> if (pdata->host_ops && pdata->host_ops->detach)
> pdata->host_ops->detach(dsi, device);
>
> - drm_bridge_put(dsi->bridge.next_bridge);
> - dsi->bridge.next_bridge = NULL;
> + drm_bridge_clear_and_put(&dsi->bridge.next_bridge);
>
> samsung_dsim_unregister_te_irq(dsi);
>
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put()
2026-03-10 12:13 [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
` (2 preceding siblings ...)
2026-03-11 8:19 ` [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Maxime Ripard
@ 2026-03-20 10:18 ` Luca Ceresoli
3 siblings, 0 replies; 6+ messages in thread
From: Luca Ceresoli @ 2026-03-20 10:18 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Inki Dae,
Jagan Teki, Marek Szyprowski, Luca Ceresoli
Cc: Osama Abdelkader, Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel,
linux-kernel
On Tue, 10 Mar 2026 13:13:22 +0100, Luca Ceresoli wrote:
> This small series introduces drm_bridge_clear_and_put(), to give a easy and
> safe way to put a bridge reference and clear the pointer without leaving a
> possible use-after-free window.
>
> This is part of the work to support hotplug of DRM bridges. The grand plan
> was discussed in [0].
>
> [...]
Applied, thanks!
[1/2] drm/bridge: add drm_bridge_clear_and_put()
commit: 8f3c83720555ffa96799896f2a0bb985a03a89f4
[2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge
commit: fbef867cf6614178bc6afd15ee15f85cddf19eab
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-20 10:18 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-10 12:13 [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 1/2] " Luca Ceresoli
2026-03-10 12:13 ` [PATCH v2 2/2] drm/bridge: samsung-dsim: use drm_bridge_clear_and_put() to put the next bridge Luca Ceresoli
2026-03-11 8:28 ` Marek Szyprowski
2026-03-11 8:19 ` [PATCH v2 0/2] drm/bridge: add drm_bridge_clear_and_put() Maxime Ripard
2026-03-20 10:18 ` Luca Ceresoli
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.