From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,
"H . Nikolaus Schaller" <hns@goldelico.com>,
Maxime Ripard <mripard@kernel.org>,
Sebastian Reichel <sebastian.reichel@collabora.com>,
Tony Lindgren <tony@atomide.com>, Sasha Levin <sashal@kernel.org>,
maarten.lankhorst@linux.intel.com, tzimmermann@suse.de,
airlied@gmail.com, daniel@ffwll.ch,
dri-devel@lists.freedesktop.org
Subject: [PATCH AUTOSEL 4.19 08/23] drm/mipi-dsi: Fix detach call without attach
Date: Mon, 22 Jan 2024 10:17:48 -0500 [thread overview]
Message-ID: <20240122151823.997644-8-sashal@kernel.org> (raw)
In-Reply-To: <20240122151823.997644-1-sashal@kernel.org>
From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
[ Upstream commit 90d50b8d85834e73536fdccd5aa913b30494fef0 ]
It's been reported that DSI host driver's detach can be called without
the attach ever happening:
https://lore.kernel.org/all/20230412073954.20601-1-tony@atomide.com/
After reading the code, I think this is what happens:
We have a DSI host defined in the device tree and a DSI peripheral under
that host (i.e. an i2c device using the DSI as data bus doesn't exhibit
this behavior).
The host driver calls mipi_dsi_host_register(), which causes (via a few
functions) mipi_dsi_device_add() to be called for the DSI peripheral. So
now we have a DSI device under the host, but attach hasn't been called.
Normally the probing of the devices continues, and eventually the DSI
peripheral's driver will call mipi_dsi_attach(), attaching the
peripheral.
However, if the host driver's probe encounters an error after calling
mipi_dsi_host_register(), and before the peripheral has called
mipi_dsi_attach(), the host driver will do cleanups and return an error
from its probe function. The cleanups include calling
mipi_dsi_host_unregister().
mipi_dsi_host_unregister() will call two functions for all its DSI
peripheral devices: mipi_dsi_detach() and mipi_dsi_device_unregister().
The latter makes sense, as the device exists, but the former may be
wrong as attach has not necessarily been done.
To fix this, track the attached state of the peripheral, and only detach
from mipi_dsi_host_unregister() if the peripheral was attached.
Note that I have only tested this with a board with an i2c DSI
peripheral, not with a "pure" DSI peripheral.
However, slightly related, the unregister machinery still seems broken.
E.g. if the DSI host driver is unbound, it'll detach and unregister the
DSI peripherals. After that, when the DSI peripheral driver unbound
it'll call detach either directly or using the devm variant, leading to
a crash. And probably the driver will crash if it happens, for some
reason, to try to send a message via the DSI bus.
But that's another topic.
Tested-by: H. Nikolaus Schaller <hns@goldelico.com>
Acked-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230921-dsi-detach-fix-v1-1-d0de2d1621d9@ideasonboard.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_mipi_dsi.c | 17 +++++++++++++++--
include/drm/drm_mipi_dsi.h | 2 ++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 81923442b42d..2bd4e768b129 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -305,7 +305,8 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
{
struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
- mipi_dsi_detach(dsi);
+ if (dsi->attached)
+ mipi_dsi_detach(dsi);
mipi_dsi_device_unregister(dsi);
return 0;
@@ -328,11 +329,18 @@ EXPORT_SYMBOL(mipi_dsi_host_unregister);
int mipi_dsi_attach(struct mipi_dsi_device *dsi)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+ int ret;
if (!ops || !ops->attach)
return -ENOSYS;
- return ops->attach(dsi->host, dsi);
+ ret = ops->attach(dsi->host, dsi);
+ if (ret)
+ return ret;
+
+ dsi->attached = true;
+
+ return 0;
}
EXPORT_SYMBOL(mipi_dsi_attach);
@@ -344,9 +352,14 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
+ if (WARN_ON(!dsi->attached))
+ return -EINVAL;
+
if (!ops || !ops->detach)
return -ENOSYS;
+ dsi->attached = false;
+
return ops->detach(dsi->host, dsi);
}
EXPORT_SYMBOL(mipi_dsi_detach);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 689f615471ab..a059f1d968b7 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -163,6 +163,7 @@ struct mipi_dsi_device_info {
* struct mipi_dsi_device - DSI peripheral device
* @host: DSI host for this peripheral
* @dev: driver model device node for this peripheral
+ * @attached: the DSI device has been successfully attached
* @name: DSI peripheral chip type
* @channel: virtual channel assigned to the peripheral
* @format: pixel format for video mode
@@ -172,6 +173,7 @@ struct mipi_dsi_device_info {
struct mipi_dsi_device {
struct mipi_dsi_host *host;
struct device dev;
+ bool attached;
char name[DSI_DEV_NAME_SIZE];
unsigned int channel;
--
2.43.0
next prev parent reply other threads:[~2024-01-22 15:18 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-22 15:17 [PATCH AUTOSEL 4.19 01/23] f2fs: fix to check return value of f2fs_reserve_new_block() Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 02/23] ALSA: hda: Refer to correct stream index at loops Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 03/23] ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 04/23] fast_dput(): handle underflows gracefully Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 05/23] RDMA/IPoIB: Fix error code return in ipoib_mcast_join Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 06/23] drm/drm_file: fix use of uninitialized variable Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 07/23] drm/framebuffer: Fix " Sasha Levin
2024-01-22 15:17 ` Sasha Levin [this message]
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 09/23] media: stk1160: Fixed high volume of stk1160_dbg messages Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 10/23] media: rockchip: rga: fix swizzling for RGB formats Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 11/23] PCI: add INTEL_HDA_ARL to pci_ids.h Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 12/23] ALSA: hda: Intel: add HDA_ARL PCI ID support Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 13/23] hwmon: (pc87360) Bounds check data->innr usage Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 14/23] drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 15/23] IB/ipoib: Fix mcast list locking Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 16/23] media: ddbridge: fix an error code problem in ddb_probe Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 17/23] drm/msm/dpu: Ratelimit framedone timeout msgs Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 18/23] clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() Sasha Levin
2024-01-22 15:17 ` [PATCH AUTOSEL 4.19 19/23] clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() Sasha Levin
2024-01-22 15:18 ` [PATCH AUTOSEL 4.19 20/23] watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 Sasha Levin
2024-01-22 15:18 ` [PATCH AUTOSEL 4.19 21/23] drm/amd/display: make flip_timestamp_in_us a 64-bit variable Sasha Levin
2024-01-22 15:18 ` [PATCH AUTOSEL 4.19 22/23] drm/amdgpu: Let KFD sync with VM fences Sasha Levin
2024-01-22 15:18 ` [PATCH AUTOSEL 4.19 23/23] drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' Sasha Levin
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=20240122151823.997644-8-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=airlied@gmail.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=hns@goldelico.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=sebastian.reichel@collabora.com \
--cc=stable@vger.kernel.org \
--cc=tomi.valkeinen@ideasonboard.com \
--cc=tony@atomide.com \
--cc=tzimmermann@suse.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox