コード例 #1
0
ファイル: radeon_gem.c プロジェクト: kvaneesh/linux-kvm
int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
			    struct drm_file *filp)
{
	struct radeon_device *rdev = dev->dev_private;
	struct drm_radeon_gem_create *args = data;
	struct drm_gem_object *gobj;
	uint32_t handle;
	int r;

	/* create a gem object to contain this object in */
	args->size = roundup(args->size, PAGE_SIZE);
	r = radeon_gem_object_create(rdev, args->size, args->alignment,
					args->initial_domain, false,
					false, &gobj);
	if (r) {
		return r;
	}
	r = drm_gem_handle_create(filp, gobj, &handle);
	if (r) {
		drm_gem_object_unreference_unlocked(gobj);
		return r;
	}
	drm_gem_object_handle_unreference_unlocked(gobj);
	args->handle = handle;
	return 0;
}
コード例 #2
0
ファイル: drm_gem.c プロジェクト: yyzreal/cedarview-drm
/**
 * Removes the mapping from handle to filp for this object.
 */
int
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
{
    struct drm_device *dev;
    struct drm_gem_object *obj;

    /* This is gross. The idr system doesn't let us try a delete and
     * return an error code.  It just spews if you fail at deleting.
     * So, we have to grab a lock around finding the object and then
     * doing the delete on it and dropping the refcount, or the user
     * could race us to double-decrement the refcount and cause a
     * use-after-free later.  Given the frequency of our handle lookups,
     * we may want to use ida for number allocation and a hash table
     * for the pointers, anyway.
     */
    spin_lock(&filp->table_lock);

    /* Check if we currently have a reference on the object */
    obj = idr_find(&filp->object_idr, handle);
    if (obj == NULL) {
        spin_unlock(&filp->table_lock);
        return -EINVAL;
    }
    dev = obj->dev;

    /* Release reference and decrement refcount. */
    idr_remove(&filp->object_idr, handle);
    spin_unlock(&filp->table_lock);

    if (dev->driver->gem_close_object)
        dev->driver->gem_close_object(obj, filp);
    drm_gem_object_handle_unreference_unlocked(obj);

    return 0;
}
コード例 #3
0
ファイル: drm_gem.c プロジェクト: Adjustxx/Savaged-Zen
/**
 * Called at device close to release the file's
 * handle references on objects.
 */
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
	struct drm_gem_object *obj = ptr;

	drm_gem_object_handle_unreference_unlocked(obj);

	return 0;
}
コード例 #4
0
int
drm_gem_handle_delete(struct drm_file *file_priv, uint32_t handle)
{
	struct drm_gem_object *obj;

	obj = drm_gem_names_remove(&file_priv->object_names, handle);
	if (obj == NULL)
		return (EINVAL);
	drm_gem_object_handle_unreference_unlocked(obj);
	return (0);
}
コード例 #5
0
ファイル: drm_gem.c プロジェクト: yyzreal/cedarview-drm
/**
 * Called at device close to release the file's
 * handle references on objects.
 */
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
    struct drm_file *file_priv = data;
    struct drm_gem_object *obj = ptr;
    struct drm_device *dev = obj->dev;

    if (dev->driver->gem_close_object)
        dev->driver->gem_close_object(obj, file_priv);

    drm_gem_object_handle_unreference_unlocked(obj);

    return 0;
}
コード例 #6
0
int
nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_nouveau_gem_new *req = data;
	struct nouveau_bo *nvbo = NULL;
	struct nouveau_channel *chan = NULL;
	uint32_t flags = 0;
	int ret = 0;

	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;

	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;

	if (req->channel_hint) {
		NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint,
						     file_priv, chan);
	}

	if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM)
		flags |= TTM_PL_FLAG_VRAM;
	if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART)
		flags |= TTM_PL_FLAG_TT;
	if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU)
		flags |= TTM_PL_FLAG_SYSTEM;

	if (!nouveau_gem_tile_flags_valid(dev, req->info.tile_flags))
		return -EINVAL;

	ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags,
			      req->info.tile_mode, req->info.tile_flags, false,
			      (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE),
			      &nvbo);
	if (ret)
		return ret;

	ret = nouveau_gem_info(nvbo->gem, &req->info);
	if (ret)
		goto out;

	ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
out:
	drm_gem_object_handle_unreference_unlocked(nvbo->gem);

	if (ret)
		drm_gem_object_unreference_unlocked(nvbo->gem);
	return ret;
}
コード例 #7
0
void
nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
{
	struct drm_device *dev = chan->dev;

	if (!chan->notifier_bo)
		return;

	nouveau_bo_unmap(chan->notifier_bo);
	mutex_lock(&dev->struct_mutex);
	nouveau_bo_unpin(chan->notifier_bo);
	mutex_unlock(&dev->struct_mutex);
	drm_gem_object_handle_unreference_unlocked(chan->notifier_bo->gem);
	drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
	drm_mm_takedown(&chan->notifier_heap);
}
コード例 #8
0
/**
 * drm_gem_handle_create_tail - internal functions to create a handle
 * @file_priv: drm file-private structure to register the handle for
 * @obj: object to register
 * @handlep: pointer to return the created handle to the caller
 * 
 * This expects the dev->object_name_lock to be held already and will drop it
 * before returning. Used to avoid races in establishing new handles when
 * importing an object from either an flink name or a dma-buf.
 */
int
drm_gem_handle_create_tail(struct drm_file *file_priv,
			   struct drm_gem_object *obj,
			   u32 *handlep)
{
	struct drm_device *dev = obj->dev;
	int ret;

	WARN_ON(!mutex_is_locked(&dev->object_name_lock));

	/*
	 * Get the user-visible handle using idr.  Preload and perform
	 * allocation under our spinlock.
	 */
	idr_preload(GFP_KERNEL);
	spin_lock(&file_priv->table_lock);

	ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
	drm_gem_object_reference(obj);
	obj->handle_count++;
	spin_unlock(&file_priv->table_lock);
	idr_preload_end();
	mutex_unlock(&dev->object_name_lock);
	if (ret < 0) {
		drm_gem_object_handle_unreference_unlocked(obj);
		return ret;
	}
	*handlep = ret;

	ret = drm_vma_node_allow(&obj->vma_node, file_priv->filp);
	if (ret) {
		drm_gem_handle_delete(file_priv, *handlep);
		return ret;
	}

	if (dev->driver->gem_open_object) {
		ret = dev->driver->gem_open_object(obj, file_priv);
		if (ret) {
			drm_gem_handle_delete(file_priv, *handlep);
			return ret;
		}
	}

	return 0;
}
コード例 #9
0
/*
 * Called at device close to release the file's
 * handle references on objects.
 */
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
	struct drm_file *file_priv = data;
	struct drm_gem_object *obj = ptr;
	struct drm_device *dev = obj->dev;

	if (drm_core_check_feature(dev, DRIVER_PRIME))
		drm_gem_remove_prime_handles(obj, file_priv);
	drm_vma_node_revoke(&obj->vma_node, file_priv->filp);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, file_priv);

	drm_gem_object_handle_unreference_unlocked(obj);

	return 0;
}
コード例 #10
0
ファイル: drm_gem.c プロジェクト: coyizumi/cs111
static int
drm_gem_object_release_handle(uint32_t name, void *ptr, void *data)
{
    struct drm_file *file_priv = data;
    struct drm_gem_object *obj = ptr;
    struct drm_device *dev = obj->dev;

#if defined(FREEBSD_NOTYET)
    drm_gem_remove_prime_handles(obj, file_priv);
#endif

    if (dev->driver->gem_close_object)
        dev->driver->gem_close_object(obj, file_priv);

    drm_gem_object_handle_unreference_unlocked(obj);

    return 0;
}
コード例 #11
0
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
	struct drm_file *file_priv = data;
	struct drm_gem_object *obj = ptr;
	struct drm_device *dev = obj->dev;

	if (obj->import_attach)
		drm_prime_remove_imported_buf_handle(&file_priv->prime,
				obj->import_attach->dmabuf);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, file_priv);

	drm_gem_object_handle_unreference_unlocked(obj);

	return 0;
}
コード例 #12
0
/**
 * Called at device close to release the file's
 * handle references on objects.
 */
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
	struct drm_file *file_priv = data;
	struct drm_gem_object *obj = ptr;
	struct drm_device *dev = obj->dev;

#ifndef __NetBSD__			/* XXX drm prime */
	drm_gem_remove_prime_handles(obj, file_priv);
#endif

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, file_priv);

	drm_gem_object_handle_unreference_unlocked(obj);

	return 0;
}
コード例 #13
0
ファイル: drm_gem.c プロジェクト: coyizumi/cs111
/**
 * Removes the mapping from handle to filp for this object.
 */
int
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
{
    struct drm_device *dev;
    struct drm_gem_object *obj;

    obj = drm_gem_names_remove(&filp->object_names, handle);
    if (obj == NULL) {
        return -EINVAL;
    }
    dev = obj->dev;

#if defined(FREEBSD_NOTYET)
    drm_gem_remove_prime_handles(obj, filp);
#endif

    if (dev->driver->gem_close_object)
        dev->driver->gem_close_object(obj, filp);
    drm_gem_object_handle_unreference_unlocked(obj);

    return 0;
}
コード例 #14
0
int
drm_gem_handle_delete(struct drm_file *filp, u32 handle)
{
	struct drm_device *dev;
	struct drm_gem_object *obj;

	/*                                                              
                                                                 
                                                                 
                                                                 
                                                              
                                                                     
                                                                 
                             
  */
	spin_lock(&filp->table_lock);

	/*                                                      */
	obj = idr_find(&filp->object_idr, handle);
	if (obj == NULL) {
		spin_unlock(&filp->table_lock);
		return -EINVAL;
	}
	dev = obj->dev;

	/*                                           */
	idr_remove(&filp->object_idr, handle);
	spin_unlock(&filp->table_lock);

	if (obj->import_attach)
		drm_prime_remove_imported_buf_handle(&filp->prime,
				obj->import_attach->dmabuf);

	if (dev->driver->gem_close_object)
		dev->driver->gem_close_object(obj, filp);
	drm_gem_object_handle_unreference_unlocked(obj);

	return 0;
}