| From 180dc5b1fa97d066bbb4494352de3214b57d79d5 Mon Sep 17 00:00:00 2001 |
| From: Sean Paul <seanpaul@chromium.org> |
| Date: Wed, 4 Sep 2019 16:29:13 -0400 |
| Subject: [PATCH] drm: damage_helper: Fix race checking plane->state->fb |
| |
| commit 354c2d310082d1c384213ba76c3757dd3cd8755d upstream. |
| |
| Since the dirtyfb ioctl doesn't give us any hints as to which plane is |
| scanning out the fb it's marking as damaged, we need to loop through |
| planes to find it. |
| |
| Currently we just reach into plane state and check, but that can race |
| with another commit changing the fb out from under us. This patch locks |
| the plane before checking the fb and will release the lock if the plane |
| is not displaying the dirty fb. |
| |
| Fixes: b9fc5e01d1ce ("drm: Add helper to implement legacy dirtyfb") |
| Cc: Rob Clark <robdclark@gmail.com> |
| Cc: Deepak Rawat <drawat@vmware.com> |
| Cc: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Cc: Thomas Hellstrom <thellstrom@vmware.com> |
| Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> |
| Cc: Maxime Ripard <maxime.ripard@bootlin.com> |
| Cc: Sean Paul <sean@poorly.run> |
| Cc: David Airlie <airlied@linux.ie> |
| Cc: Daniel Vetter <daniel@ffwll.ch> |
| Cc: dri-devel@lists.freedesktop.org |
| Cc: <stable@vger.kernel.org> # v5.0+ |
| Reported-by: Daniel Vetter <daniel@ffwll.ch> |
| Reviewed-by: Daniel Vetter <daniel@ffwll.ch> |
| Signed-off-by: Sean Paul <seanpaul@chromium.org> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20190904202938.110207-1-sean@poorly.run |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c |
| index ee67c96841fa..f7219474bda1 100644 |
| --- a/drivers/gpu/drm/drm_damage_helper.c |
| +++ b/drivers/gpu/drm/drm_damage_helper.c |
| @@ -212,8 +212,14 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, |
| drm_for_each_plane(plane, fb->dev) { |
| struct drm_plane_state *plane_state; |
| |
| - if (plane->state->fb != fb) |
| + ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx); |
| + if (ret) |
| + goto out; |
| + |
| + if (plane->state->fb != fb) { |
| + drm_modeset_unlock(&plane->mutex); |
| continue; |
| + } |
| |
| plane_state = drm_atomic_get_plane_state(state, plane); |
| if (IS_ERR(plane_state)) { |
| -- |
| 2.7.4 |
| |