Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40647e45 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

drm: Hide master MAP cleanup in drm_bufs.c



And again make sure it's a no-op for modern drivers. Another case of
dev->struct_mutex gone for modern drivers!

Note that the entirety of the legacy addmap interface is now protected
by DRIVER_MODESET. Note that just auditing kernel code is not enough,
since userspace loves to set up legacy maps on it's own for various
things - with ums userspace and kernel space share control over
resources.

v2: Also add a DRIVER_* check like for all other maps functions to
really short-circuit the code. And give drm_legacy_rmmap used by the
dev unregister code the same treatment.

v3:
- remove redundant return; (Alex, Chris)
- don't special case nouveau with DRIVER_KMS_LEGACY_CONTEXT.

v4: Again special case nouveau. The problem is not directly in the
ddx, but that it calls dri1 functions from the X server. And those do
call drmAddMap. Fixed only in

    commit b1a630b48210d6a3c44994fce1b73273000ace5c
    Author: Dave Airlie <airlied@redhat.com>
    Date:   Wed Nov 7 14:45:14 2012 +1000

        nouveau: drop DRI1 device open interface.

Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1461741618-12679-1-git-send-email-daniel.vetter@ffwll.ch
parent e975eef0
Loading
Loading
Loading
Loading
+22 −5
Original line number Original line Diff line number Diff line
@@ -542,18 +542,35 @@ int drm_legacy_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
}
}
EXPORT_SYMBOL(drm_legacy_rmmap_locked);
EXPORT_SYMBOL(drm_legacy_rmmap_locked);


int drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
void drm_legacy_rmmap(struct drm_device *dev, struct drm_local_map *map)
{
{
	int ret;
	if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
	    drm_core_check_feature(dev, DRIVER_MODESET))
		return;


	mutex_lock(&dev->struct_mutex);
	mutex_lock(&dev->struct_mutex);
	ret = drm_legacy_rmmap_locked(dev, map);
	drm_legacy_rmmap_locked(dev, map);
	mutex_unlock(&dev->struct_mutex);
	mutex_unlock(&dev->struct_mutex);

	return ret;
}
}
EXPORT_SYMBOL(drm_legacy_rmmap);
EXPORT_SYMBOL(drm_legacy_rmmap);


void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master)
{
	struct drm_map_list *r_list, *list_temp;

	if (drm_core_check_feature(dev, DRIVER_MODESET))
		return;

	mutex_lock(&dev->struct_mutex);
	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
		if (r_list->master == master) {
			drm_legacy_rmmap_locked(dev, r_list->map);
			r_list = NULL;
		}
	}
	mutex_unlock(&dev->struct_mutex);
}

/* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
/* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
 * the last close of the device, and this is necessary for cleanup when things
 * the last close of the device, and this is necessary for cleanup when things
 * exit uncleanly.  Therefore, having userland manually remove mappings seems
 * exit uncleanly.  Therefore, having userland manually remove mappings seems
+1 −9
Original line number Original line Diff line number Diff line
@@ -121,19 +121,11 @@ static void drm_master_destroy(struct kref *kref)
{
{
	struct drm_master *master = container_of(kref, struct drm_master, refcount);
	struct drm_master *master = container_of(kref, struct drm_master, refcount);
	struct drm_device *dev = master->minor->dev;
	struct drm_device *dev = master->minor->dev;
	struct drm_map_list *r_list, *list_temp;


	if (dev->driver->master_destroy)
	if (dev->driver->master_destroy)
		dev->driver->master_destroy(dev, master);
		dev->driver->master_destroy(dev, master);


	mutex_lock(&dev->struct_mutex);
	drm_legacy_master_rmmaps(dev, master);
	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
		if (r_list->master == master) {
			drm_legacy_rmmap_locked(dev, r_list->map);
			r_list = NULL;
		}
	}
	mutex_unlock(&dev->struct_mutex);


	idr_destroy(&master->magic_map);
	idr_destroy(&master->magic_map);
	kfree(master->unique);
	kfree(master->unique);
+3 −1
Original line number Original line Diff line number Diff line
@@ -154,8 +154,10 @@ struct drm_map_list {
int drm_legacy_addmap(struct drm_device *d, resource_size_t offset,
int drm_legacy_addmap(struct drm_device *d, resource_size_t offset,
		      unsigned int size, enum drm_map_type type,
		      unsigned int size, enum drm_map_type type,
		      enum drm_map_flags flags, struct drm_local_map **map_p);
		      enum drm_map_flags flags, struct drm_local_map **map_p);
int drm_legacy_rmmap(struct drm_device *d, struct drm_local_map *map);
void drm_legacy_rmmap(struct drm_device *d, struct drm_local_map *map);
int drm_legacy_rmmap_locked(struct drm_device *d, struct drm_local_map *map);
int drm_legacy_rmmap_locked(struct drm_device *d, struct drm_local_map *map);
void drm_legacy_master_rmmaps(struct drm_device *dev,
			      struct drm_master *master);
struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev);
struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev);
int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma);
int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma);