diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index 3b5ca298c..0b6b59134 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -514,6 +514,13 @@ static int gk20a_ctrl_vsm_mapping(struct gk20a *g, return err; } +static int gk20a_ctrl_get_buffer_info( + struct gk20a *g, struct nvgpu_gpu_get_buffer_info_args *args) +{ + return gk20a_mm_get_buffer_info(dev_from_gk20a(g), args->in.dmabuf_fd, + &args->out.id, &args->out.length); +} + long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct platform_device *dev = filp->private_data; @@ -729,6 +736,10 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg (struct nvgpu_gpu_vsms_mapping *)buf); break; + case NVGPU_GPU_IOCTL_GET_BUFFER_INFO: + err = gk20a_ctrl_get_buffer_info(g, + (struct nvgpu_gpu_get_buffer_info_args *)buf); + break; default: dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 1bc355977..141a37afe 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -120,6 +120,8 @@ struct gk20a_dmabuf_priv { int pin_count; struct list_head states; + + u64 buffer_id; }; static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); @@ -3044,6 +3046,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) { struct gk20a_dmabuf_priv *priv; static DEFINE_MUTEX(priv_lock); + static u64 priv_count = 0; priv = dma_buf_get_drvdata(dmabuf, dev); if (likely(priv)) @@ -3060,6 +3063,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev) } mutex_init(&priv->lock); INIT_LIST_HEAD(&priv->states); + priv->buffer_id = ++priv_count; dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv); priv_exist_or_err: mutex_unlock(&priv_lock); @@ -3145,8 +3149,11 @@ int gk20a_vm_map_buffer(struct vm_gk20a *vm, /* get ref to the mem handle (released on unmap_locked) */ dmabuf = dma_buf_get(dmabuf_fd); - if (IS_ERR(dmabuf)) + if (IS_ERR(dmabuf)) { + dev_warn(dev_from_vm(vm), "%s: fd %d is not a dmabuf", + __func__, dmabuf_fd); return PTR_ERR(dmabuf); + } err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm)); if (err) { @@ -3653,6 +3660,37 @@ const struct gk20a_mmu_level *gk20a_mm_get_mmu_levels(struct gk20a *g, gk20a_mm_levels_64k : gk20a_mm_levels_128k; } +int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, + u64 *buffer_id, u64 *buffer_len) +{ + struct dma_buf *dmabuf; + struct gk20a_dmabuf_priv *priv; + int err = 0; + + dmabuf = dma_buf_get(dmabuf_fd); + if (IS_ERR(dmabuf)) { + dev_warn(dev, "%s: fd %d is not a dmabuf", __func__, dmabuf_fd); + return PTR_ERR(dmabuf); + } + + err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev); + if (err) { + dev_warn(dev, "Failed to allocate dmabuf drvdata (err = %d)", + err); + goto clean_up; + } + + priv = dma_buf_get_drvdata(dmabuf, dev); + if (likely(priv)) { + *buffer_id = priv->buffer_id; + *buffer_len = dmabuf->size; + } + +clean_up: + dma_buf_put(dmabuf); + return err; +} + void gk20a_init_mm(struct gpu_ops *gops) { gops->mm.is_debug_mode_enabled = gk20a_mm_mmu_debug_mode_enabled; diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 7bbaf2830..7be4383ba 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -688,4 +688,7 @@ static inline void nvgpu_free(void *p) vfree(p); } +int gk20a_mm_get_buffer_info(struct device *dev, int dmabuf_fd, + u64 *buffer_id, u64 *buffer_len); + #endif /* MM_GK20A_H */ diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 6024edeec..6a8e44c58 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -314,6 +314,22 @@ struct nvgpu_gpu_vsms_mapping { __u64 vsms_map_buf_addr; }; +struct nvgpu_gpu_get_buffer_info_args { + union { + struct { + __u32 dmabuf_fd; /* dma-buf fd */ + } in; + struct { + __u64 id; /* Unique within live + * buffers */ + __u64 length; /* Allocated length of the + * buffer */ + __u64 reserved0; + __u64 reserved1; + } out; + }; +}; + #define NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE \ _IOR(NVGPU_GPU_IOCTL_MAGIC, 1, struct nvgpu_gpu_zcull_get_ctx_size_args) #define NVGPU_GPU_IOCTL_ZCULL_GET_INFO \ @@ -352,9 +368,11 @@ struct nvgpu_gpu_vsms_mapping { _IOWR(NVGPU_GPU_IOCTL_MAGIC, 18, struct nvgpu_gpu_num_vsms) #define NVGPU_GPU_IOCTL_VSMS_MAPPING \ _IOWR(NVGPU_GPU_IOCTL_MAGIC, 19, struct nvgpu_gpu_vsms_mapping) +#define NVGPU_GPU_IOCTL_GET_BUFFER_INFO \ + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 20, struct nvgpu_gpu_get_buffer_info_args) #define NVGPU_GPU_IOCTL_LAST \ - _IOC_NR(NVGPU_GPU_IOCTL_VSMS_MAPPING) + _IOC_NR(NVGPU_GPU_IOCTL_GET_BUFFER_INFO) #define NVGPU_GPU_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_gpu_prepare_compressible_read_args)