From: Yair Shachar <yair.shac...@amd.com>

Signed-off-by: Yair Shachar <yair.shachar at amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay at gmail.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 88 +++++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 5b9776d..6288084 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -537,7 +537,93 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
 static int kfd_ioctl_dbg_wave_control(struct file *filep,
                                        struct kfd_process *p, void *data)
 {
-       long status = -EFAULT;
+       struct kfd_ioctl_dbg_wave_control_args *args = data;
+       struct kfd_dev *dev;
+       struct dbg_wave_control_info wac_info;
+       unsigned char *args_buff;
+       uint32_t computed_buff_size;
+       long status;
+       unsigned int args_idx = 0;
+
+       memset((void *) &wac_info, 0, sizeof(struct dbg_wave_control_info));
+
+       /* we use compact form, independent of the packing attribute value */
+       computed_buff_size = sizeof(*args) +
+                               sizeof(wac_info.mode) +
+                               sizeof(wac_info.operand) +
+                               sizeof(wac_info.dbgWave_msg.DbgWaveMsg) +
+                               sizeof(wac_info.dbgWave_msg.MemoryVA) +
+                               sizeof(wac_info.trapId);
+
+       dev = kfd_device_by_id(args->gpu_id);
+       if (dev == NULL)
+               return -EINVAL;
+
+       if (dev->device_info->asic_family == CHIP_CARRIZO) {
+               pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n");
+               return -EINVAL;
+       }
+
+       /* input size must match the computed "compact" size */
+       if (args->buf_size_in_bytes != computed_buff_size) {
+               pr_debug("size mismatch, computed : actual %u : %u\n",
+                               args->buf_size_in_bytes, computed_buff_size);
+               return -EINVAL;
+       }
+
+       /* this is the actual buffer to work with */
+
+       args_buff = kzalloc(args->buf_size_in_bytes - sizeof(*args),
+                       GFP_KERNEL);
+
+       if (args_buff == NULL)
+               return -ENOMEM;
+
+       if (args->content_ptr == NULL) {
+               kfree(args_buff);
+               return -EINVAL;
+       }
+
+       /* Now copy the entire buffer from user */
+       status = copy_from_user(args_buff,
+                               (void __user *) args->content_ptr,
+                               args->buf_size_in_bytes - sizeof(*args));
+       if (status != 0) {
+               pr_debug("Failed to copy wave control user data\n");
+               kfree(args_buff);
+               return -EINVAL;
+       }
+
+       /* move ptr to the start of the "pay-load" area */
+       wac_info.process = p;
+
+       wac_info.operand = *((enum HSA_DBG_WAVEOP *)(&args_buff[args_idx]));
+       args_idx += sizeof(wac_info.operand);
+
+       wac_info.mode = *((enum HSA_DBG_WAVEMODE *)(&args_buff[args_idx]));
+       args_idx += sizeof(wac_info.mode);
+
+       wac_info.trapId = *((uint32_t *)(&args_buff[args_idx]));
+       args_idx += sizeof(wac_info.trapId);
+
+       wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value =
+                                       *((uint32_t *)(&args_buff[args_idx]));
+       wac_info.dbgWave_msg.MemoryVA = NULL;
+
+       mutex_lock(get_dbgmgr_mutex());
+
+       pr_debug("Calling dbg manager process %p, operand %u, mode %u, trapId 
%u, message %u\n",
+                       wac_info.process, wac_info.operand,
+                       wac_info.mode, wac_info.trapId,
+                       wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value);
+
+       status = kfd_dbgmgr_wave_control(dev->dbgmgr, &wac_info);
+
+       pr_debug("Returned status of dbg manager is %ld\n", status);
+
+       mutex_unlock(get_dbgmgr_mutex());
+
+       kfree(args_buff);

        return status;
 }
-- 
2.1.0

Reply via email to