summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index d15386d7..1a219d2e 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -21,6 +21,7 @@
21#include <linux/cdev.h> 21#include <linux/cdev.h>
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <linux/nvhost.h> 23#include <linux/nvhost.h>
24#include <linux/dma-buf.h>
24#include <uapi/linux/nvgpu.h> 25#include <uapi/linux/nvgpu.h>
25 26
26#include "gk20a.h" 27#include "gk20a.h"
@@ -789,6 +790,84 @@ nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(struct dbg_session_gk20a *dbg_s,
789 return err; 790 return err;
790} 791}
791 792
793static int nvgpu_dbg_gpu_ioctl_access_fb_memory(struct dbg_session_gk20a *dbg_s,
794 struct nvgpu_dbg_gpu_access_fb_memory_args *args)
795{
796 struct gk20a *g = dbg_s->g;
797 struct dma_buf *dmabuf;
798 void __user *user_buffer = (void __user *)(uintptr_t)args->buffer;
799 void *buffer;
800 u64 size, access_size, offset;
801 u64 access_limit_size = SZ_4K;
802 int err = 0;
803
804 if ((args->offset & 3) || (!args->size) || (args->size & 3))
805 return -EINVAL;
806
807 dmabuf = dma_buf_get(args->dmabuf_fd);
808 if (IS_ERR(dmabuf))
809 return -EINVAL;
810
811 if ((args->offset > dmabuf->size) ||
812 (args->size > dmabuf->size) ||
813 (args->offset + args->size > dmabuf->size)) {
814 err = -EINVAL;
815 goto fail_dmabuf_put;
816 }
817
818 buffer = nvgpu_alloc(access_limit_size, true);
819 if (!buffer) {
820 err = -ENOMEM;
821 goto fail_dmabuf_put;
822 }
823
824 size = args->size;
825 offset = 0;
826
827 err = gk20a_busy(g->dev);
828 if (err)
829 goto fail_free_buffer;
830
831 while (size) {
832 /* Max access size of access_limit_size in one loop */
833 access_size = min(access_limit_size, size);
834
835 if (args->cmd ==
836 NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_WRITE) {
837 err = copy_from_user(buffer, user_buffer + offset,
838 access_size);
839 if (err)
840 goto fail_idle;
841 }
842
843 err = gk20a_vidbuf_access_memory(g, dmabuf, buffer,
844 args->offset + offset, access_size,
845 args->cmd);
846 if (err)
847 goto fail_idle;
848
849 if (args->cmd ==
850 NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_READ) {
851 err = copy_to_user(user_buffer + offset,
852 buffer, access_size);
853 if (err)
854 goto fail_idle;
855 }
856
857 size -= access_size;
858 offset += access_size;
859 }
860
861fail_idle:
862 gk20a_idle(g->dev);
863fail_free_buffer:
864 nvgpu_free(buffer);
865fail_dmabuf_put:
866 dma_buf_put(dmabuf);
867
868 return err;
869}
870
792long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, 871long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
793 unsigned long arg) 872 unsigned long arg)
794{ 873{
@@ -911,6 +990,11 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
911 (struct nvgpu_dbg_gpu_suspend_resume_contexts_args *)buf); 990 (struct nvgpu_dbg_gpu_suspend_resume_contexts_args *)buf);
912 break; 991 break;
913 992
993 case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY:
994 err = nvgpu_dbg_gpu_ioctl_access_fb_memory(dbg_s,
995 (struct nvgpu_dbg_gpu_access_fb_memory_args *)buf);
996 break;
997
914 default: 998 default:
915 gk20a_err(dev_from_gk20a(g), 999 gk20a_err(dev_from_gk20a(g),
916 "unrecognized dbg gpu ioctl cmd: 0x%x", 1000 "unrecognized dbg gpu ioctl cmd: 0x%x",