diff options
| author | Thomas Hellstrom <thellstrom@vmware.com> | 2014-02-25 13:57:44 -0500 |
|---|---|---|
| committer | Thomas Hellstrom <thellstrom@vmware.com> | 2014-03-28 09:19:02 -0400 |
| commit | c996fd0b956450563454e7ccc97a82ca31f9d043 (patch) | |
| tree | 68fa27376f60773bd2feaf5340351cb29e0a834b /include/drm | |
| parent | a12cd0025cdc0b4d43b79249dbd8c266af284032 (diff) | |
drm: Protect the master management with a drm_device::master_mutex v3
The master management was previously protected by the drm_device::struct_mutex.
In order to avoid locking order violations in a reworked dropped master
security check in the vmwgfx driver, break it out into a separate master_mutex.
Locking order is master_mutex -> struct_mutex.
Also remove drm_master::blocked since it's not used.
v2: Add an inline comment about what drm_device::master_mutex is protecting.
v3: Remove unneeded struct_mutex locks. Fix error returns in
drm_setmaster_ioctl().
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Daniel Vetter <daniel@ffwll.ch>
Diffstat (limited to 'include/drm')
| -rw-r--r-- | include/drm/drmP.h | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3d594ca7fa62..4e24a1a0daeb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -405,7 +405,8 @@ struct drm_prime_file_private { | |||
| 405 | struct drm_file { | 405 | struct drm_file { |
| 406 | unsigned always_authenticated :1; | 406 | unsigned always_authenticated :1; |
| 407 | unsigned authenticated :1; | 407 | unsigned authenticated :1; |
| 408 | unsigned is_master :1; /* this file private is a master for a minor */ | 408 | /* Whether we're master for a minor. Protected by master_mutex */ |
| 409 | unsigned is_master :1; | ||
| 409 | /* true when the client has asked us to expose stereo 3D mode flags */ | 410 | /* true when the client has asked us to expose stereo 3D mode flags */ |
| 410 | unsigned stereo_allowed :1; | 411 | unsigned stereo_allowed :1; |
| 411 | 412 | ||
| @@ -684,28 +685,29 @@ struct drm_gem_object { | |||
| 684 | 685 | ||
| 685 | #include <drm/drm_crtc.h> | 686 | #include <drm/drm_crtc.h> |
| 686 | 687 | ||
| 687 | /* per-master structure */ | 688 | /** |
| 689 | * struct drm_master - drm master structure | ||
| 690 | * | ||
| 691 | * @refcount: Refcount for this master object. | ||
| 692 | * @minor: Link back to minor char device we are master for. Immutable. | ||
| 693 | * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex. | ||
| 694 | * @unique_len: Length of unique field. Protected by drm_global_mutex. | ||
| 695 | * @unique_size: Amount allocated. Protected by drm_global_mutex. | ||
| 696 | * @magiclist: Hash of used authentication tokens. Protected by struct_mutex. | ||
| 697 | * @magicfree: List of used authentication tokens. Protected by struct_mutex. | ||
| 698 | * @lock: DRI lock information. | ||
| 699 | * @driver_priv: Pointer to driver-private information. | ||
| 700 | */ | ||
| 688 | struct drm_master { | 701 | struct drm_master { |
| 689 | 702 | struct kref refcount; | |
| 690 | struct kref refcount; /* refcount for this master */ | 703 | struct drm_minor *minor; |
| 691 | 704 | char *unique; | |
| 692 | struct drm_minor *minor; /**< link back to minor we are a master for */ | 705 | int unique_len; |
| 693 | 706 | int unique_size; | |
| 694 | char *unique; /**< Unique identifier: e.g., busid */ | ||
| 695 | int unique_len; /**< Length of unique field */ | ||
| 696 | int unique_size; /**< amount allocated */ | ||
| 697 | |||
| 698 | int blocked; /**< Blocked due to VC switch? */ | ||
| 699 | |||
| 700 | /** \name Authentication */ | ||
| 701 | /*@{ */ | ||
| 702 | struct drm_open_hash magiclist; | 707 | struct drm_open_hash magiclist; |
| 703 | struct list_head magicfree; | 708 | struct list_head magicfree; |
| 704 | /*@} */ | 709 | struct drm_lock_data lock; |
| 705 | 710 | void *driver_priv; | |
| 706 | struct drm_lock_data lock; /**< Information on hardware lock */ | ||
| 707 | |||
| 708 | void *driver_priv; /**< Private structure for driver to use */ | ||
| 709 | }; | 711 | }; |
| 710 | 712 | ||
| 711 | /* Size of ringbuffer for vblank timestamps. Just double-buffer | 713 | /* Size of ringbuffer for vblank timestamps. Just double-buffer |
| @@ -1020,7 +1022,8 @@ struct drm_minor { | |||
| 1020 | struct list_head debugfs_list; | 1022 | struct list_head debugfs_list; |
| 1021 | struct mutex debugfs_lock; /* Protects debugfs_list. */ | 1023 | struct mutex debugfs_lock; /* Protects debugfs_list. */ |
| 1022 | 1024 | ||
| 1023 | struct drm_master *master; /* currently active master for this node */ | 1025 | /* currently active master for this node. Protected by master_mutex */ |
| 1026 | struct drm_master *master; | ||
| 1024 | struct drm_mode_group mode_group; | 1027 | struct drm_mode_group mode_group; |
| 1025 | }; | 1028 | }; |
| 1026 | 1029 | ||
| @@ -1070,6 +1073,7 @@ struct drm_device { | |||
| 1070 | /*@{ */ | 1073 | /*@{ */ |
| 1071 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ | 1074 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ |
| 1072 | struct mutex struct_mutex; /**< For others */ | 1075 | struct mutex struct_mutex; /**< For others */ |
| 1076 | struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ | ||
| 1073 | /*@} */ | 1077 | /*@} */ |
| 1074 | 1078 | ||
| 1075 | /** \name Usage Counters */ | 1079 | /** \name Usage Counters */ |
