]>
Commit | Line | Data |
---|---|---|
de2fa02c GKH |
1 | From 9b39b013037fbfa8d4b999345d9e904d8a336fc2 Mon Sep 17 00:00:00 2001 |
2 | From: Dave Airlie <airlied@redhat.com> | |
3 | Date: Fri, 5 Apr 2019 13:17:13 +1000 | |
4 | Subject: drm/udl: add a release method and delay modeset teardown | |
5 | ||
6 | From: Dave Airlie <airlied@redhat.com> | |
7 | ||
8 | commit 9b39b013037fbfa8d4b999345d9e904d8a336fc2 upstream. | |
9 | ||
10 | If we unplug a udl device, the usb callback with deinit the | |
11 | mode_config struct, however userspace will still have an open | |
12 | file descriptor and a framebuffer on that device. When userspace | |
13 | closes the fd, we'll oops because it'll try and look stuff up | |
14 | in the object idr which we've destroyed. | |
15 | ||
16 | This punts destroying the mode objects until release time instead. | |
17 | ||
18 | Cc: stable@vger.kernel.org | |
19 | Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> | |
20 | Signed-off-by: Dave Airlie <airlied@redhat.com> | |
21 | Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-2-airlied@gmail.com | |
22 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
23 | ||
24 | --- | |
25 | drivers/gpu/drm/udl/udl_drv.c | 1 + | |
26 | drivers/gpu/drm/udl/udl_drv.h | 1 + | |
27 | drivers/gpu/drm/udl/udl_main.c | 8 +++++++- | |
28 | 3 files changed, 9 insertions(+), 1 deletion(-) | |
29 | ||
30 | --- a/drivers/gpu/drm/udl/udl_drv.c | |
31 | +++ b/drivers/gpu/drm/udl/udl_drv.c | |
32 | @@ -51,6 +51,7 @@ static struct drm_driver driver = { | |
33 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, | |
34 | .load = udl_driver_load, | |
35 | .unload = udl_driver_unload, | |
36 | + .release = udl_driver_release, | |
37 | ||
38 | /* gem hooks */ | |
39 | .gem_free_object_unlocked = udl_gem_free_object, | |
40 | --- a/drivers/gpu/drm/udl/udl_drv.h | |
41 | +++ b/drivers/gpu/drm/udl/udl_drv.h | |
42 | @@ -104,6 +104,7 @@ void udl_urb_completion(struct urb *urb) | |
43 | ||
44 | int udl_driver_load(struct drm_device *dev, unsigned long flags); | |
45 | void udl_driver_unload(struct drm_device *dev); | |
46 | +void udl_driver_release(struct drm_device *dev); | |
47 | ||
48 | int udl_fbdev_init(struct drm_device *dev); | |
49 | void udl_fbdev_cleanup(struct drm_device *dev); | |
50 | --- a/drivers/gpu/drm/udl/udl_main.c | |
51 | +++ b/drivers/gpu/drm/udl/udl_main.c | |
52 | @@ -378,6 +378,12 @@ void udl_driver_unload(struct drm_device | |
53 | udl_free_urb_list(dev); | |
54 | ||
55 | udl_fbdev_cleanup(dev); | |
56 | - udl_modeset_cleanup(dev); | |
57 | kfree(udl); | |
58 | } | |
59 | + | |
60 | +void udl_driver_release(struct drm_device *dev) | |
61 | +{ | |
62 | + udl_modeset_cleanup(dev); | |
63 | + drm_dev_fini(dev); | |
64 | + kfree(dev); | |
65 | +} |