xref: /dragonfly/sys/dev/drm/i915/i915_gem_dmabuf.c (revision 3f2dd94a)
18665870eSFrançois Tigeot /*
28665870eSFrançois Tigeot  * Copyright 2012 Red Hat Inc
38665870eSFrançois Tigeot  *
48665870eSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
58665870eSFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
68665870eSFrançois Tigeot  * to deal in the Software without restriction, including without limitation
78665870eSFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88665870eSFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
98665870eSFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
108665870eSFrançois Tigeot  *
118665870eSFrançois Tigeot  * The above copyright notice and this permission notice (including the next
128665870eSFrançois Tigeot  * paragraph) shall be included in all copies or substantial portions of the
138665870eSFrançois Tigeot  * Software.
148665870eSFrançois Tigeot  *
158665870eSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168665870eSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178665870eSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
188665870eSFrançois Tigeot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198665870eSFrançois Tigeot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
208665870eSFrançois Tigeot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
218665870eSFrançois Tigeot  * DEALINGS IN THE SOFTWARE.
228665870eSFrançois Tigeot  *
238665870eSFrançois Tigeot  * Authors:
248665870eSFrançois Tigeot  *	Dave Airlie <airlied@redhat.com>
258665870eSFrançois Tigeot  */
2671f41f3eSFrançois Tigeot 
278665870eSFrançois Tigeot #include <linux/dma-buf.h>
2871f41f3eSFrançois Tigeot #include <linux/reservation.h>
2971f41f3eSFrançois Tigeot 
3071f41f3eSFrançois Tigeot #include <drm/drmP.h>
3171f41f3eSFrançois Tigeot 
3271f41f3eSFrançois Tigeot #include "i915_drv.h"
338665870eSFrançois Tigeot 
dma_buf_to_obj(struct dma_buf * buf)348665870eSFrançois Tigeot static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf)
358665870eSFrançois Tigeot {
368665870eSFrançois Tigeot 	return to_intel_bo(buf->priv);
378665870eSFrançois Tigeot }
388665870eSFrançois Tigeot 
i915_gem_map_dma_buf(struct dma_buf_attachment * attachment,enum dma_data_direction dir)398665870eSFrançois Tigeot static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachment,
408665870eSFrançois Tigeot 					     enum dma_data_direction dir)
418665870eSFrançois Tigeot {
428665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
438665870eSFrançois Tigeot 	struct sg_table *st;
448665870eSFrançois Tigeot 	struct scatterlist *src, *dst;
458665870eSFrançois Tigeot 	int ret, i;
468665870eSFrançois Tigeot 
474be47400SFrançois Tigeot 	ret = i915_gem_object_pin_pages(obj);
488665870eSFrançois Tigeot 	if (ret)
498665870eSFrançois Tigeot 		goto err;
508665870eSFrançois Tigeot 
518665870eSFrançois Tigeot 	/* Copy sg so that we make an independent mapping */
521487f786SFrançois Tigeot 	st = kmalloc(sizeof(struct sg_table), M_DRM, GFP_KERNEL);
538665870eSFrançois Tigeot 	if (st == NULL) {
548665870eSFrançois Tigeot 		ret = -ENOMEM;
554be47400SFrançois Tigeot 		goto err_unpin_pages;
568665870eSFrançois Tigeot 	}
578665870eSFrançois Tigeot 
584be47400SFrançois Tigeot 	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
598665870eSFrançois Tigeot 	if (ret)
608665870eSFrançois Tigeot 		goto err_free;
618665870eSFrançois Tigeot 
624be47400SFrançois Tigeot 	src = obj->mm.pages->sgl;
638665870eSFrançois Tigeot 	dst = st->sgl;
644be47400SFrançois Tigeot 	for (i = 0; i < obj->mm.pages->nents; i++) {
658665870eSFrançois Tigeot 		sg_set_page(dst, sg_page(src), src->length, 0);
668665870eSFrançois Tigeot 		dst = sg_next(dst);
678665870eSFrançois Tigeot 		src = sg_next(src);
688665870eSFrançois Tigeot 	}
698665870eSFrançois Tigeot 
708665870eSFrançois Tigeot 	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
718665870eSFrançois Tigeot 		ret = -ENOMEM;
728665870eSFrançois Tigeot 		goto err_free_sg;
738665870eSFrançois Tigeot 	}
748665870eSFrançois Tigeot 
758665870eSFrançois Tigeot 	return st;
768665870eSFrançois Tigeot 
778665870eSFrançois Tigeot err_free_sg:
788665870eSFrançois Tigeot 	sg_free_table(st);
798665870eSFrançois Tigeot err_free:
808665870eSFrançois Tigeot 	kfree(st);
814be47400SFrançois Tigeot err_unpin_pages:
828665870eSFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
838665870eSFrançois Tigeot err:
848665870eSFrançois Tigeot 	return ERR_PTR(ret);
858665870eSFrançois Tigeot }
868665870eSFrançois Tigeot 
i915_gem_unmap_dma_buf(struct dma_buf_attachment * attachment,struct sg_table * sg,enum dma_data_direction dir)878665870eSFrançois Tigeot static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
888665870eSFrançois Tigeot 				   struct sg_table *sg,
898665870eSFrançois Tigeot 				   enum dma_data_direction dir)
908665870eSFrançois Tigeot {
918665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
928665870eSFrançois Tigeot 
938665870eSFrançois Tigeot 	dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
948665870eSFrançois Tigeot 	sg_free_table(sg);
958665870eSFrançois Tigeot 	kfree(sg);
968665870eSFrançois Tigeot 
978665870eSFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
988665870eSFrançois Tigeot }
998665870eSFrançois Tigeot 
i915_gem_dmabuf_vmap(struct dma_buf * dma_buf)1008665870eSFrançois Tigeot static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
1018665870eSFrançois Tigeot {
1028665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1038665870eSFrançois Tigeot 
1044be47400SFrançois Tigeot 	return i915_gem_object_pin_map(obj, I915_MAP_WB);
1058665870eSFrançois Tigeot }
1068665870eSFrançois Tigeot 
i915_gem_dmabuf_vunmap(struct dma_buf * dma_buf,void * vaddr)1078665870eSFrançois Tigeot static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
1088665870eSFrançois Tigeot {
1098665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1108665870eSFrançois Tigeot 
1118665870eSFrançois Tigeot 	i915_gem_object_unpin_map(obj);
1128665870eSFrançois Tigeot }
1138665870eSFrançois Tigeot 
i915_gem_dmabuf_kmap_atomic(struct dma_buf * dma_buf,unsigned long page_num)1148665870eSFrançois Tigeot static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
1158665870eSFrançois Tigeot {
1168665870eSFrançois Tigeot 	return NULL;
1178665870eSFrançois Tigeot }
1188665870eSFrançois Tigeot 
i915_gem_dmabuf_kunmap_atomic(struct dma_buf * dma_buf,unsigned long page_num,void * addr)1198665870eSFrançois Tigeot static void i915_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
1208665870eSFrançois Tigeot {
1218665870eSFrançois Tigeot 
1228665870eSFrançois Tigeot }
i915_gem_dmabuf_kmap(struct dma_buf * dma_buf,unsigned long page_num)1238665870eSFrançois Tigeot static void *i915_gem_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
1248665870eSFrançois Tigeot {
125*3f2dd94aSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
126*3f2dd94aSFrançois Tigeot 	struct page *page;
127*3f2dd94aSFrançois Tigeot 
128*3f2dd94aSFrançois Tigeot 	if (page_num >= obj->base.size >> PAGE_SHIFT)
129*3f2dd94aSFrançois Tigeot 		return NULL;
130*3f2dd94aSFrançois Tigeot 
131*3f2dd94aSFrançois Tigeot 	if (!i915_gem_object_has_struct_page(obj))
132*3f2dd94aSFrançois Tigeot 		return NULL;
133*3f2dd94aSFrançois Tigeot 
134*3f2dd94aSFrançois Tigeot 	if (i915_gem_object_pin_pages(obj))
135*3f2dd94aSFrançois Tigeot 		return NULL;
136*3f2dd94aSFrançois Tigeot 
137*3f2dd94aSFrançois Tigeot 	/* Synchronisation is left to the caller (via .begin_cpu_access()) */
138*3f2dd94aSFrançois Tigeot 	page = i915_gem_object_get_page(obj, page_num);
139*3f2dd94aSFrançois Tigeot 	if (IS_ERR(page))
140*3f2dd94aSFrançois Tigeot 		goto err_unpin;
141*3f2dd94aSFrançois Tigeot 
142*3f2dd94aSFrançois Tigeot 	return kmap(page);
143*3f2dd94aSFrançois Tigeot 
144*3f2dd94aSFrançois Tigeot err_unpin:
145*3f2dd94aSFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
1468665870eSFrançois Tigeot 	return NULL;
1478665870eSFrançois Tigeot }
1488665870eSFrançois Tigeot 
i915_gem_dmabuf_kunmap(struct dma_buf * dma_buf,unsigned long page_num,void * addr)1498665870eSFrançois Tigeot static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
1508665870eSFrançois Tigeot {
151*3f2dd94aSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1528665870eSFrançois Tigeot 
153*3f2dd94aSFrançois Tigeot 	kunmap(virt_to_page(addr));
154*3f2dd94aSFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
1558665870eSFrançois Tigeot }
1568665870eSFrançois Tigeot 
i915_gem_dmabuf_mmap(struct dma_buf * dma_buf,struct vm_area_struct * vma)1578665870eSFrançois Tigeot static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
1588665870eSFrançois Tigeot {
1598665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1608665870eSFrançois Tigeot #if 0
1618665870eSFrançois Tigeot 	int ret;
1628665870eSFrançois Tigeot #endif
1638665870eSFrançois Tigeot 
1648665870eSFrançois Tigeot 	if (obj->base.size < vma->vm_end - vma->vm_start)
1658665870eSFrançois Tigeot 		return -EINVAL;
1668665870eSFrançois Tigeot 
1678665870eSFrançois Tigeot 	if (!obj->base.filp)
1688665870eSFrançois Tigeot 		return -ENODEV;
1698665870eSFrançois Tigeot 
1708665870eSFrançois Tigeot #if 0
1718665870eSFrançois Tigeot 	ret = obj->base.filp->f_op->mmap(obj->base.filp, vma);
1728665870eSFrançois Tigeot 	if (ret)
1738665870eSFrançois Tigeot 		return ret;
1748665870eSFrançois Tigeot 
1758665870eSFrançois Tigeot 	fput(vma->vm_file);
1768665870eSFrançois Tigeot 	vma->vm_file = get_file(obj->base.filp);
1778665870eSFrançois Tigeot #endif
1788665870eSFrançois Tigeot 
1798665870eSFrançois Tigeot 	return 0;
1808665870eSFrançois Tigeot }
1818665870eSFrançois Tigeot 
i915_gem_begin_cpu_access(struct dma_buf * dma_buf,enum dma_data_direction direction)1828665870eSFrançois Tigeot static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
1838665870eSFrançois Tigeot {
1848665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
1858665870eSFrançois Tigeot 	struct drm_device *dev = obj->base.dev;
1868665870eSFrançois Tigeot 	bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
1874be47400SFrançois Tigeot 	int err;
1888665870eSFrançois Tigeot 
1894be47400SFrançois Tigeot 	err = i915_gem_object_pin_pages(obj);
1904be47400SFrançois Tigeot 	if (err)
1914be47400SFrançois Tigeot 		return err;
1928665870eSFrançois Tigeot 
1934be47400SFrançois Tigeot 	err = i915_mutex_lock_interruptible(dev);
1944be47400SFrançois Tigeot 	if (err)
1954be47400SFrançois Tigeot 		goto out;
1964be47400SFrançois Tigeot 
1974be47400SFrançois Tigeot 	err = i915_gem_object_set_to_cpu_domain(obj, write);
1988665870eSFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
1994be47400SFrançois Tigeot 
2004be47400SFrançois Tigeot out:
2014be47400SFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
2024be47400SFrançois Tigeot 	return err;
2038665870eSFrançois Tigeot }
2048665870eSFrançois Tigeot 
i915_gem_end_cpu_access(struct dma_buf * dma_buf,enum dma_data_direction direction)2058665870eSFrançois Tigeot static int i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction)
2068665870eSFrançois Tigeot {
2078665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
2088665870eSFrançois Tigeot 	struct drm_device *dev = obj->base.dev;
2094be47400SFrançois Tigeot 	int err;
2108665870eSFrançois Tigeot 
2114be47400SFrançois Tigeot 	err = i915_gem_object_pin_pages(obj);
2124be47400SFrançois Tigeot 	if (err)
2134be47400SFrançois Tigeot 		return err;
2148665870eSFrançois Tigeot 
2154be47400SFrançois Tigeot 	err = i915_mutex_lock_interruptible(dev);
2164be47400SFrançois Tigeot 	if (err)
2174be47400SFrançois Tigeot 		goto out;
2184be47400SFrançois Tigeot 
2194be47400SFrançois Tigeot 	err = i915_gem_object_set_to_gtt_domain(obj, false);
2208665870eSFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
2218665870eSFrançois Tigeot 
2224be47400SFrançois Tigeot out:
2234be47400SFrançois Tigeot 	i915_gem_object_unpin_pages(obj);
2244be47400SFrançois Tigeot 	return err;
2258665870eSFrançois Tigeot }
2268665870eSFrançois Tigeot 
2278665870eSFrançois Tigeot static const struct dma_buf_ops i915_dmabuf_ops =  {
2288665870eSFrançois Tigeot 	.map_dma_buf = i915_gem_map_dma_buf,
2298665870eSFrançois Tigeot 	.unmap_dma_buf = i915_gem_unmap_dma_buf,
2308665870eSFrançois Tigeot 	.release = drm_gem_dmabuf_release,
231a85cb24fSFrançois Tigeot 	.map = i915_gem_dmabuf_kmap,
232a85cb24fSFrançois Tigeot 	.map_atomic = i915_gem_dmabuf_kmap_atomic,
233a85cb24fSFrançois Tigeot 	.unmap = i915_gem_dmabuf_kunmap,
234a85cb24fSFrançois Tigeot 	.unmap_atomic = i915_gem_dmabuf_kunmap_atomic,
2358665870eSFrançois Tigeot 	.mmap = i915_gem_dmabuf_mmap,
2368665870eSFrançois Tigeot 	.vmap = i915_gem_dmabuf_vmap,
2378665870eSFrançois Tigeot 	.vunmap = i915_gem_dmabuf_vunmap,
2388665870eSFrançois Tigeot 	.begin_cpu_access = i915_gem_begin_cpu_access,
2398665870eSFrançois Tigeot 	.end_cpu_access = i915_gem_end_cpu_access,
2408665870eSFrançois Tigeot };
2418665870eSFrançois Tigeot 
i915_gem_prime_export(struct drm_device * dev,struct drm_gem_object * gem_obj,int flags)2428665870eSFrançois Tigeot struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
2438665870eSFrançois Tigeot 				      struct drm_gem_object *gem_obj, int flags)
2448665870eSFrançois Tigeot {
2458665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
2468665870eSFrançois Tigeot 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
2478665870eSFrançois Tigeot 
2488665870eSFrançois Tigeot 	exp_info.ops = &i915_dmabuf_ops;
2498665870eSFrançois Tigeot 	exp_info.size = gem_obj->size;
2508665870eSFrançois Tigeot 	exp_info.flags = flags;
2518665870eSFrançois Tigeot 	exp_info.priv = gem_obj;
2524be47400SFrançois Tigeot 	exp_info.resv = obj->resv;
2538665870eSFrançois Tigeot 
2548665870eSFrançois Tigeot 	if (obj->ops->dmabuf_export) {
2558665870eSFrançois Tigeot 		int ret = obj->ops->dmabuf_export(obj);
2568665870eSFrançois Tigeot 		if (ret)
2578665870eSFrançois Tigeot 			return ERR_PTR(ret);
2588665870eSFrançois Tigeot 	}
2598665870eSFrançois Tigeot 
2604be47400SFrançois Tigeot 	return drm_gem_dmabuf_export(dev, &exp_info);
2618665870eSFrançois Tigeot }
2628665870eSFrançois Tigeot 
i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object * obj)263*3f2dd94aSFrançois Tigeot static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
2648665870eSFrançois Tigeot {
265*3f2dd94aSFrançois Tigeot 	struct sg_table *pages;
266*3f2dd94aSFrançois Tigeot 	unsigned int sg_page_sizes;
267*3f2dd94aSFrançois Tigeot 
268*3f2dd94aSFrançois Tigeot 	pages = dma_buf_map_attachment(obj->base.import_attach,
2694be47400SFrançois Tigeot 				       DMA_BIDIRECTIONAL);
270*3f2dd94aSFrançois Tigeot 	if (IS_ERR(pages))
271*3f2dd94aSFrançois Tigeot 		return PTR_ERR(pages);
272*3f2dd94aSFrançois Tigeot 
273*3f2dd94aSFrançois Tigeot 	sg_page_sizes = i915_sg_page_sizes(pages->sgl);
274*3f2dd94aSFrançois Tigeot 
275*3f2dd94aSFrançois Tigeot 	__i915_gem_object_set_pages(obj, pages, sg_page_sizes);
276*3f2dd94aSFrançois Tigeot 
277*3f2dd94aSFrançois Tigeot 	return 0;
2788665870eSFrançois Tigeot }
2798665870eSFrançois Tigeot 
i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object * obj,struct sg_table * pages)2804be47400SFrançois Tigeot static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj,
2814be47400SFrançois Tigeot 					     struct sg_table *pages)
2828665870eSFrançois Tigeot {
2834be47400SFrançois Tigeot 	dma_buf_unmap_attachment(obj->base.import_attach, pages,
2844be47400SFrançois Tigeot 				 DMA_BIDIRECTIONAL);
2858665870eSFrançois Tigeot }
2868665870eSFrançois Tigeot 
2878665870eSFrançois Tigeot static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
2888665870eSFrançois Tigeot 	.get_pages = i915_gem_object_get_pages_dmabuf,
2898665870eSFrançois Tigeot 	.put_pages = i915_gem_object_put_pages_dmabuf,
2908665870eSFrançois Tigeot };
2918665870eSFrançois Tigeot 
i915_gem_prime_import(struct drm_device * dev,struct dma_buf * dma_buf)2928665870eSFrançois Tigeot struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
2938665870eSFrançois Tigeot 					     struct dma_buf *dma_buf)
2948665870eSFrançois Tigeot {
2958665870eSFrançois Tigeot 	struct dma_buf_attachment *attach;
2968665870eSFrançois Tigeot 	struct drm_i915_gem_object *obj;
2978665870eSFrançois Tigeot 	int ret;
2988665870eSFrançois Tigeot 
2998665870eSFrançois Tigeot 	/* is this one of own objects? */
3008665870eSFrançois Tigeot 	if (dma_buf->ops == &i915_dmabuf_ops) {
3018665870eSFrançois Tigeot 		obj = dma_buf_to_obj(dma_buf);
3028665870eSFrançois Tigeot 		/* is it from our device? */
3038665870eSFrançois Tigeot 		if (obj->base.dev == dev) {
3048665870eSFrançois Tigeot 			/*
3058665870eSFrançois Tigeot 			 * Importing dmabuf exported from out own gem increases
3068665870eSFrançois Tigeot 			 * refcount on gem itself instead of f_count of dmabuf.
3078665870eSFrançois Tigeot 			 */
30887df8fc6SFrançois Tigeot 			return &i915_gem_object_get(obj)->base;
3098665870eSFrançois Tigeot 		}
3108665870eSFrançois Tigeot 	}
3118665870eSFrançois Tigeot 
3128665870eSFrançois Tigeot 	/* need to attach */
3138665870eSFrançois Tigeot 	attach = dma_buf_attach(dma_buf, dev->dev);
3148665870eSFrançois Tigeot 	if (IS_ERR(attach))
3158665870eSFrançois Tigeot 		return ERR_CAST(attach);
3168665870eSFrançois Tigeot 
3178665870eSFrançois Tigeot #if 0
3188665870eSFrançois Tigeot 	get_dma_buf(dma_buf);
3198665870eSFrançois Tigeot #endif
3208665870eSFrançois Tigeot 
321a85cb24fSFrançois Tigeot 	obj = i915_gem_object_alloc(to_i915(dev));
3228665870eSFrançois Tigeot 	if (obj == NULL) {
3238665870eSFrançois Tigeot 		ret = -ENOMEM;
3248665870eSFrançois Tigeot 		goto fail_detach;
3258665870eSFrançois Tigeot 	}
3268665870eSFrançois Tigeot 
3278665870eSFrançois Tigeot 	drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
3288665870eSFrançois Tigeot 	i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops);
3298665870eSFrançois Tigeot 	obj->base.import_attach = attach;
3304be47400SFrançois Tigeot 	obj->resv = dma_buf->resv;
3318665870eSFrançois Tigeot 
33287df8fc6SFrançois Tigeot 	/* We use GTT as shorthand for a coherent domain, one that is
33387df8fc6SFrançois Tigeot 	 * neither in the GPU cache nor in the CPU cache, where all
33487df8fc6SFrançois Tigeot 	 * writes are immediately visible in memory. (That's not strictly
33587df8fc6SFrançois Tigeot 	 * true, but it's close! There are internal buffers such as the
33687df8fc6SFrançois Tigeot 	 * write-combined buffer or a delay through the chipset for GTT
33787df8fc6SFrançois Tigeot 	 * writes that do require us to treat GTT as a separate cache domain.)
33887df8fc6SFrançois Tigeot 	 */
33987df8fc6SFrançois Tigeot 	obj->base.read_domains = I915_GEM_DOMAIN_GTT;
34087df8fc6SFrançois Tigeot 	obj->base.write_domain = 0;
34187df8fc6SFrançois Tigeot 
3428665870eSFrançois Tigeot 	return &obj->base;
3438665870eSFrançois Tigeot 
3448665870eSFrançois Tigeot fail_detach:
3458665870eSFrançois Tigeot #if 0
3468665870eSFrançois Tigeot 	dma_buf_detach(dma_buf, attach);
3478665870eSFrançois Tigeot 	dma_buf_put(dma_buf);
3488665870eSFrançois Tigeot #endif
3498665870eSFrançois Tigeot 
3508665870eSFrançois Tigeot 	return ERR_PTR(ret);
3518665870eSFrançois Tigeot }
352a85cb24fSFrançois Tigeot 
353a85cb24fSFrançois Tigeot #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
354a85cb24fSFrançois Tigeot #include "selftests/mock_dmabuf.c"
355a85cb24fSFrançois Tigeot #include "selftests/i915_gem_dmabuf.c"
356a85cb24fSFrançois Tigeot #endif
357