From: Johan Hovold <johan+linaro@kernel.org>
To: Bjorn Andersson <andersson@kernel.org>,
Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
Vinod Koul <vkoul@kernel.org>
Cc: Jonas Karlman <jonas@kwiboo.se>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Konrad Dybcio <konrad.dybcio@linaro.org>,
Kishon Vijay Abraham I <kishon@kernel.org>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Rob Clark <robdclark@gmail.com>,
Abhinav Kumar <quic_abhinavk@quicinc.com>,
Kuogee Hsieh <quic_khsieh@quicinc.com>,
freedreno@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-phy@lists.infradead.org,
Johan Hovold <johan+linaro@kernel.org>
Subject: [PATCH 2/6] drm/bridge: aux-hpd: separate allocation and registration
Date: Sat, 17 Feb 2024 16:02:24 +0100 [thread overview]
Message-ID: <20240217150228.5788-3-johan+linaro@kernel.org> (raw)
In-Reply-To: <20240217150228.5788-1-johan+linaro@kernel.org>
Combining allocation and registration is an anti-pattern that should be
avoided. Add two new functions for allocating and registering an dp-hpd
bridge with a proper 'devm' prefix so that it is clear that these are
device managed interfaces.
devm_drm_dp_hpd_bridge_alloc()
devm_drm_dp_hpd_bridge_add()
The new interface will be used to fix a use-after-free bug in the
Qualcomm PMIC GLINK driver and may prevent similar issues from being
introduced elsewhere.
The existing drm_dp_hpd_bridge_register() is reimplemented using the
above and left in place for now.
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 67 +++++++++++++++++++------
include/drm/bridge/aux-bridge.h | 15 ++++++
2 files changed, 67 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 9e71daf95bde..6886db2d9e00 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -30,16 +30,13 @@ static void drm_aux_hpd_bridge_release(struct device *dev)
kfree(adev);
}
-static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
+static void drm_aux_hpd_bridge_free_adev(void *_adev)
{
- struct auxiliary_device *adev = _adev;
-
- auxiliary_device_delete(adev);
- auxiliary_device_uninit(adev);
+ auxiliary_device_uninit(_adev);
}
/**
- * drm_dp_hpd_bridge_register - Create a simple HPD DisplayPort bridge
+ * devm_drm_dp_hpd_bridge_alloc - allocate a HPD DisplayPort bridge
* @parent: device instance providing this bridge
* @np: device node pointer corresponding to this bridge instance
*
@@ -47,11 +44,9 @@ static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
* DRM_MODE_CONNECTOR_DisplayPort, which terminates the bridge chain and is
* able to send the HPD events.
*
- * Return: device instance that will handle created bridge or an error code
- * encoded into the pointer.
+ * Return: bridge auxiliary device pointer or an error pointer
*/
-struct device *drm_dp_hpd_bridge_register(struct device *parent,
- struct device_node *np)
+struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np)
{
struct auxiliary_device *adev;
int ret;
@@ -82,13 +77,55 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent,
return ERR_PTR(ret);
}
- ret = auxiliary_device_add(adev);
- if (ret) {
- auxiliary_device_uninit(adev);
+ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_free_adev, adev);
+ if (ret)
return ERR_PTR(ret);
- }
- ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_unregister_adev, adev);
+ return adev;
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_alloc);
+
+static void drm_aux_hpd_bridge_del_adev(void *_adev)
+{
+ auxiliary_device_delete(_adev);
+}
+
+/**
+ * devm_drm_dp_hpd_bridge_add - register a HDP DisplayPort bridge
+ * @dev: struct device to tie registration lifetime to
+ * @adev: bridge auxiliary device to be registered
+ *
+ * Returns: zero on success or a negative errno
+ */
+int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev)
+{
+ int ret;
+
+ ret = auxiliary_device_add(adev);
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(dev, drm_aux_hpd_bridge_del_adev, adev);
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_add);
+
+/**
+ * drm_dp_hpd_bridge_register - allocate and register a HDP DisplayPort bridge
+ * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
+ *
+ * Return: device instance that will handle created bridge or an error pointer
+ */
+struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_node *np)
+{
+ struct auxiliary_device *adev;
+ int ret;
+
+ adev = devm_drm_dp_hpd_bridge_alloc(parent, np);
+ if (IS_ERR(adev))
+ return ERR_CAST(adev);
+
+ ret = devm_drm_dp_hpd_bridge_add(parent, adev);
if (ret)
return ERR_PTR(ret);
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c4c423e97f06..4453906105ca 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -9,6 +9,8 @@
#include <drm/drm_connector.h>
+struct auxiliary_device;
+
#if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
int drm_aux_bridge_register(struct device *parent);
#else
@@ -19,10 +21,23 @@ static inline int drm_aux_bridge_register(struct device *parent)
#endif
#if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
+struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np);
+int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np);
void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
#else
+static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
+ struct device_node *np)
+{
+ return NULL;
+}
+
+static inline int devm_drm_dp_hpd_bridge_add(struct auxiliary_device *adev)
+{
+ return 0;
+}
+
static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np)
{
--
2.43.0
WARNING: multiple messages have this Message-ID (diff)
From: Johan Hovold <johan+linaro@kernel.org>
To: Bjorn Andersson <andersson@kernel.org>,
Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
Vinod Koul <vkoul@kernel.org>
Cc: Jonas Karlman <jonas@kwiboo.se>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Konrad Dybcio <konrad.dybcio@linaro.org>,
Kishon Vijay Abraham I <kishon@kernel.org>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Rob Clark <robdclark@gmail.com>,
Abhinav Kumar <quic_abhinavk@quicinc.com>,
Kuogee Hsieh <quic_khsieh@quicinc.com>,
freedreno@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-phy@lists.infradead.org,
Johan Hovold <johan+linaro@kernel.org>
Subject: [PATCH 2/6] drm/bridge: aux-hpd: separate allocation and registration
Date: Sat, 17 Feb 2024 16:02:24 +0100 [thread overview]
Message-ID: <20240217150228.5788-3-johan+linaro@kernel.org> (raw)
In-Reply-To: <20240217150228.5788-1-johan+linaro@kernel.org>
Combining allocation and registration is an anti-pattern that should be
avoided. Add two new functions for allocating and registering an dp-hpd
bridge with a proper 'devm' prefix so that it is clear that these are
device managed interfaces.
devm_drm_dp_hpd_bridge_alloc()
devm_drm_dp_hpd_bridge_add()
The new interface will be used to fix a use-after-free bug in the
Qualcomm PMIC GLINK driver and may prevent similar issues from being
introduced elsewhere.
The existing drm_dp_hpd_bridge_register() is reimplemented using the
above and left in place for now.
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 67 +++++++++++++++++++------
include/drm/bridge/aux-bridge.h | 15 ++++++
2 files changed, 67 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
index 9e71daf95bde..6886db2d9e00 100644
--- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
@@ -30,16 +30,13 @@ static void drm_aux_hpd_bridge_release(struct device *dev)
kfree(adev);
}
-static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
+static void drm_aux_hpd_bridge_free_adev(void *_adev)
{
- struct auxiliary_device *adev = _adev;
-
- auxiliary_device_delete(adev);
- auxiliary_device_uninit(adev);
+ auxiliary_device_uninit(_adev);
}
/**
- * drm_dp_hpd_bridge_register - Create a simple HPD DisplayPort bridge
+ * devm_drm_dp_hpd_bridge_alloc - allocate a HPD DisplayPort bridge
* @parent: device instance providing this bridge
* @np: device node pointer corresponding to this bridge instance
*
@@ -47,11 +44,9 @@ static void drm_aux_hpd_bridge_unregister_adev(void *_adev)
* DRM_MODE_CONNECTOR_DisplayPort, which terminates the bridge chain and is
* able to send the HPD events.
*
- * Return: device instance that will handle created bridge or an error code
- * encoded into the pointer.
+ * Return: bridge auxiliary device pointer or an error pointer
*/
-struct device *drm_dp_hpd_bridge_register(struct device *parent,
- struct device_node *np)
+struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np)
{
struct auxiliary_device *adev;
int ret;
@@ -82,13 +77,55 @@ struct device *drm_dp_hpd_bridge_register(struct device *parent,
return ERR_PTR(ret);
}
- ret = auxiliary_device_add(adev);
- if (ret) {
- auxiliary_device_uninit(adev);
+ ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_free_adev, adev);
+ if (ret)
return ERR_PTR(ret);
- }
- ret = devm_add_action_or_reset(parent, drm_aux_hpd_bridge_unregister_adev, adev);
+ return adev;
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_alloc);
+
+static void drm_aux_hpd_bridge_del_adev(void *_adev)
+{
+ auxiliary_device_delete(_adev);
+}
+
+/**
+ * devm_drm_dp_hpd_bridge_add - register a HDP DisplayPort bridge
+ * @dev: struct device to tie registration lifetime to
+ * @adev: bridge auxiliary device to be registered
+ *
+ * Returns: zero on success or a negative errno
+ */
+int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev)
+{
+ int ret;
+
+ ret = auxiliary_device_add(adev);
+ if (ret)
+ return ret;
+
+ return devm_add_action_or_reset(dev, drm_aux_hpd_bridge_del_adev, adev);
+}
+EXPORT_SYMBOL_GPL(devm_drm_dp_hpd_bridge_add);
+
+/**
+ * drm_dp_hpd_bridge_register - allocate and register a HDP DisplayPort bridge
+ * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
+ *
+ * Return: device instance that will handle created bridge or an error pointer
+ */
+struct device *drm_dp_hpd_bridge_register(struct device *parent, struct device_node *np)
+{
+ struct auxiliary_device *adev;
+ int ret;
+
+ adev = devm_drm_dp_hpd_bridge_alloc(parent, np);
+ if (IS_ERR(adev))
+ return ERR_CAST(adev);
+
+ ret = devm_drm_dp_hpd_bridge_add(parent, adev);
if (ret)
return ERR_PTR(ret);
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c4c423e97f06..4453906105ca 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -9,6 +9,8 @@
#include <drm/drm_connector.h>
+struct auxiliary_device;
+
#if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
int drm_aux_bridge_register(struct device *parent);
#else
@@ -19,10 +21,23 @@ static inline int drm_aux_bridge_register(struct device *parent)
#endif
#if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
+struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, struct device_node *np);
+int devm_drm_dp_hpd_bridge_add(struct device *dev, struct auxiliary_device *adev);
struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np);
void drm_aux_hpd_bridge_notify(struct device *dev, enum drm_connector_status status);
#else
+static inline struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent,
+ struct device_node *np)
+{
+ return NULL;
+}
+
+static inline int devm_drm_dp_hpd_bridge_add(struct auxiliary_device *adev)
+{
+ return 0;
+}
+
static inline struct device *drm_dp_hpd_bridge_register(struct device *parent,
struct device_node *np)
{
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
next prev parent reply other threads:[~2024-02-17 15:03 UTC|newest]
Thread overview: 102+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-17 15:02 [PATCH 0/6] soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-17 15:02 ` [PATCH 1/6] drm/bridge: aux-hpd: fix OF node leaks Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-19 17:48 ` Markus Elfring
2024-02-19 17:48 ` Markus Elfring
2024-02-20 7:24 ` Johan Hovold
2024-02-20 7:24 ` Johan Hovold
2024-02-20 11:52 ` Julia Lawall
2024-02-20 11:52 ` Julia Lawall
2024-02-20 11:55 ` Dmitry Baryshkov
2024-02-20 11:55 ` Dmitry Baryshkov
2024-02-20 12:56 ` Julia Lawall
2024-02-20 12:56 ` Julia Lawall
2024-02-20 13:35 ` Dmitry Baryshkov
2024-02-20 13:35 ` Dmitry Baryshkov
2024-02-22 1:22 ` Bjorn Andersson
2024-02-22 1:22 ` Bjorn Andersson
2024-02-22 21:00 ` Dmitry Baryshkov
2024-02-22 21:00 ` Dmitry Baryshkov
2024-02-23 10:56 ` Neil Armstrong
2024-02-23 10:56 ` Neil Armstrong
2024-02-23 10:56 ` Neil Armstrong
2024-02-23 10:56 ` Neil Armstrong
2024-02-17 15:02 ` Johan Hovold [this message]
2024-02-17 15:02 ` [PATCH 2/6] drm/bridge: aux-hpd: separate allocation and registration Johan Hovold
2024-02-22 2:06 ` Bjorn Andersson
2024-02-22 2:06 ` Bjorn Andersson
2024-02-22 16:06 ` Johan Hovold
2024-02-22 16:06 ` Johan Hovold
2024-02-22 20:57 ` Dmitry Baryshkov
2024-02-22 20:57 ` Dmitry Baryshkov
2024-02-23 12:46 ` Johan Hovold
2024-02-23 12:46 ` Johan Hovold
2024-02-17 15:02 ` [PATCH 3/6] soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-20 8:25 ` Markus Elfring
2024-02-20 8:25 ` Markus Elfring
2024-02-20 10:55 ` Markus Elfring
2024-02-20 10:55 ` Markus Elfring
2024-02-20 11:26 ` Johan Hovold
2024-02-20 11:26 ` Johan Hovold
2024-02-20 12:40 ` [3/6] " Markus Elfring
2024-02-20 12:40 ` Markus Elfring
2024-02-22 2:11 ` [PATCH 3/6] " Bjorn Andersson
2024-02-22 2:11 ` Bjorn Andersson
2024-02-22 21:10 ` Dmitry Baryshkov
2024-02-22 21:10 ` Dmitry Baryshkov
2024-02-17 15:02 ` [PATCH 4/6] soc: qcom: pmic_glink: Fix boot when QRTR=m Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-22 2:18 ` Bjorn Andersson
2024-02-22 2:18 ` Bjorn Andersson
2024-02-22 21:10 ` Dmitry Baryshkov
2024-02-22 21:10 ` Dmitry Baryshkov
2024-02-23 11:04 ` Neil Armstrong
2024-02-23 11:04 ` Neil Armstrong
2024-02-17 15:02 ` [PATCH 5/6] phy: qcom-qmp-combo: fix drm bridge registration Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-19 9:03 ` Neil Armstrong
2024-02-19 9:03 ` Neil Armstrong
2024-02-22 2:21 ` Bjorn Andersson
2024-02-22 2:21 ` Bjorn Andersson
2024-02-22 21:11 ` Dmitry Baryshkov
2024-02-22 21:11 ` Dmitry Baryshkov
2024-02-23 12:09 ` Vinod Koul
2024-02-23 12:09 ` Vinod Koul
2024-02-17 15:02 ` [PATCH 6/6] phy: qcom-qmp-combo: fix type-c switch registration Johan Hovold
2024-02-17 15:02 ` Johan Hovold
2024-02-22 2:23 ` Bjorn Andersson
2024-02-22 2:23 ` Bjorn Andersson
2024-02-22 21:12 ` Dmitry Baryshkov
2024-02-22 21:12 ` Dmitry Baryshkov
2024-02-23 12:10 ` Vinod Koul
2024-02-23 12:10 ` Vinod Koul
2024-02-23 11:02 ` [PATCH 0/6] soc: qcom: pmic_glink_altmode: fix drm bridge use-after-free Neil Armstrong
2024-02-23 11:02 ` Neil Armstrong
2024-02-23 11:03 ` Neil Armstrong
2024-02-23 11:03 ` Neil Armstrong
2024-02-23 12:51 ` Johan Hovold
2024-02-23 12:51 ` Johan Hovold
2024-02-23 13:52 ` Neil Armstrong
2024-02-23 13:52 ` Neil Armstrong
2024-02-23 14:18 ` Dmitry Baryshkov
2024-02-23 14:18 ` Dmitry Baryshkov
2024-02-23 14:28 ` Johan Hovold
2024-02-23 14:28 ` Johan Hovold
2024-02-23 14:21 ` Johan Hovold
2024-02-23 14:21 ` Johan Hovold
2024-02-23 14:38 ` Neil Armstrong
2024-02-23 14:38 ` Neil Armstrong
2024-02-23 14:52 ` Johan Hovold
2024-02-23 14:52 ` Johan Hovold
2024-02-23 14:55 ` Neil Armstrong
2024-02-23 14:55 ` Neil Armstrong
2024-02-23 15:07 ` Dmitry Baryshkov
2024-02-23 15:07 ` Dmitry Baryshkov
2024-02-23 14:54 ` Neil Armstrong
2024-02-23 14:54 ` Neil Armstrong
2024-02-23 15:06 ` (subset) " Dmitry Baryshkov
2024-02-23 15:06 ` Dmitry Baryshkov
2024-03-06 17:47 ` Vinod Koul
2024-03-06 17:47 ` Vinod Koul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240217150228.5788-3-johan+linaro@kernel.org \
--to=johan+linaro@kernel.org \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=andersson@kernel.org \
--cc=andrzej.hajda@intel.com \
--cc=daniel@ffwll.ch \
--cc=dmitry.baryshkov@linaro.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=kishon@kernel.org \
--cc=konrad.dybcio@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=quic_abhinavk@quicinc.com \
--cc=quic_khsieh@quicinc.com \
--cc=rfoss@kernel.org \
--cc=robdclark@gmail.com \
--cc=tzimmermann@suse.de \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.