diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-11-29 07:02:17 -0500 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-11-29 15:52:32 -0500 |
commit | a53ca63502e62ca459de32821753c8227dc94197 (patch) | |
tree | 215d63accb417972f11dc0f3654c6accd96c525e | |
parent | 64e94407fb5a4128636c2b15b38fa6e71a427228 (diff) |
drm: Protect fb_helper list manipulation with a mutex
Though we only walk the kernel_fb_helper_list inside a panic (or single
thread debugging), we still need to protect the list manipulation on
creating/removing a framebuffer device in order to prevent list
corruption.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20161129120217.7344-3-chris@chris-wilson.co.uk
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 90da28d2fcf3..e934b541feea 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -49,6 +49,7 @@ MODULE_PARM_DESC(fbdev_emulation, | |||
49 | "Enable legacy fbdev emulation [default=true]"); | 49 | "Enable legacy fbdev emulation [default=true]"); |
50 | 50 | ||
51 | static LIST_HEAD(kernel_fb_helper_list); | 51 | static LIST_HEAD(kernel_fb_helper_list); |
52 | static DEFINE_MUTEX(kernel_fb_helper_lock); | ||
52 | 53 | ||
53 | /** | 54 | /** |
54 | * DOC: fbdev helpers | 55 | * DOC: fbdev helpers |
@@ -855,12 +856,14 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) | |||
855 | if (!drm_fbdev_emulation) | 856 | if (!drm_fbdev_emulation) |
856 | return; | 857 | return; |
857 | 858 | ||
859 | mutex_lock(&kernel_fb_helper_lock); | ||
858 | if (!list_empty(&fb_helper->kernel_fb_list)) { | 860 | if (!list_empty(&fb_helper->kernel_fb_list)) { |
859 | list_del(&fb_helper->kernel_fb_list); | 861 | list_del(&fb_helper->kernel_fb_list); |
860 | if (list_empty(&kernel_fb_helper_list)) { | 862 | if (list_empty(&kernel_fb_helper_list)) { |
861 | unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); | 863 | unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); |
862 | } | 864 | } |
863 | } | 865 | } |
866 | mutex_unlock(&kernel_fb_helper_lock); | ||
864 | 867 | ||
865 | drm_fb_helper_crtc_free(fb_helper); | 868 | drm_fb_helper_crtc_free(fb_helper); |
866 | 869 | ||
@@ -2258,10 +2261,12 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) | |||
2258 | dev_info(dev->dev, "fb%d: %s frame buffer device\n", | 2261 | dev_info(dev->dev, "fb%d: %s frame buffer device\n", |
2259 | info->node, info->fix.id); | 2262 | info->node, info->fix.id); |
2260 | 2263 | ||
2264 | mutex_lock(&kernel_fb_helper_lock); | ||
2261 | if (list_empty(&kernel_fb_helper_list)) | 2265 | if (list_empty(&kernel_fb_helper_list)) |
2262 | register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); | 2266 | register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); |
2263 | 2267 | ||
2264 | list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); | 2268 | list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); |
2269 | mutex_unlock(&kernel_fb_helper_lock); | ||
2265 | 2270 | ||
2266 | return 0; | 2271 | return 0; |
2267 | } | 2272 | } |