drm/i915: Add some mock tests for dmabuf interop
Check that we can create both dmabuf and objects from dmabuf. v2: Cleanups, correct include, fix unpin on dead path and prevent explosion on dmabuf init failure Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170213171558.20942-25-chris@chris-wilson.co.uk
This commit is contained in:
parent
a8fb2bad82
commit
6cca22ede8
|
@ -307,3 +307,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
|
||||||
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
|
||||||
|
#include "selftests/mock_dmabuf.c"
|
||||||
|
#include "selftests/i915_gem_dmabuf.c"
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../i915_selftest.h"
|
||||||
|
|
||||||
|
#include "mock_gem_device.h"
|
||||||
|
#include "mock_dmabuf.h"
|
||||||
|
|
||||||
|
static int igt_dmabuf_export(void *arg)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = arg;
|
||||||
|
struct drm_i915_gem_object *obj;
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
|
||||||
|
obj = i915_gem_object_create(i915, PAGE_SIZE);
|
||||||
|
if (IS_ERR(obj))
|
||||||
|
return PTR_ERR(obj);
|
||||||
|
|
||||||
|
dmabuf = i915_gem_prime_export(&i915->drm, &obj->base, 0);
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
if (IS_ERR(dmabuf)) {
|
||||||
|
pr_err("i915_gem_prime_export failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(dmabuf));
|
||||||
|
return PTR_ERR(dmabuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_dmabuf_import_self(void *arg)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = arg;
|
||||||
|
struct drm_i915_gem_object *obj;
|
||||||
|
struct drm_gem_object *import;
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
obj = i915_gem_object_create(i915, PAGE_SIZE);
|
||||||
|
if (IS_ERR(obj))
|
||||||
|
return PTR_ERR(obj);
|
||||||
|
|
||||||
|
dmabuf = i915_gem_prime_export(&i915->drm, &obj->base, 0);
|
||||||
|
if (IS_ERR(dmabuf)) {
|
||||||
|
pr_err("i915_gem_prime_export failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(dmabuf));
|
||||||
|
err = PTR_ERR(dmabuf);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
import = i915_gem_prime_import(&i915->drm, dmabuf);
|
||||||
|
if (IS_ERR(import)) {
|
||||||
|
pr_err("i915_gem_prime_import failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(import));
|
||||||
|
err = PTR_ERR(import);
|
||||||
|
goto out_dmabuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import != &obj->base) {
|
||||||
|
pr_err("i915_gem_prime_import created a new object!\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out_import;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
out_import:
|
||||||
|
i915_gem_object_put(to_intel_bo(import));
|
||||||
|
out_dmabuf:
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
out:
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_dmabuf_import(void *arg)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = arg;
|
||||||
|
struct drm_i915_gem_object *obj;
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
void *obj_map, *dma_map;
|
||||||
|
u32 pattern[] = { 0, 0xaa, 0xcc, 0x55, 0xff };
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
dmabuf = mock_dmabuf(1);
|
||||||
|
if (IS_ERR(dmabuf))
|
||||||
|
return PTR_ERR(dmabuf);
|
||||||
|
|
||||||
|
obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
|
||||||
|
if (IS_ERR(obj)) {
|
||||||
|
pr_err("i915_gem_prime_import failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(obj));
|
||||||
|
err = PTR_ERR(obj);
|
||||||
|
goto out_dmabuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->base.dev != &i915->drm) {
|
||||||
|
pr_err("i915_gem_prime_import created a non-i915 object!\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->base.size != PAGE_SIZE) {
|
||||||
|
pr_err("i915_gem_prime_import is wrong size found %lld, expected %ld\n",
|
||||||
|
(long long)obj->base.size, PAGE_SIZE);
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_map = dma_buf_vmap(dmabuf);
|
||||||
|
if (!dma_map) {
|
||||||
|
pr_err("dma_buf_vmap failed\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0) { /* Can not yet map dmabuf */
|
||||||
|
obj_map = i915_gem_object_pin_map(obj, I915_MAP_WB);
|
||||||
|
if (IS_ERR(obj_map)) {
|
||||||
|
err = PTR_ERR(obj_map);
|
||||||
|
pr_err("i915_gem_object_pin_map failed with err=%d\n", err);
|
||||||
|
goto out_dma_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(pattern); i++) {
|
||||||
|
memset(dma_map, pattern[i], PAGE_SIZE);
|
||||||
|
if (memchr_inv(obj_map, pattern[i], PAGE_SIZE)) {
|
||||||
|
err = -EINVAL;
|
||||||
|
pr_err("imported vmap not all set to %x!\n", pattern[i]);
|
||||||
|
i915_gem_object_unpin_map(obj);
|
||||||
|
goto out_dma_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(pattern); i++) {
|
||||||
|
memset(obj_map, pattern[i], PAGE_SIZE);
|
||||||
|
if (memchr_inv(dma_map, pattern[i], PAGE_SIZE)) {
|
||||||
|
err = -EINVAL;
|
||||||
|
pr_err("exported vmap not all set to %x!\n", pattern[i]);
|
||||||
|
i915_gem_object_unpin_map(obj);
|
||||||
|
goto out_dma_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i915_gem_object_unpin_map(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
out_dma_map:
|
||||||
|
dma_buf_vunmap(dmabuf, dma_map);
|
||||||
|
out_obj:
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
out_dmabuf:
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_dmabuf_import_ownership(void *arg)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = arg;
|
||||||
|
struct drm_i915_gem_object *obj;
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
void *ptr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
dmabuf = mock_dmabuf(1);
|
||||||
|
if (IS_ERR(dmabuf))
|
||||||
|
return PTR_ERR(dmabuf);
|
||||||
|
|
||||||
|
ptr = dma_buf_vmap(dmabuf);
|
||||||
|
if (!ptr) {
|
||||||
|
pr_err("dma_buf_vmap failed\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_dmabuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ptr, 0xc5, PAGE_SIZE);
|
||||||
|
dma_buf_vunmap(dmabuf, ptr);
|
||||||
|
|
||||||
|
obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
|
||||||
|
if (IS_ERR(obj)) {
|
||||||
|
pr_err("i915_gem_prime_import failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(obj));
|
||||||
|
err = PTR_ERR(obj);
|
||||||
|
goto err_dmabuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
|
||||||
|
err = i915_gem_object_pin_pages(obj);
|
||||||
|
if (err) {
|
||||||
|
pr_err("i915_gem_object_pin_pages failed with err=%d\n", err);
|
||||||
|
goto out_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
i915_gem_object_unpin_pages(obj);
|
||||||
|
out_obj:
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err_dmabuf:
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_dmabuf_export_vmap(void *arg)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *i915 = arg;
|
||||||
|
struct drm_i915_gem_object *obj;
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
void *ptr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
obj = i915_gem_object_create(i915, PAGE_SIZE);
|
||||||
|
if (IS_ERR(obj))
|
||||||
|
return PTR_ERR(obj);
|
||||||
|
|
||||||
|
dmabuf = i915_gem_prime_export(&i915->drm, &obj->base, 0);
|
||||||
|
if (IS_ERR(dmabuf)) {
|
||||||
|
pr_err("i915_gem_prime_export failed with err=%d\n",
|
||||||
|
(int)PTR_ERR(dmabuf));
|
||||||
|
err = PTR_ERR(dmabuf);
|
||||||
|
goto err_obj;
|
||||||
|
}
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
|
||||||
|
ptr = dma_buf_vmap(dmabuf);
|
||||||
|
if (IS_ERR(ptr)) {
|
||||||
|
err = PTR_ERR(ptr);
|
||||||
|
pr_err("dma_buf_vmap failed with err=%d\n", err);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memchr_inv(ptr, 0, dmabuf->size)) {
|
||||||
|
pr_err("Exported object not initialiased to zero!\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ptr, 0xc5, dmabuf->size);
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
dma_buf_vunmap(dmabuf, ptr);
|
||||||
|
out:
|
||||||
|
dma_buf_put(dmabuf);
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err_obj:
|
||||||
|
i915_gem_object_put(obj);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i915_gem_dmabuf_mock_selftests(void)
|
||||||
|
{
|
||||||
|
static const struct i915_subtest tests[] = {
|
||||||
|
SUBTEST(igt_dmabuf_export),
|
||||||
|
SUBTEST(igt_dmabuf_import_self),
|
||||||
|
SUBTEST(igt_dmabuf_import),
|
||||||
|
SUBTEST(igt_dmabuf_import_ownership),
|
||||||
|
SUBTEST(igt_dmabuf_export_vmap),
|
||||||
|
};
|
||||||
|
struct drm_i915_private *i915;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
i915 = mock_gem_device();
|
||||||
|
if (!i915)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
err = i915_subtests(tests, i915);
|
||||||
|
|
||||||
|
drm_dev_unref(&i915->drm);
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -14,3 +14,4 @@ selftest(uncore, intel_uncore_mock_selftests)
|
||||||
selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
|
selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
|
||||||
selftest(requests, i915_gem_request_mock_selftests)
|
selftest(requests, i915_gem_request_mock_selftests)
|
||||||
selftest(objects, i915_gem_object_mock_selftests)
|
selftest(objects, i915_gem_object_mock_selftests)
|
||||||
|
selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mock_dmabuf.h"
|
||||||
|
|
||||||
|
static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
|
||||||
|
enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(attachment->dmabuf);
|
||||||
|
struct sg_table *st;
|
||||||
|
struct scatterlist *sg;
|
||||||
|
int i, err;
|
||||||
|
|
||||||
|
st = kmalloc(sizeof(*st), GFP_KERNEL);
|
||||||
|
if (!st)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
err = sg_alloc_table(st, mock->npages, GFP_KERNEL);
|
||||||
|
if (err)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
sg = st->sgl;
|
||||||
|
for (i = 0; i < mock->npages; i++) {
|
||||||
|
sg_set_page(sg, mock->pages[i], PAGE_SIZE, 0);
|
||||||
|
sg = sg_next(sg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_st;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st;
|
||||||
|
|
||||||
|
err_st:
|
||||||
|
sg_free_table(st);
|
||||||
|
err_free:
|
||||||
|
kfree(st);
|
||||||
|
return ERR_PTR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
|
||||||
|
struct sg_table *st,
|
||||||
|
enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
|
||||||
|
sg_free_table(st);
|
||||||
|
kfree(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_dmabuf_release(struct dma_buf *dma_buf)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mock->npages; i++)
|
||||||
|
put_page(mock->pages[i]);
|
||||||
|
|
||||||
|
kfree(mock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *mock_dmabuf_vmap(struct dma_buf *dma_buf)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
|
||||||
|
return vm_map_ram(mock->pages, mock->npages, 0, PAGE_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
|
||||||
|
vm_unmap_ram(vaddr, mock->npages);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *mock_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
|
||||||
|
return kmap_atomic(mock->pages[page_num]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
|
||||||
|
{
|
||||||
|
kunmap_atomic(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *mock_dmabuf_kmap(struct dma_buf *dma_buf, unsigned long page_num)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
|
||||||
|
return kmap(mock->pages[page_num]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mock_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock = to_mock(dma_buf);
|
||||||
|
|
||||||
|
return kunmap(mock->pages[page_num]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dma_buf_ops mock_dmabuf_ops = {
|
||||||
|
.map_dma_buf = mock_map_dma_buf,
|
||||||
|
.unmap_dma_buf = mock_unmap_dma_buf,
|
||||||
|
.release = mock_dmabuf_release,
|
||||||
|
.kmap = mock_dmabuf_kmap,
|
||||||
|
.kmap_atomic = mock_dmabuf_kmap_atomic,
|
||||||
|
.kunmap = mock_dmabuf_kunmap,
|
||||||
|
.kunmap_atomic = mock_dmabuf_kunmap_atomic,
|
||||||
|
.mmap = mock_dmabuf_mmap,
|
||||||
|
.vmap = mock_dmabuf_vmap,
|
||||||
|
.vunmap = mock_dmabuf_vunmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dma_buf *mock_dmabuf(int npages)
|
||||||
|
{
|
||||||
|
struct mock_dmabuf *mock;
|
||||||
|
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||||
|
struct dma_buf *dmabuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mock = kmalloc(sizeof(*mock) + npages * sizeof(struct page *),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!mock)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
mock->npages = npages;
|
||||||
|
for (i = 0; i < npages; i++) {
|
||||||
|
mock->pages[i] = alloc_page(GFP_KERNEL);
|
||||||
|
if (!mock->pages[i])
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
exp_info.ops = &mock_dmabuf_ops;
|
||||||
|
exp_info.size = npages * PAGE_SIZE;
|
||||||
|
exp_info.flags = O_CLOEXEC;
|
||||||
|
exp_info.priv = mock;
|
||||||
|
|
||||||
|
dmabuf = dma_buf_export(&exp_info);
|
||||||
|
if (IS_ERR(dmabuf))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return dmabuf;
|
||||||
|
|
||||||
|
err:
|
||||||
|
while (i--)
|
||||||
|
put_page(mock->pages[i]);
|
||||||
|
kfree(mock);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MOCK_DMABUF_H__
|
||||||
|
#define __MOCK_DMABUF_H__
|
||||||
|
|
||||||
|
#include <linux/dma-buf.h>
|
||||||
|
|
||||||
|
struct mock_dmabuf {
|
||||||
|
int npages;
|
||||||
|
struct page *pages[];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mock_dmabuf *to_mock(struct dma_buf *buf)
|
||||||
|
{
|
||||||
|
return buf->priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !__MOCK_DMABUF_H__ */
|
Loading…
Reference in New Issue