Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdkfd: add H/W debugger IOCTL set definitions

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>

authored by

Yair Shachar and committed by
Oded Gabbay
aef11009 a6186f4d

+95 -2
+54
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 432 432 return err; 433 433 } 434 434 435 + static int kfd_ioctl_dbg_register(struct file *filep, 436 + struct kfd_process *p, void *data) 437 + { 438 + long status = -EFAULT; 439 + 440 + return status; 441 + } 442 + 443 + static int kfd_ioctl_dbg_unrgesiter(struct file *filep, 444 + struct kfd_process *p, void *data) 445 + { 446 + long status = -EFAULT; 447 + 448 + return status; 449 + } 450 + 451 + /* 452 + * Parse and generate variable size data structure for address watch. 453 + * Total size of the buffer and # watch points is limited in order 454 + * to prevent kernel abuse. (no bearing to the much smaller HW limitation 455 + * which is enforced by dbgdev module) 456 + * please also note that the watch address itself are not "copied from user", 457 + * since it be set into the HW in user mode values. 458 + * 459 + */ 460 + static int kfd_ioctl_dbg_address_watch(struct file *filep, 461 + struct kfd_process *p, void *data) 462 + { 463 + long status = -EFAULT; 464 + 465 + return status; 466 + } 467 + 468 + /* Parse and generate fixed size data structure for wave control */ 469 + static int kfd_ioctl_dbg_wave_control(struct file *filep, 470 + struct kfd_process *p, void *data) 471 + { 472 + long status = -EFAULT; 473 + 474 + return status; 475 + } 476 + 435 477 static int kfd_ioctl_get_clock_counters(struct file *filep, 436 478 struct kfd_process *p, void *data) 437 479 { ··· 654 612 655 613 AMDKFD_IOCTL_DEF(AMDKFD_IOC_WAIT_EVENTS, 656 614 kfd_ioctl_wait_events, 0), 615 + 616 + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_REGISTER, 617 + kfd_ioctl_dbg_register, 0), 618 + 619 + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_UNREGISTER, 620 + kfd_ioctl_dbg_unrgesiter, 0), 621 + 622 + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_ADDRESS_WATCH, 623 + kfd_ioctl_dbg_address_watch, 0), 624 + 625 + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL, 626 + kfd_ioctl_dbg_wave_control, 0), 657 627 }; 658 628 659 629 #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
+41 -2
include/uapi/linux/kfd_ioctl.h
··· 128 128 uint32_t pad; 129 129 }; 130 130 131 + #define MAX_ALLOWED_NUM_POINTS 100 132 + #define MAX_ALLOWED_AW_BUFF_SIZE 4096 133 + #define MAX_ALLOWED_WAC_BUFF_SIZE 128 134 + 135 + struct kfd_ioctl_dbg_register_args { 136 + uint32_t gpu_id; /* to KFD */ 137 + uint32_t pad; 138 + }; 139 + 140 + struct kfd_ioctl_dbg_unregister_args { 141 + uint32_t gpu_id; /* to KFD */ 142 + uint32_t pad; 143 + }; 144 + 145 + struct kfd_ioctl_dbg_address_watch_args { 146 + uint64_t content_ptr; /* a pointer to the actual content */ 147 + uint32_t gpu_id; /* to KFD */ 148 + uint32_t buf_size_in_bytes; /*including gpu_id and buf_size */ 149 + }; 150 + 151 + struct kfd_ioctl_dbg_wave_control_args { 152 + uint64_t content_ptr; /* a pointer to the actual content */ 153 + uint32_t gpu_id; /* to KFD */ 154 + uint32_t buf_size_in_bytes; /*including gpu_id and buf_size */ 155 + }; 156 + 131 157 /* Matching HSA_EVENTTYPE */ 132 158 #define KFD_IOC_EVENT_SIGNAL 0 133 159 #define KFD_IOC_EVENT_NODECHANGE 1 ··· 224 198 }; 225 199 226 200 struct kfd_ioctl_wait_events_args { 227 - uint64_t events_ptr; /* to KFD */ 201 + uint64_t events_ptr; /* pointed to struct 202 + kfd_event_data array, to KFD */ 228 203 uint32_t num_events; /* to KFD */ 229 204 uint32_t wait_for_all; /* to KFD */ 230 205 uint32_t timeout; /* to KFD */ ··· 274 247 #define AMDKFD_IOC_WAIT_EVENTS \ 275 248 AMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args) 276 249 250 + #define AMDKFD_IOC_DBG_REGISTER \ 251 + AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args) 252 + 253 + #define AMDKFD_IOC_DBG_UNREGISTER \ 254 + AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args) 255 + 256 + #define AMDKFD_IOC_DBG_ADDRESS_WATCH \ 257 + AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args) 258 + 259 + #define AMDKFD_IOC_DBG_WAVE_CONTROL \ 260 + AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args) 261 + 277 262 #define AMDKFD_COMMAND_START 0x01 278 - #define AMDKFD_COMMAND_END 0x0D 263 + #define AMDKFD_COMMAND_END 0x11 279 264 280 265 #endif