cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ttm_object.c (18759B)


      1/* SPDX-License-Identifier: GPL-2.0 OR MIT */
      2/**************************************************************************
      3 *
      4 * Copyright (c) 2009-2013 VMware, Inc., Palo Alto, CA., USA
      5 * All Rights Reserved.
      6 *
      7 * Permission is hereby granted, free of charge, to any person obtaining a
      8 * copy of this software and associated documentation files (the
      9 * "Software"), to deal in the Software without restriction, including
     10 * without limitation the rights to use, copy, modify, merge, publish,
     11 * distribute, sub license, and/or sell copies of the Software, and to
     12 * permit persons to whom the Software is furnished to do so, subject to
     13 * the following conditions:
     14 *
     15 * The above copyright notice and this permission notice (including the
     16 * next paragraph) shall be included in all copies or substantial portions
     17 * of the Software.
     18 *
     19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     22 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     25 * USE OR OTHER DEALINGS IN THE SOFTWARE.
     26 *
     27 **************************************************************************/
     28/*
     29 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
     30 *
     31 * While no substantial code is shared, the prime code is inspired by
     32 * drm_prime.c, with
     33 * Authors:
     34 *      Dave Airlie <airlied@redhat.com>
     35 *      Rob Clark <rob.clark@linaro.org>
     36 */
     37/** @file ttm_ref_object.c
     38 *
     39 * Base- and reference object implementation for the various
     40 * ttm objects. Implements reference counting, minimal security checks
     41 * and release on file close.
     42 */
     43
     44
     45#define pr_fmt(fmt) "[TTM] " fmt
     46
     47#include <linux/list.h>
     48#include <linux/spinlock.h>
     49#include <linux/slab.h>
     50#include <linux/atomic.h>
     51#include <linux/module.h>
     52#include "ttm_object.h"
     53#include "vmwgfx_drv.h"
     54
     55MODULE_IMPORT_NS(DMA_BUF);
     56
     57/**
     58 * struct ttm_object_file
     59 *
     60 * @tdev: Pointer to the ttm_object_device.
     61 *
     62 * @lock: Lock that protects the ref_list list and the
     63 * ref_hash hash tables.
     64 *
     65 * @ref_list: List of ttm_ref_objects to be destroyed at
     66 * file release.
     67 *
     68 * @ref_hash: Hash tables of ref objects, one per ttm_ref_type,
     69 * for fast lookup of ref objects given a base object.
     70 *
     71 * @refcount: reference/usage count
     72 */
     73struct ttm_object_file {
     74	struct ttm_object_device *tdev;
     75	spinlock_t lock;
     76	struct list_head ref_list;
     77	struct vmwgfx_open_hash ref_hash;
     78	struct kref refcount;
     79};
     80
     81/*
     82 * struct ttm_object_device
     83 *
     84 * @object_lock: lock that protects the object_hash hash table.
     85 *
     86 * @object_hash: hash table for fast lookup of object global names.
     87 *
     88 * @object_count: Per device object count.
     89 *
     90 * This is the per-device data structure needed for ttm object management.
     91 */
     92
     93struct ttm_object_device {
     94	spinlock_t object_lock;
     95	struct vmwgfx_open_hash object_hash;
     96	atomic_t object_count;
     97	struct dma_buf_ops ops;
     98	void (*dmabuf_release)(struct dma_buf *dma_buf);
     99	struct idr idr;
    100};
    101
    102/*
    103 * struct ttm_ref_object
    104 *
    105 * @hash: Hash entry for the per-file object reference hash.
    106 *
    107 * @head: List entry for the per-file list of ref-objects.
    108 *
    109 * @kref: Ref count.
    110 *
    111 * @obj: Base object this ref object is referencing.
    112 *
    113 * @ref_type: Type of ref object.
    114 *
    115 * This is similar to an idr object, but it also has a hash table entry
    116 * that allows lookup with a pointer to the referenced object as a key. In
    117 * that way, one can easily detect whether a base object is referenced by
    118 * a particular ttm_object_file. It also carries a ref count to avoid creating
    119 * multiple ref objects if a ttm_object_file references the same base
    120 * object more than once.
    121 */
    122
    123struct ttm_ref_object {
    124	struct rcu_head rcu_head;
    125	struct vmwgfx_hash_item hash;
    126	struct list_head head;
    127	struct kref kref;
    128	struct ttm_base_object *obj;
    129	struct ttm_object_file *tfile;
    130};
    131
    132static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf);
    133
    134static inline struct ttm_object_file *
    135ttm_object_file_ref(struct ttm_object_file *tfile)
    136{
    137	kref_get(&tfile->refcount);
    138	return tfile;
    139}
    140
    141static void ttm_object_file_destroy(struct kref *kref)
    142{
    143	struct ttm_object_file *tfile =
    144		container_of(kref, struct ttm_object_file, refcount);
    145
    146	kfree(tfile);
    147}
    148
    149
    150static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile)
    151{
    152	struct ttm_object_file *tfile = *p_tfile;
    153
    154	*p_tfile = NULL;
    155	kref_put(&tfile->refcount, ttm_object_file_destroy);
    156}
    157
    158
    159int ttm_base_object_init(struct ttm_object_file *tfile,
    160			 struct ttm_base_object *base,
    161			 bool shareable,
    162			 enum ttm_object_type object_type,
    163			 void (*refcount_release) (struct ttm_base_object **))
    164{
    165	struct ttm_object_device *tdev = tfile->tdev;
    166	int ret;
    167
    168	base->shareable = shareable;
    169	base->tfile = ttm_object_file_ref(tfile);
    170	base->refcount_release = refcount_release;
    171	base->object_type = object_type;
    172	kref_init(&base->refcount);
    173	idr_preload(GFP_KERNEL);
    174	spin_lock(&tdev->object_lock);
    175	ret = idr_alloc(&tdev->idr, base, 1, 0, GFP_NOWAIT);
    176	spin_unlock(&tdev->object_lock);
    177	idr_preload_end();
    178	if (ret < 0)
    179		return ret;
    180
    181	base->handle = ret;
    182	ret = ttm_ref_object_add(tfile, base, NULL, false);
    183	if (unlikely(ret != 0))
    184		goto out_err1;
    185
    186	ttm_base_object_unref(&base);
    187
    188	return 0;
    189out_err1:
    190	spin_lock(&tdev->object_lock);
    191	idr_remove(&tdev->idr, base->handle);
    192	spin_unlock(&tdev->object_lock);
    193	return ret;
    194}
    195
    196static void ttm_release_base(struct kref *kref)
    197{
    198	struct ttm_base_object *base =
    199	    container_of(kref, struct ttm_base_object, refcount);
    200	struct ttm_object_device *tdev = base->tfile->tdev;
    201
    202	spin_lock(&tdev->object_lock);
    203	idr_remove(&tdev->idr, base->handle);
    204	spin_unlock(&tdev->object_lock);
    205
    206	/*
    207	 * Note: We don't use synchronize_rcu() here because it's far
    208	 * too slow. It's up to the user to free the object using
    209	 * call_rcu() or ttm_base_object_kfree().
    210	 */
    211
    212	ttm_object_file_unref(&base->tfile);
    213	if (base->refcount_release)
    214		base->refcount_release(&base);
    215}
    216
    217void ttm_base_object_unref(struct ttm_base_object **p_base)
    218{
    219	struct ttm_base_object *base = *p_base;
    220
    221	*p_base = NULL;
    222
    223	kref_put(&base->refcount, ttm_release_base);
    224}
    225
    226/**
    227 * ttm_base_object_noref_lookup - look up a base object without reference
    228 * @tfile: The struct ttm_object_file the object is registered with.
    229 * @key: The object handle.
    230 *
    231 * This function looks up a ttm base object and returns a pointer to it
    232 * without refcounting the pointer. The returned pointer is only valid
    233 * until ttm_base_object_noref_release() is called, and the object
    234 * pointed to by the returned pointer may be doomed. Any persistent usage
    235 * of the object requires a refcount to be taken using kref_get_unless_zero().
    236 * Iff this function returns successfully it needs to be paired with
    237 * ttm_base_object_noref_release() and no sleeping- or scheduling functions
    238 * may be called inbetween these function callse.
    239 *
    240 * Return: A pointer to the object if successful or NULL otherwise.
    241 */
    242struct ttm_base_object *
    243ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key)
    244{
    245	struct vmwgfx_hash_item *hash;
    246	struct vmwgfx_open_hash *ht = &tfile->ref_hash;
    247	int ret;
    248
    249	rcu_read_lock();
    250	ret = vmwgfx_ht_find_item_rcu(ht, key, &hash);
    251	if (ret) {
    252		rcu_read_unlock();
    253		return NULL;
    254	}
    255
    256	__release(RCU);
    257	return drm_hash_entry(hash, struct ttm_ref_object, hash)->obj;
    258}
    259EXPORT_SYMBOL(ttm_base_object_noref_lookup);
    260
    261struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
    262					       uint32_t key)
    263{
    264	struct ttm_base_object *base = NULL;
    265	struct vmwgfx_hash_item *hash;
    266	struct vmwgfx_open_hash *ht = &tfile->ref_hash;
    267	int ret;
    268
    269	rcu_read_lock();
    270	ret = vmwgfx_ht_find_item_rcu(ht, key, &hash);
    271
    272	if (likely(ret == 0)) {
    273		base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj;
    274		if (!kref_get_unless_zero(&base->refcount))
    275			base = NULL;
    276	}
    277	rcu_read_unlock();
    278
    279	return base;
    280}
    281
    282struct ttm_base_object *
    283ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key)
    284{
    285	struct ttm_base_object *base;
    286
    287	rcu_read_lock();
    288	base = idr_find(&tdev->idr, key);
    289
    290	if (base && !kref_get_unless_zero(&base->refcount))
    291		base = NULL;
    292	rcu_read_unlock();
    293
    294	return base;
    295}
    296
    297int ttm_ref_object_add(struct ttm_object_file *tfile,
    298		       struct ttm_base_object *base,
    299		       bool *existed,
    300		       bool require_existed)
    301{
    302	struct vmwgfx_open_hash *ht = &tfile->ref_hash;
    303	struct ttm_ref_object *ref;
    304	struct vmwgfx_hash_item *hash;
    305	int ret = -EINVAL;
    306
    307	if (base->tfile != tfile && !base->shareable)
    308		return -EPERM;
    309
    310	if (existed != NULL)
    311		*existed = true;
    312
    313	while (ret == -EINVAL) {
    314		rcu_read_lock();
    315		ret = vmwgfx_ht_find_item_rcu(ht, base->handle, &hash);
    316
    317		if (ret == 0) {
    318			ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
    319			if (kref_get_unless_zero(&ref->kref)) {
    320				rcu_read_unlock();
    321				break;
    322			}
    323		}
    324
    325		rcu_read_unlock();
    326		if (require_existed)
    327			return -EPERM;
    328
    329		ref = kmalloc(sizeof(*ref), GFP_KERNEL);
    330		if (unlikely(ref == NULL)) {
    331			return -ENOMEM;
    332		}
    333
    334		ref->hash.key = base->handle;
    335		ref->obj = base;
    336		ref->tfile = tfile;
    337		kref_init(&ref->kref);
    338
    339		spin_lock(&tfile->lock);
    340		ret = vmwgfx_ht_insert_item_rcu(ht, &ref->hash);
    341
    342		if (likely(ret == 0)) {
    343			list_add_tail(&ref->head, &tfile->ref_list);
    344			kref_get(&base->refcount);
    345			spin_unlock(&tfile->lock);
    346			if (existed != NULL)
    347				*existed = false;
    348			break;
    349		}
    350
    351		spin_unlock(&tfile->lock);
    352		BUG_ON(ret != -EINVAL);
    353
    354		kfree(ref);
    355	}
    356
    357	return ret;
    358}
    359
    360static void __releases(tfile->lock) __acquires(tfile->lock)
    361ttm_ref_object_release(struct kref *kref)
    362{
    363	struct ttm_ref_object *ref =
    364	    container_of(kref, struct ttm_ref_object, kref);
    365	struct ttm_object_file *tfile = ref->tfile;
    366	struct vmwgfx_open_hash *ht;
    367
    368	ht = &tfile->ref_hash;
    369	(void)vmwgfx_ht_remove_item_rcu(ht, &ref->hash);
    370	list_del(&ref->head);
    371	spin_unlock(&tfile->lock);
    372
    373	ttm_base_object_unref(&ref->obj);
    374	kfree_rcu(ref, rcu_head);
    375	spin_lock(&tfile->lock);
    376}
    377
    378int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
    379			      unsigned long key)
    380{
    381	struct vmwgfx_open_hash *ht = &tfile->ref_hash;
    382	struct ttm_ref_object *ref;
    383	struct vmwgfx_hash_item *hash;
    384	int ret;
    385
    386	spin_lock(&tfile->lock);
    387	ret = vmwgfx_ht_find_item(ht, key, &hash);
    388	if (unlikely(ret != 0)) {
    389		spin_unlock(&tfile->lock);
    390		return -EINVAL;
    391	}
    392	ref = drm_hash_entry(hash, struct ttm_ref_object, hash);
    393	kref_put(&ref->kref, ttm_ref_object_release);
    394	spin_unlock(&tfile->lock);
    395	return 0;
    396}
    397
    398void ttm_object_file_release(struct ttm_object_file **p_tfile)
    399{
    400	struct ttm_ref_object *ref;
    401	struct list_head *list;
    402	struct ttm_object_file *tfile = *p_tfile;
    403
    404	*p_tfile = NULL;
    405	spin_lock(&tfile->lock);
    406
    407	/*
    408	 * Since we release the lock within the loop, we have to
    409	 * restart it from the beginning each time.
    410	 */
    411
    412	while (!list_empty(&tfile->ref_list)) {
    413		list = tfile->ref_list.next;
    414		ref = list_entry(list, struct ttm_ref_object, head);
    415		ttm_ref_object_release(&ref->kref);
    416	}
    417
    418	spin_unlock(&tfile->lock);
    419	vmwgfx_ht_remove(&tfile->ref_hash);
    420
    421	ttm_object_file_unref(&tfile);
    422}
    423
    424struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev,
    425					     unsigned int hash_order)
    426{
    427	struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
    428	int ret;
    429
    430	if (unlikely(tfile == NULL))
    431		return NULL;
    432
    433	spin_lock_init(&tfile->lock);
    434	tfile->tdev = tdev;
    435	kref_init(&tfile->refcount);
    436	INIT_LIST_HEAD(&tfile->ref_list);
    437
    438	ret = vmwgfx_ht_create(&tfile->ref_hash, hash_order);
    439	if (ret)
    440		goto out_err;
    441
    442	return tfile;
    443out_err:
    444	vmwgfx_ht_remove(&tfile->ref_hash);
    445
    446	kfree(tfile);
    447
    448	return NULL;
    449}
    450
    451struct ttm_object_device *
    452ttm_object_device_init(unsigned int hash_order,
    453		       const struct dma_buf_ops *ops)
    454{
    455	struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL);
    456	int ret;
    457
    458	if (unlikely(tdev == NULL))
    459		return NULL;
    460
    461	spin_lock_init(&tdev->object_lock);
    462	atomic_set(&tdev->object_count, 0);
    463	ret = vmwgfx_ht_create(&tdev->object_hash, hash_order);
    464	if (ret != 0)
    465		goto out_no_object_hash;
    466
    467	/*
    468	 * Our base is at VMWGFX_NUM_MOB + 1 because we want to create
    469	 * a seperate namespace for GEM handles (which are
    470	 * 1..VMWGFX_NUM_MOB) and the surface handles. Some ioctl's
    471	 * can take either handle as an argument so we want to
    472	 * easily be able to tell whether the handle refers to a
    473	 * GEM buffer or a surface.
    474	 */
    475	idr_init_base(&tdev->idr, VMWGFX_NUM_MOB + 1);
    476	tdev->ops = *ops;
    477	tdev->dmabuf_release = tdev->ops.release;
    478	tdev->ops.release = ttm_prime_dmabuf_release;
    479	return tdev;
    480
    481out_no_object_hash:
    482	kfree(tdev);
    483	return NULL;
    484}
    485
    486void ttm_object_device_release(struct ttm_object_device **p_tdev)
    487{
    488	struct ttm_object_device *tdev = *p_tdev;
    489
    490	*p_tdev = NULL;
    491
    492	WARN_ON_ONCE(!idr_is_empty(&tdev->idr));
    493	idr_destroy(&tdev->idr);
    494	vmwgfx_ht_remove(&tdev->object_hash);
    495
    496	kfree(tdev);
    497}
    498
    499/**
    500 * get_dma_buf_unless_doomed - get a dma_buf reference if possible.
    501 *
    502 * @dmabuf: Non-refcounted pointer to a struct dma-buf.
    503 *
    504 * Obtain a file reference from a lookup structure that doesn't refcount
    505 * the file, but synchronizes with its release method to make sure it has
    506 * not been freed yet. See for example kref_get_unless_zero documentation.
    507 * Returns true if refcounting succeeds, false otherwise.
    508 *
    509 * Nobody really wants this as a public API yet, so let it mature here
    510 * for some time...
    511 */
    512static bool __must_check get_dma_buf_unless_doomed(struct dma_buf *dmabuf)
    513{
    514	return atomic_long_inc_not_zero(&dmabuf->file->f_count) != 0L;
    515}
    516
    517/**
    518 * ttm_prime_refcount_release - refcount release method for a prime object.
    519 *
    520 * @p_base: Pointer to ttm_base_object pointer.
    521 *
    522 * This is a wrapper that calls the refcount_release founction of the
    523 * underlying object. At the same time it cleans up the prime object.
    524 * This function is called when all references to the base object we
    525 * derive from are gone.
    526 */
    527static void ttm_prime_refcount_release(struct ttm_base_object **p_base)
    528{
    529	struct ttm_base_object *base = *p_base;
    530	struct ttm_prime_object *prime;
    531
    532	*p_base = NULL;
    533	prime = container_of(base, struct ttm_prime_object, base);
    534	BUG_ON(prime->dma_buf != NULL);
    535	mutex_destroy(&prime->mutex);
    536	if (prime->refcount_release)
    537		prime->refcount_release(&base);
    538}
    539
    540/**
    541 * ttm_prime_dmabuf_release - Release method for the dma-bufs we export
    542 *
    543 * @dma_buf:
    544 *
    545 * This function first calls the dma_buf release method the driver
    546 * provides. Then it cleans up our dma_buf pointer used for lookup,
    547 * and finally releases the reference the dma_buf has on our base
    548 * object.
    549 */
    550static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf)
    551{
    552	struct ttm_prime_object *prime =
    553		(struct ttm_prime_object *) dma_buf->priv;
    554	struct ttm_base_object *base = &prime->base;
    555	struct ttm_object_device *tdev = base->tfile->tdev;
    556
    557	if (tdev->dmabuf_release)
    558		tdev->dmabuf_release(dma_buf);
    559	mutex_lock(&prime->mutex);
    560	if (prime->dma_buf == dma_buf)
    561		prime->dma_buf = NULL;
    562	mutex_unlock(&prime->mutex);
    563	ttm_base_object_unref(&base);
    564}
    565
    566/**
    567 * ttm_prime_fd_to_handle - Get a base object handle from a prime fd
    568 *
    569 * @tfile: A struct ttm_object_file identifying the caller.
    570 * @fd: The prime / dmabuf fd.
    571 * @handle: The returned handle.
    572 *
    573 * This function returns a handle to an object that previously exported
    574 * a dma-buf. Note that we don't handle imports yet, because we simply
    575 * have no consumers of that implementation.
    576 */
    577int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
    578			   int fd, u32 *handle)
    579{
    580	struct ttm_object_device *tdev = tfile->tdev;
    581	struct dma_buf *dma_buf;
    582	struct ttm_prime_object *prime;
    583	struct ttm_base_object *base;
    584	int ret;
    585
    586	dma_buf = dma_buf_get(fd);
    587	if (IS_ERR(dma_buf))
    588		return PTR_ERR(dma_buf);
    589
    590	if (dma_buf->ops != &tdev->ops)
    591		return -ENOSYS;
    592
    593	prime = (struct ttm_prime_object *) dma_buf->priv;
    594	base = &prime->base;
    595	*handle = base->handle;
    596	ret = ttm_ref_object_add(tfile, base, NULL, false);
    597
    598	dma_buf_put(dma_buf);
    599
    600	return ret;
    601}
    602
    603/**
    604 * ttm_prime_handle_to_fd - Return a dma_buf fd from a ttm prime object
    605 *
    606 * @tfile: Struct ttm_object_file identifying the caller.
    607 * @handle: Handle to the object we're exporting from.
    608 * @flags: flags for dma-buf creation. We just pass them on.
    609 * @prime_fd: The returned file descriptor.
    610 *
    611 */
    612int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
    613			   uint32_t handle, uint32_t flags,
    614			   int *prime_fd)
    615{
    616	struct ttm_object_device *tdev = tfile->tdev;
    617	struct ttm_base_object *base;
    618	struct dma_buf *dma_buf;
    619	struct ttm_prime_object *prime;
    620	int ret;
    621
    622	base = ttm_base_object_lookup(tfile, handle);
    623	if (unlikely(base == NULL ||
    624		     base->object_type != ttm_prime_type)) {
    625		ret = -ENOENT;
    626		goto out_unref;
    627	}
    628
    629	prime = container_of(base, struct ttm_prime_object, base);
    630	if (unlikely(!base->shareable)) {
    631		ret = -EPERM;
    632		goto out_unref;
    633	}
    634
    635	ret = mutex_lock_interruptible(&prime->mutex);
    636	if (unlikely(ret != 0)) {
    637		ret = -ERESTARTSYS;
    638		goto out_unref;
    639	}
    640
    641	dma_buf = prime->dma_buf;
    642	if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) {
    643		DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
    644		exp_info.ops = &tdev->ops;
    645		exp_info.size = prime->size;
    646		exp_info.flags = flags;
    647		exp_info.priv = prime;
    648
    649		/*
    650		 * Need to create a new dma_buf
    651		 */
    652
    653		dma_buf = dma_buf_export(&exp_info);
    654		if (IS_ERR(dma_buf)) {
    655			ret = PTR_ERR(dma_buf);
    656			mutex_unlock(&prime->mutex);
    657			goto out_unref;
    658		}
    659
    660		/*
    661		 * dma_buf has taken the base object reference
    662		 */
    663		base = NULL;
    664		prime->dma_buf = dma_buf;
    665	}
    666	mutex_unlock(&prime->mutex);
    667
    668	ret = dma_buf_fd(dma_buf, flags);
    669	if (ret >= 0) {
    670		*prime_fd = ret;
    671		ret = 0;
    672	} else
    673		dma_buf_put(dma_buf);
    674
    675out_unref:
    676	if (base)
    677		ttm_base_object_unref(&base);
    678	return ret;
    679}
    680
    681/**
    682 * ttm_prime_object_init - Initialize a ttm_prime_object
    683 *
    684 * @tfile: struct ttm_object_file identifying the caller
    685 * @size: The size of the dma_bufs we export.
    686 * @prime: The object to be initialized.
    687 * @shareable: See ttm_base_object_init
    688 * @type: See ttm_base_object_init
    689 * @refcount_release: See ttm_base_object_init
    690 *
    691 * Initializes an object which is compatible with the drm_prime model
    692 * for data sharing between processes and devices.
    693 */
    694int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size,
    695			  struct ttm_prime_object *prime, bool shareable,
    696			  enum ttm_object_type type,
    697			  void (*refcount_release) (struct ttm_base_object **))
    698{
    699	mutex_init(&prime->mutex);
    700	prime->size = PAGE_ALIGN(size);
    701	prime->real_type = type;
    702	prime->dma_buf = NULL;
    703	prime->refcount_release = refcount_release;
    704	return ttm_base_object_init(tfile, &prime->base, shareable,
    705				    ttm_prime_type,
    706				    ttm_prime_refcount_release);
    707}