dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework
@ 2022-08-24 16:13 Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 1/4] drm/vc4: hdmi: unlock mutex when device is unplugged Danilo Krummrich
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Danilo Krummrich @ 2022-08-24 16:13 UTC (permalink / raw)
  To: daniel, airlied, tzimmermann, mripard
  Cc: Danilo Krummrich, linux-kernel, dri-devel

Hi,

I've found a few potential issues left after the hotplug rework.

In vc4_hdmi.c we're missing two mutex_unlock() calls when the device is
unplugged.

vc4_crtc and vc4_plane seem to miss some drm_dev_enter()/drm_dev_exit() calls
to protect against resource access after the device/driver is unbound, but the
DRM potentially isn't freed yet and userspace can still call into the driver.

Changes in v2:
  - Use drm_device pointer from struct drm_plane (Maxime)
  - Protect entire functions to increase readability (Maxime)
  - Add another patch to fix an uncovered MMIO access in vc4_hvs.c

Changes in v3:
  - vc4_plane: Actually protect entire functions to increase readability (Maxime)

Danilo Krummrich (4):
  drm/vc4: hdmi: unlock mutex when device is unplugged
  drm/vc4: plane: protect device resources after removal
  drm/vc4: crtc: protect device resources after removal
  drm/vc4: hvs: protect drm_print_regset32()

 drivers/gpu/drm/vc4/vc4_crtc.c  | 41 ++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/vc4/vc4_hdmi.c  |  7 ++++--
 drivers/gpu/drm/vc4/vc4_hvs.c   |  4 ++--
 drivers/gpu/drm/vc4/vc4_plane.c | 20 ++++++++++++++++
 4 files changed, 67 insertions(+), 5 deletions(-)


base-commit: 4d07b0bc403403438d9cf88450506240c5faf92f
-- 
2.37.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH drm-misc-next v3 1/4] drm/vc4: hdmi: unlock mutex when device is unplugged
  2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
@ 2022-08-24 16:13 ` Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 2/4] drm/vc4: plane: protect device resources after removal Danilo Krummrich
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Danilo Krummrich @ 2022-08-24 16:13 UTC (permalink / raw)
  To: daniel, airlied, tzimmermann, mripard
  Cc: Danilo Krummrich, linux-kernel, dri-devel

In vc4_hdmi_encoder_{pre,post}_crtc_enable() commit cd00ed5187bf
("drm/vc4: hdmi: Protect device resources after removal") missed to
unlock the mutex before returning due to drm_dev_enter() indicating the
device being unplugged.

Fixes: cd00ed5187bf ("drm/vc4: hdmi: Protect device resources after removal")
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 84e5a91c2ea7..4d3ff51ad2a8 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1425,7 +1425,7 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder,
 	mutex_lock(&vc4_hdmi->mutex);
 
 	if (!drm_dev_enter(drm, &idx))
-		return;
+		goto out;
 
 	if (vc4_hdmi->variant->csc_setup)
 		vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode);
@@ -1436,6 +1436,7 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder,
 
 	drm_dev_exit(idx);
 
+out:
 	mutex_unlock(&vc4_hdmi->mutex);
 }
 
@@ -1455,7 +1456,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 	mutex_lock(&vc4_hdmi->mutex);
 
 	if (!drm_dev_enter(drm, &idx))
-		return;
+		goto out;
 
 	spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
 
@@ -1516,6 +1517,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
 	vc4_hdmi_enable_scrambling(encoder);
 
 	drm_dev_exit(idx);
+
+out:
 	mutex_unlock(&vc4_hdmi->mutex);
 }
 
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH drm-misc-next v3 2/4] drm/vc4: plane: protect device resources after removal
  2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 1/4] drm/vc4: hdmi: unlock mutex when device is unplugged Danilo Krummrich
@ 2022-08-24 16:13 ` Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 3/4] drm/vc4: crtc: " Danilo Krummrich
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Danilo Krummrich @ 2022-08-24 16:13 UTC (permalink / raw)
  To: daniel, airlied, tzimmermann, mripard
  Cc: Danilo Krummrich, linux-kernel, dri-devel

(Hardware) resources which are bound to the driver and device lifecycle
must not be accessed after the device and driver are unbound.

However, the DRM device isn't freed as long as the last user closed it,
hence userspace can still call into the driver.

Therefore protect the critical sections which are accessing those
resources with drm_dev_enter() and drm_dev_exit().

Fixes: 9872c7a31921 ("drm/vc4: plane: Switch to drmm_universal_plane_alloc()")
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
---
 drivers/gpu/drm/vc4/vc4_plane.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index eff9c63adfa7..8b92a45a3c89 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -19,6 +19,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_uapi.h>
 #include <drm/drm_blend.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_fb_dma_helper.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_framebuffer.h>
@@ -1219,6 +1220,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
 {
 	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
 	int i;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		goto out;
 
 	vc4_state->hw_dlist = dlist;
 
@@ -1226,6 +1231,9 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
 	for (i = 0; i < vc4_state->dlist_count; i++)
 		writel(vc4_state->dlist[i], &dlist[i]);
 
+	drm_dev_exit(idx);
+
+out:
 	return vc4_state->dlist_count;
 }
 
@@ -1245,6 +1253,10 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
 	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
 	struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0);
 	uint32_t addr;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
 
 	/* We're skipping the address adjustment for negative origin,
 	 * because this is only called on the primary plane.
@@ -1263,6 +1275,8 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
 	 * also use our updated address.
 	 */
 	vc4_state->dlist[vc4_state->ptr0_offset] = addr;
+
+	drm_dev_exit(idx);
 }
 
 static void vc4_plane_atomic_async_update(struct drm_plane *plane,
@@ -1271,6 +1285,10 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane,
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
 	struct vc4_plane_state *vc4_state, *new_vc4_state;
+	int idx;
+
+	if (!drm_dev_enter(plane->dev, &idx))
+		return;
 
 	swap(plane->state->fb, new_plane_state->fb);
 	plane->state->crtc_x = new_plane_state->crtc_x;
@@ -1333,6 +1351,8 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane,
 	       &vc4_state->hw_dlist[vc4_state->pos2_offset]);
 	writel(vc4_state->dlist[vc4_state->ptr0_offset],
 	       &vc4_state->hw_dlist[vc4_state->ptr0_offset]);
+
+	drm_dev_exit(idx);
 }
 
 static int vc4_plane_atomic_async_check(struct drm_plane *plane,
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH drm-misc-next v3 3/4] drm/vc4: crtc: protect device resources after removal
  2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 1/4] drm/vc4: hdmi: unlock mutex when device is unplugged Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 2/4] drm/vc4: plane: protect device resources after removal Danilo Krummrich
@ 2022-08-24 16:13 ` Danilo Krummrich
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 4/4] drm/vc4: hvs: protect drm_print_regset32() Danilo Krummrich
  2022-08-25  7:47 ` [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Maxime Ripard
  4 siblings, 0 replies; 6+ messages in thread
From: Danilo Krummrich @ 2022-08-24 16:13 UTC (permalink / raw)
  To: daniel, airlied, tzimmermann, mripard
  Cc: Danilo Krummrich, linux-kernel, dri-devel

(Hardware) resources which are bound to the driver and device lifecycle
must not be accessed after the device and driver are unbound.

However, the DRM device isn't freed as long as the last user closed it,
hence userspace can still call into the driver.

Therefore protect the critical sections which are accessing those
resources with drm_dev_enter() and drm_dev_exit().

Fixes: 7cc4214c27cf ("drm/vc4: crtc: Switch to drmm_kzalloc")
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 41 +++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2def6e2ad6f0..0108613e79d5 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -39,6 +39,7 @@
 #include <drm/drm_atomic_uapi.h>
 #include <drm/drm_fb_dma_helper.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
@@ -295,10 +296,17 @@ struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
 static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
 {
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	int idx;
+
+	if (!drm_dev_enter(dev, &idx))
+		return;
 
 	/* The PV needs to be disabled before it can be flushed */
 	CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
 	CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
+
+	drm_dev_exit(idx);
 }
 
 static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encoder,
@@ -321,6 +329,10 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
 	u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
 	u8 ppc = pv_data->pixels_per_clock;
 	bool debug_dump_regs = false;
+	int idx;
+
+	if (!drm_dev_enter(dev, &idx))
+		return;
 
 	if (debug_dump_regs) {
 		struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
@@ -410,6 +422,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
 			 drm_crtc_index(crtc));
 		drm_print_regset32(&p, &vc4_crtc->regset);
 	}
+
+	drm_dev_exit(idx);
 }
 
 static void require_hvs_enabled(struct drm_device *dev)
@@ -430,7 +444,10 @@ static int vc4_crtc_disable(struct drm_crtc *crtc,
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
-	int ret;
+	int idx, ret;
+
+	if (!drm_dev_enter(dev, &idx))
+		return -ENODEV;
 
 	CRTC_WRITE(PV_V_CONTROL,
 		   CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
@@ -464,6 +481,8 @@ static int vc4_crtc_disable(struct drm_crtc *crtc,
 	if (vc4_encoder && vc4_encoder->post_crtc_powerdown)
 		vc4_encoder->post_crtc_powerdown(encoder, state);
 
+	drm_dev_exit(idx);
+
 	return 0;
 }
 
@@ -588,10 +607,14 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
 	struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, new_state);
 	struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+	int idx;
 
 	drm_dbg(dev, "Enabling CRTC %s (%u) connected to Encoder %s (%u)",
 		crtc->name, crtc->base.id, encoder->name, encoder->base.id);
 
+	if (!drm_dev_enter(dev, &idx))
+		return;
+
 	require_hvs_enabled(dev);
 
 	/* Enable vblank irq handling before crtc is started otherwise
@@ -619,6 +642,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	if (vc4_encoder->post_crtc_enable)
 		vc4_encoder->post_crtc_enable(encoder, state);
+
+	drm_dev_exit(idx);
 }
 
 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
@@ -711,17 +736,31 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 static int vc4_enable_vblank(struct drm_crtc *crtc)
 {
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	int idx;
+
+	if (!drm_dev_enter(dev, &idx))
+		return -ENODEV;
 
 	CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
 
+	drm_dev_exit(idx);
+
 	return 0;
 }
 
 static void vc4_disable_vblank(struct drm_crtc *crtc)
 {
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	int idx;
+
+	if (!drm_dev_enter(dev, &idx))
+		return;
 
 	CRTC_WRITE(PV_INTEN, 0);
+
+	drm_dev_exit(idx);
 }
 
 static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH drm-misc-next v3 4/4] drm/vc4: hvs: protect drm_print_regset32()
  2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
                   ` (2 preceding siblings ...)
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 3/4] drm/vc4: crtc: " Danilo Krummrich
@ 2022-08-24 16:13 ` Danilo Krummrich
  2022-08-25  7:47 ` [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Maxime Ripard
  4 siblings, 0 replies; 6+ messages in thread
From: Danilo Krummrich @ 2022-08-24 16:13 UTC (permalink / raw)
  To: daniel, airlied, tzimmermann, mripard
  Cc: Danilo Krummrich, linux-kernel, dri-devel

In vc4_hvs_dump_state() potentially freed resources are protected from
being accessed with drm_dev_enter()/drm_dev_exit().

Also include drm_print_regset32() in the protected section, since
drm_print_regset32() does access memory that is typically mapped via
devm_* calls.

Fixes: 969cfae1f01d ("drm/vc4: hvs: Protect device resources after removal")
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
---
 drivers/gpu/drm/vc4/vc4_hvs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 9e823e0de197..4ac9f5a2d5f9 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -71,11 +71,11 @@ void vc4_hvs_dump_state(struct vc4_hvs *hvs)
 	struct drm_printer p = drm_info_printer(&hvs->pdev->dev);
 	int idx, i;
 
-	drm_print_regset32(&p, &hvs->regset);
-
 	if (!drm_dev_enter(drm, &idx))
 		return;
 
+	drm_print_regset32(&p, &hvs->regset);
+
 	DRM_INFO("HVS ctx:\n");
 	for (i = 0; i < 64; i += 4) {
 		DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework
  2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
                   ` (3 preceding siblings ...)
  2022-08-24 16:13 ` [PATCH drm-misc-next v3 4/4] drm/vc4: hvs: protect drm_print_regset32() Danilo Krummrich
@ 2022-08-25  7:47 ` Maxime Ripard
  4 siblings, 0 replies; 6+ messages in thread
From: Maxime Ripard @ 2022-08-25  7:47 UTC (permalink / raw)
  To: airlied, daniel, tzimmermann, dakr, mripard
  Cc: Maxime Ripard, dri-devel, linux-kernel

On Wed, 24 Aug 2022 18:13:23 +0200, Danilo Krummrich wrote:
> I've found a few potential issues left after the hotplug rework.
> 
> In vc4_hdmi.c we're missing two mutex_unlock() calls when the device is
> unplugged.
> 
> vc4_crtc and vc4_plane seem to miss some drm_dev_enter()/drm_dev_exit() calls
> to protect against resource access after the device/driver is unbound, but the
> DRM potentially isn't freed yet and userspace can still call into the driver.
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-08-25  7:47 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-24 16:13 [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Danilo Krummrich
2022-08-24 16:13 ` [PATCH drm-misc-next v3 1/4] drm/vc4: hdmi: unlock mutex when device is unplugged Danilo Krummrich
2022-08-24 16:13 ` [PATCH drm-misc-next v3 2/4] drm/vc4: plane: protect device resources after removal Danilo Krummrich
2022-08-24 16:13 ` [PATCH drm-misc-next v3 3/4] drm/vc4: crtc: " Danilo Krummrich
2022-08-24 16:13 ` [PATCH drm-misc-next v3 4/4] drm/vc4: hvs: protect drm_print_regset32() Danilo Krummrich
2022-08-25  7:47 ` [PATCH drm-misc-next v3 0/4] Fixes for vc4 hotplug rework Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).