History

drm: fix fb-helper vs MST dangling connector ptrs (v2)

VT switch back/forth from console to xserver (for example) has potential to go horribly wrong if a dynamic DP MST connector ends up in the saved modeset that is restored when switching back to fbcon. When removing a dynamic connector, don't forget to clean up the saved state. v1: original v2: null out set->fb if no more connectors to avoid making i915 cranky

Rob Clark committed 11 years ago

Commit 2148f181 parent 1c999c41 file · +30 −0Browse files

Unified · Split

drivers/gpu/drm/drm_fb_helper.c+30−0
@@ -145,6 +145,31 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ · 144 unmodified lines
145}145}
146EXPORT_SYMBOL(drm_fb_helper_add_one_connector);146EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
147 147
148static void remove_from_modeset(struct drm_mode_set *set,
149 struct drm_connector *connector)
150{
151 int i, j;
152
153 for (i = 0; i < set->num_connectors; i++) {
154 if (set->connectors[i] == connector)
155 break;
156 }
157
158 if (i == set->num_connectors)
159 return;
160
161 for (j = i + 1; j < set->num_connectors; j++) {
162 set->connectors[j - 1] = set->connectors[j];
163 }
164 set->num_connectors--;
165
166 /* because i915 is pissy about this..
167 * TODO maybe need to makes sure we set it back to !=NULL somewhere?
168 */
169 if (set->num_connectors == 0)
170 set->fb = NULL;
171}
172
148int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,173int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
149 struct drm_connector *connector)174 struct drm_connector *connector)
150{175{
@@ -167,6 +192,11 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, · 16 unmodified lines
167 }192 }
168 fb_helper->connector_count--;193 fb_helper->connector_count--;
169 kfree(fb_helper_connector);194 kfree(fb_helper_connector);
195
196 /* also cleanup dangling references to the connector: */
197 for (i = 0; i < fb_helper->crtc_count; i++)
198 remove_from_modeset(&fb_helper->crtc_info[i].mode_set, connector);
199
170 return 0;200 return 0;
171}201}
172EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);202EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);