Commit c2d2588c authored by Jonathan Kim's avatar Jonathan Kim Committed by Alex Deucher
Browse files

drm/amdkfd: add send exception operation



Add a debug operation that allows the debugger to send an exception
directly to runtime through a payload address.

For memory violations, normal vmfault signals will be applied to
notify runtime instead after passing in the saved exception data
when a memory violation was raised to the debugger.

For runtime exceptions, this will unblock the runtime enable
function which will be explained and implemented in a follow up
patch.

Signed-off-by: default avatarJonathan Kim <jonathan.kim@amd.com>
Reviewed-by: default avatarFelix Kuehling <felix.kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 44b87bb0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -118,9 +118,9 @@ static void cik_event_interrupt_wq(struct kfd_node *dev,
			return;

		if (info.vmid == vmid)
			kfd_signal_vm_fault_event(dev, pasid, &info);
			kfd_signal_vm_fault_event(dev, pasid, &info, NULL);
		else
			kfd_signal_vm_fault_event(dev, pasid, NULL);
			kfd_signal_vm_fault_event(dev, pasid, NULL, NULL);
	}
}

+5 −0
Original line number Diff line number Diff line
@@ -2833,6 +2833,11 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
		r = kfd_dbg_trap_disable(target);
		break;
	case KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT:
		r = kfd_dbg_send_exception_to_runtime(target,
				args->send_runtime_event.gpu_id,
				args->send_runtime_event.queue_id,
				args->send_runtime_event.exception_mask);
		break;
	case KFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED:
	case KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE:
	case KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE:
+43 −0
Original line number Diff line number Diff line
@@ -125,6 +125,49 @@ bool kfd_dbg_ev_raise(uint64_t event_mask,
	return is_subscribed;
}

int kfd_dbg_send_exception_to_runtime(struct kfd_process *p,
					unsigned int dev_id,
					unsigned int queue_id,
					uint64_t error_reason)
{
	if (error_reason & KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION)) {
		struct kfd_process_device *pdd = NULL;
		struct kfd_hsa_memory_exception_data *data;
		int i;

		for (i = 0; i < p->n_pdds; i++) {
			if (p->pdds[i]->dev->id == dev_id) {
				pdd = p->pdds[i];
				break;
			}
		}

		if (!pdd)
			return -ENODEV;

		data = (struct kfd_hsa_memory_exception_data *)
						pdd->vm_fault_exc_data;

		kfd_dqm_evict_pasid(pdd->dev->dqm, p->pasid);
		kfd_signal_vm_fault_event(pdd->dev, p->pasid, NULL, data);
		error_reason &= ~KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION);
	}

	if (error_reason & (KFD_EC_MASK(EC_PROCESS_RUNTIME))) {
		/*
		 * block should only happen after the debugger receives runtime
		 * enable notice.
		 */
		up(&p->runtime_enable_sema);
		error_reason &= ~KFD_EC_MASK(EC_PROCESS_RUNTIME);
	}

	if (error_reason)
		return kfd_send_exception_to_runtime(p, queue_id, error_reason);

	return 0;
}

static int kfd_dbg_set_queue_workaround(struct queue *q, bool enable)
{
	struct mqd_update_info minfo = {0};
+6 −0
Original line number Diff line number Diff line
@@ -34,6 +34,12 @@ int kfd_dbg_trap_disable(struct kfd_process *target);
int kfd_dbg_trap_enable(struct kfd_process *target, uint32_t fd,
			void __user *runtime_info,
			uint32_t *runtime_info_size);

int kfd_dbg_send_exception_to_runtime(struct kfd_process *p,
					unsigned int dev_id,
					unsigned int queue_id,
					uint64_t error_reason);

static inline bool kfd_dbg_is_per_vmid_supported(struct kfd_node *dev)
{
	return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) ||
+2 −1
Original line number Diff line number Diff line
@@ -1222,7 +1222,8 @@ void kfd_signal_hw_exception_event(u32 pasid)
}

void kfd_signal_vm_fault_event(struct kfd_node *dev, u32 pasid,
			       struct kfd_vm_fault_info *info)
				struct kfd_vm_fault_info *info,
				struct kfd_hsa_memory_exception_data *data)
{
	struct kfd_event *ev;
	uint32_t id;
Loading