aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-04-04 23:17:13 -0400
committerDave Airlie <airlied@redhat.com>2019-04-08 02:20:02 -0400
commit9b39b013037fbfa8d4b999345d9e904d8a336fc2 (patch)
tree303ac359547bf20530401a22ee0e42548449d202
parent15ade5d2e7775667cf191cf2f94327a4889f8b9d (diff)
drm/udl: add a release method and delay modeset teardown
If we unplug a udl device, the usb callback with deinit the mode_config struct, however userspace will still have an open file descriptor and a framebuffer on that device. When userspace closes the fd, we'll oops because it'll try and look stuff up in the object idr which we've destroyed. This punts destroying the mode objects until release time instead. Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-2-airlied@gmail.com
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c1
-rw-r--r--drivers/gpu/drm/udl/udl_drv.h1
-rw-r--r--drivers/gpu/drm/udl/udl_main.c8
3 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 22cd2d13e272..ff47f890e6ad 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -52,6 +52,7 @@ static struct drm_driver driver = {
52 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, 52 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
53 .load = udl_driver_load, 53 .load = udl_driver_load,
54 .unload = udl_driver_unload, 54 .unload = udl_driver_unload,
55 .release = udl_driver_release,
55 56
56 /* gem hooks */ 57 /* gem hooks */
57 .gem_free_object_unlocked = udl_gem_free_object, 58 .gem_free_object_unlocked = udl_gem_free_object,
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index e9e9b1ff678e..4ae67d882eae 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -104,6 +104,7 @@ void udl_urb_completion(struct urb *urb);
104 104
105int udl_driver_load(struct drm_device *dev, unsigned long flags); 105int udl_driver_load(struct drm_device *dev, unsigned long flags);
106void udl_driver_unload(struct drm_device *dev); 106void udl_driver_unload(struct drm_device *dev);
107void udl_driver_release(struct drm_device *dev);
107 108
108int udl_fbdev_init(struct drm_device *dev); 109int udl_fbdev_init(struct drm_device *dev);
109void udl_fbdev_cleanup(struct drm_device *dev); 110void udl_fbdev_cleanup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 9086d0d1b880..1f8ef34ade24 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -379,6 +379,12 @@ void udl_driver_unload(struct drm_device *dev)
379 udl_free_urb_list(dev); 379 udl_free_urb_list(dev);
380 380
381 udl_fbdev_cleanup(dev); 381 udl_fbdev_cleanup(dev);
382 udl_modeset_cleanup(dev);
383 kfree(udl); 382 kfree(udl);
384} 383}
384
385void udl_driver_release(struct drm_device *dev)
386{
387 udl_modeset_cleanup(dev);
388 drm_dev_fini(dev);
389 kfree(dev);
390}