drm/amdkfd: add H/W debugger IOCTL set definitions
authorYair Shachar <yair.shachar@amd.com>
Sun, 7 Dec 2014 15:05:22 +0000 (17:05 +0200)
committerOded Gabbay <oded.gabbay@gmail.com>
Wed, 3 Jun 2015 08:32:07 +0000 (11:32 +0300)
This patch adds four new IOCTLs to amdkfd. These IOCTLs expose a H/W
debugger functionality to the userspace.

The IOCTLs are:

- AMDKFD_IOC_DBG_REGISTER:

The purpose of this IOCTL is to notify amdkfd that a process wants to use
GPU debugging facilities on itself only.
It is expected that this IOCTL would be called before any other H/W
debugger requests are sent to amdkfd and for each GPU where the H/W
debugging needs to be enabled. The use of this IOCTL ensures that only
one instance of a debugger is active in the system.

- AMDKFD_IOC_DBG_UNREGISTER:

This IOCTL detaches the debugger/debugged process from the H/W
Debug which was established by the AMDKFD_IOC_DBG_REGISTER IOCTL.

- AMDKFD_IOC_DBG_ADDRESS_WATCH:

This IOCTL allows to set different watchpoints with various conditions as
indicated by the IOCTL's arguments. The available number of watchpoints
is retrieved from topology. This operation is confined to the current
debugged process, which was registered through AMDKFD_IOC_DBG_REGISTER.

- AMDKFD_IOC_DBG_WAVE_CONTROL:

This IOCTL allows to control a wavefront as indicated by the IOCTL's
arguments. For example, you can halt/resume or kill either a
single wavefront or a set of wavefronts. This operation is confined to
the current debugged process, which was registered through
AMDKFD_IOC_DBG_REGISTER.

Because the arguments for the address watch IOCTL and wave control IOCTL
are dynamic, meaning that they could vary in size, the userspace passes a
pointer to a structure (in userspace) that contains the value of the
arguments. The kernel driver is responsible to parse this structure and
validate its contents.

v2: change void* to uint64_t inside ioctl arguments

Signed-off-by: Yair Shachar <yair.shachar@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
include/uapi/linux/kfd_ioctl.h

index b2c6109bd7af12fcff5d5ebaa27e8a23f1dc1827..b358e910378fc099682b470d37991625de44f7b7 100644 (file)
@@ -432,6 +432,48 @@ out:
        return err;
 }
 
+static int kfd_ioctl_dbg_register(struct file *filep,
+                               struct kfd_process *p, void *data)
+{
+       long status = -EFAULT;
+
+       return status;
+}
+
+static int kfd_ioctl_dbg_unrgesiter(struct file *filep,
+                               struct kfd_process *p, void *data)
+{
+       long status = -EFAULT;
+
+       return status;
+}
+
+/*
+ * Parse and generate variable size data structure for address watch.
+ * Total size of the buffer and # watch points is limited in order
+ * to prevent kernel abuse. (no bearing to the much smaller HW limitation
+ * which is enforced by dbgdev module)
+ * please also note that the watch address itself are not "copied from user",
+ * since it be set into the HW in user mode values.
+ *
+ */
+static int kfd_ioctl_dbg_address_watch(struct file *filep,
+                                       struct kfd_process *p, void *data)
+{
+       long status = -EFAULT;
+
+       return status;
+}
+
+/* Parse and generate fixed size data structure for wave control */
+static int kfd_ioctl_dbg_wave_control(struct file *filep,
+                                       struct kfd_process *p, void *data)
+{
+       long status = -EFAULT;
+
+       return status;
+}
+
 static int kfd_ioctl_get_clock_counters(struct file *filep,
                                struct kfd_process *p, void *data)
 {
@@ -612,6 +654,18 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
 
        AMDKFD_IOCTL_DEF(AMDKFD_IOC_WAIT_EVENTS,
                        kfd_ioctl_wait_events, 0),
+
+       AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_REGISTER,
+                       kfd_ioctl_dbg_register, 0),
+
+       AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_UNREGISTER,
+                       kfd_ioctl_dbg_unrgesiter, 0),
+
+       AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_ADDRESS_WATCH,
+                       kfd_ioctl_dbg_address_watch, 0),
+
+       AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL,
+                       kfd_ioctl_dbg_wave_control, 0),
 };
 
 #define AMDKFD_CORE_IOCTL_COUNT        ARRAY_SIZE(amdkfd_ioctls)
index 4ca35a8f9891dae2638207c13903c0f9b55bfa61..d6833426fdef15479a0c2f3fe6145a6d5b8b2e15 100644 (file)
@@ -128,6 +128,32 @@ struct kfd_ioctl_get_process_apertures_args {
        uint32_t pad;
 };
 
+#define MAX_ALLOWED_NUM_POINTS    100
+#define MAX_ALLOWED_AW_BUFF_SIZE 4096
+#define MAX_ALLOWED_WAC_BUFF_SIZE  128
+
+struct kfd_ioctl_dbg_register_args {
+       uint32_t gpu_id;                /* to KFD */
+       uint32_t pad;
+};
+
+struct kfd_ioctl_dbg_unregister_args {
+       uint32_t gpu_id;                /* to KFD */
+       uint32_t pad;
+};
+
+struct kfd_ioctl_dbg_address_watch_args {
+       uint64_t content_ptr;           /* a pointer to the actual content */
+       uint32_t gpu_id;                /* to KFD */
+       uint32_t buf_size_in_bytes;     /*including gpu_id and buf_size */
+};
+
+struct kfd_ioctl_dbg_wave_control_args {
+       uint64_t content_ptr;           /* a pointer to the actual content */
+       uint32_t gpu_id;                /* to KFD */
+       uint32_t buf_size_in_bytes;     /*including gpu_id and buf_size */
+};
+
 /* Matching HSA_EVENTTYPE */
 #define KFD_IOC_EVENT_SIGNAL                   0
 #define KFD_IOC_EVENT_NODECHANGE               1
@@ -198,7 +224,8 @@ struct kfd_event_data {
 };
 
 struct kfd_ioctl_wait_events_args {
-       uint64_t events_ptr;            /* to KFD */
+       uint64_t events_ptr;            /* pointed to struct
+                                          kfd_event_data array, to KFD */
        uint32_t num_events;            /* to KFD */
        uint32_t wait_for_all;          /* to KFD */
        uint32_t timeout;               /* to KFD */
@@ -247,7 +274,19 @@ struct kfd_ioctl_wait_events_args {
 #define AMDKFD_IOC_WAIT_EVENTS                 \
                AMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args)
 
+#define AMDKFD_IOC_DBG_REGISTER                        \
+               AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args)
+
+#define AMDKFD_IOC_DBG_UNREGISTER              \
+               AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)
+
+#define AMDKFD_IOC_DBG_ADDRESS_WATCH           \
+               AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)
+
+#define AMDKFD_IOC_DBG_WAVE_CONTROL            \
+               AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
+
 #define AMDKFD_COMMAND_START           0x01
-#define AMDKFD_COMMAND_END             0x0D
+#define AMDKFD_COMMAND_END             0x11
 
 #endif