We need dmabuf specific pread() callback utilizing dma-buf API, otherwise GEM_PREAD IOCTL will no longer work with dma-buf backed (i.e., PRIME imported) objects on hardware with no mappable aperture. Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@xxxxxxxxxxxxxxx> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx> Cc: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx> --- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 55 ++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 93eea1031c82..207dbf044296 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -248,6 +248,60 @@ static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj, DMA_BIDIRECTIONAL); } +static int i915_gem_object_pread_dmabuf(struct drm_i915_gem_object *obj, + const struct drm_i915_gem_pread *args) +{ + struct dma_buf *dmabuf = obj->base.import_attach->dmabuf; + void __user *user_data = u64_to_user_ptr(args->data_ptr); + struct file *file = dmabuf->file; + const struct file_operations *fop = file->f_op; + void __force *vaddr; + int ret; + + if (fop->read) { + loff_t offset = args->offset; + + /* + * fop->read() is supposed to call dma_buf_begin_cpu_access() + * if O_SYNC flag is set, avoid calling it twice + */ + if (!(file->f_flags & O_SYNC)) { + ret = dma_buf_begin_cpu_access(dmabuf, DMA_FROM_DEVICE); + if (ret) + return ret; + } + + ret = fop->read(file, user_data, args->size, &offset); + + if (!(file->f_flags & O_SYNC)) + dma_buf_end_cpu_access(dmabuf, DMA_FROM_DEVICE); + + if (!ret) + return 0; + } + + /* dma-buf file .read() not supported or failed, try dma_buf_vmap() */ + ret = dma_buf_begin_cpu_access(dmabuf, DMA_FROM_DEVICE); + if (ret) + return ret; + + vaddr = dma_buf_vmap(dmabuf); + if (!vaddr) + goto out_err; + + ret = copy_to_user(user_data, vaddr + args->offset, args->size); + dma_buf_vunmap(dmabuf, vaddr); + if (!ret) + goto out_end; + +out_err: + /* fall back to GTT mapping */ + ret = -ENODEV; +out_end: + dma_buf_end_cpu_access(dmabuf, DMA_FROM_DEVICE); + return ret; +} + static int i915_gem_object_pwrite_dmabuf(struct drm_i915_gem_object *obj, const struct drm_i915_gem_pwrite *args) { @@ -305,6 +359,7 @@ static int i915_gem_object_pwrite_dmabuf(struct drm_i915_gem_object *obj, static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = { .get_pages = i915_gem_object_get_pages_dmabuf, .put_pages = i915_gem_object_put_pages_dmabuf, + .pread = i915_gem_object_pread_dmabuf, .pwrite = i915_gem_object_pwrite_dmabuf, }; -- 2.21.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx