summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/gud
diff options
context:
space:
mode:
authorShenghao Yang <me@shenghaoyang.info>2025-12-31 13:50:26 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-01-23 11:21:13 +0100
commita255ec07f91d4c73a361a28b7a3d82f5710245f1 (patch)
treec91ee831189b889810cedd67d96b345e3da81c21 /drivers/gpu/drm/gud
parent67dfd9e8567cc4a1063013bdd14f45ead6ab3297 (diff)
downloadlinux-a255ec07f91d4c73a361a28b7a3d82f5710245f1.tar.gz
linux-a255ec07f91d4c73a361a28b7a3d82f5710245f1.tar.bz2
linux-a255ec07f91d4c73a361a28b7a3d82f5710245f1.zip
drm/gud: fix NULL fb and crtc dereferences on USB disconnect
commit dc2d5ddb193e363187bae2ad358245642d2721fb upstream. On disconnect drm_atomic_helper_disable_all() is called which sets both the fb and crtc for a plane to NULL before invoking a commit. This causes a kernel oops on every display disconnect. Add guards for those dereferences. Cc: <stable@vger.kernel.org> # 6.18.x Fixes: 73cfd166e045 ("drm/gud: Replace simple display pipe with DRM atomic helpers") Signed-off-by: Shenghao Yang <me@shenghaoyang.info> Reviewed-by: Ruben Wauters <rubenru09@aol.com> Signed-off-by: Ruben Wauters <rubenru09@aol.com> Link: https://patch.msgid.link/20251231055039.44266-1-me@shenghaoyang.info Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/gud')
-rw-r--r--drivers/gpu/drm/gud/gud_pipe.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 54d9aa9998e5..cfd66c879ae4 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -457,27 +457,20 @@ int gud_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
struct drm_crtc *crtc = new_plane_state->crtc;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *crtc_state = NULL;
const struct drm_display_mode *mode;
struct drm_framebuffer *old_fb = old_plane_state->fb;
struct drm_connector_state *connector_state = NULL;
struct drm_framebuffer *fb = new_plane_state->fb;
- const struct drm_format_info *format = fb->format;
+ const struct drm_format_info *format;
struct drm_connector *connector;
unsigned int i, num_properties;
struct gud_state_req *req;
int idx, ret;
size_t len;
- if (drm_WARN_ON_ONCE(plane->dev, !fb))
- return -EINVAL;
-
- if (drm_WARN_ON_ONCE(plane->dev, !crtc))
- return -EINVAL;
-
- crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-
- mode = &crtc_state->mode;
+ if (crtc)
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
DRM_PLANE_NO_SCALING,
@@ -492,6 +485,9 @@ int gud_plane_atomic_check(struct drm_plane *plane,
if (old_plane_state->rotation != new_plane_state->rotation)
crtc_state->mode_changed = true;
+ mode = &crtc_state->mode;
+ format = fb->format;
+
if (old_fb && old_fb->format != format)
crtc_state->mode_changed = true;
@@ -598,7 +594,7 @@ void gud_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_helper_damage_iter iter;
int ret, idx;
- if (crtc->state->mode_changed || !crtc->state->enable) {
+ if (!crtc || crtc->state->mode_changed || !crtc->state->enable) {
cancel_work_sync(&gdrm->work);
mutex_lock(&gdrm->damage_lock);
if (gdrm->fb) {