diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-06-15 08:17:48 -0400 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-17 03:43:29 -0400 |
| commit | 40daac6136948dc83c1dec14fe4a2444915b22df (patch) | |
| tree | d1a6fd9ec859efb4ae9b241dbb5b642d9a20cbc2 | |
| parent | aaf285e2e0ff490e924dbcdfd08e8274c3093354 (diff) | |
drm: Make drm_connector_register() safe against multiple calls
Protect against drivers that may try to register the connector more
than once, or who try to unregister it multiple times.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Airlie <airlied@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1465993109-19523-4-git-send-email-chris@chris-wilson.co.uk
| -rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 9 | ||||
| -rw-r--r-- | include/drm/drm_crtc.h | 2 |
2 files changed, 11 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 23dfec41decb..ea5ec641eacc 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -984,6 +984,9 @@ int drm_connector_register(struct drm_connector *connector) | |||
| 984 | { | 984 | { |
| 985 | int ret; | 985 | int ret; |
| 986 | 986 | ||
| 987 | if (connector->registered) | ||
| 988 | return 0; | ||
| 989 | |||
| 987 | ret = drm_sysfs_connector_add(connector); | 990 | ret = drm_sysfs_connector_add(connector); |
| 988 | if (ret) | 991 | if (ret) |
| 989 | return ret; | 992 | return ret; |
| @@ -1001,6 +1004,7 @@ int drm_connector_register(struct drm_connector *connector) | |||
| 1001 | 1004 | ||
| 1002 | drm_mode_object_register(connector->dev, &connector->base); | 1005 | drm_mode_object_register(connector->dev, &connector->base); |
| 1003 | 1006 | ||
| 1007 | connector->registered = true; | ||
| 1004 | return 0; | 1008 | return 0; |
| 1005 | 1009 | ||
| 1006 | err_debugfs: | 1010 | err_debugfs: |
| @@ -1019,11 +1023,16 @@ EXPORT_SYMBOL(drm_connector_register); | |||
| 1019 | */ | 1023 | */ |
| 1020 | void drm_connector_unregister(struct drm_connector *connector) | 1024 | void drm_connector_unregister(struct drm_connector *connector) |
| 1021 | { | 1025 | { |
| 1026 | if (!connector->registered) | ||
| 1027 | return; | ||
| 1028 | |||
| 1022 | if (connector->funcs->early_unregister) | 1029 | if (connector->funcs->early_unregister) |
| 1023 | connector->funcs->early_unregister(connector); | 1030 | connector->funcs->early_unregister(connector); |
| 1024 | 1031 | ||
| 1025 | drm_sysfs_connector_remove(connector); | 1032 | drm_sysfs_connector_remove(connector); |
| 1026 | drm_debugfs_connector_remove(connector); | 1033 | drm_debugfs_connector_remove(connector); |
| 1034 | |||
| 1035 | connector->registered = false; | ||
| 1027 | } | 1036 | } |
| 1028 | EXPORT_SYMBOL(drm_connector_unregister); | 1037 | EXPORT_SYMBOL(drm_connector_unregister); |
| 1029 | 1038 | ||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4cc170cfc8fd..c2734979f164 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -1193,6 +1193,7 @@ struct drm_encoder { | |||
| 1193 | * @interlace_allowed: can this connector handle interlaced modes? | 1193 | * @interlace_allowed: can this connector handle interlaced modes? |
| 1194 | * @doublescan_allowed: can this connector handle doublescan? | 1194 | * @doublescan_allowed: can this connector handle doublescan? |
| 1195 | * @stereo_allowed: can this connector handle stereo modes? | 1195 | * @stereo_allowed: can this connector handle stereo modes? |
| 1196 | * @registered: is this connector exposed (registered) with userspace? | ||
| 1196 | * @modes: modes available on this connector (from fill_modes() + user) | 1197 | * @modes: modes available on this connector (from fill_modes() + user) |
| 1197 | * @status: one of the drm_connector_status enums (connected, not, or unknown) | 1198 | * @status: one of the drm_connector_status enums (connected, not, or unknown) |
| 1198 | * @probed_modes: list of modes derived directly from the display | 1199 | * @probed_modes: list of modes derived directly from the display |
| @@ -1249,6 +1250,7 @@ struct drm_connector { | |||
| 1249 | bool interlace_allowed; | 1250 | bool interlace_allowed; |
| 1250 | bool doublescan_allowed; | 1251 | bool doublescan_allowed; |
| 1251 | bool stereo_allowed; | 1252 | bool stereo_allowed; |
| 1253 | bool registered; | ||
| 1252 | struct list_head modes; /* list of modes on this connector */ | 1254 | struct list_head modes; /* list of modes on this connector */ |
| 1253 | 1255 | ||
| 1254 | enum drm_connector_status status; | 1256 | enum drm_connector_status status; |
