1ca750681SFelix Kuehling /* 2ca750681SFelix Kuehling * Copyright 2016-2018 Advanced Micro Devices, Inc. 3ca750681SFelix Kuehling * 4ca750681SFelix Kuehling * Permission is hereby granted, free of charge, to any person obtaining a 5ca750681SFelix Kuehling * copy of this software and associated documentation files (the "Software"), 6ca750681SFelix Kuehling * to deal in the Software without restriction, including without limitation 7ca750681SFelix Kuehling * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8ca750681SFelix Kuehling * and/or sell copies of the Software, and to permit persons to whom the 9ca750681SFelix Kuehling * Software is furnished to do so, subject to the following conditions: 10ca750681SFelix Kuehling * 11ca750681SFelix Kuehling * The above copyright notice and this permission notice shall be included in 12ca750681SFelix Kuehling * all copies or substantial portions of the Software. 13ca750681SFelix Kuehling * 14ca750681SFelix Kuehling * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15ca750681SFelix Kuehling * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16ca750681SFelix Kuehling * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17ca750681SFelix Kuehling * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18ca750681SFelix Kuehling * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ca750681SFelix Kuehling * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20ca750681SFelix Kuehling * OTHER DEALINGS IN THE SOFTWARE. 21ca750681SFelix Kuehling */ 22ca750681SFelix Kuehling 23ca750681SFelix Kuehling #include "kfd_priv.h" 24ca750681SFelix Kuehling #include "kfd_events.h" 25ca750681SFelix Kuehling #include "soc15_int.h" 26a53a11a8SYong Zhao #include "kfd_device_queue_manager.h" 27938a0650SAmber Lin #include "kfd_smi_events.h" 2820161e51SDennis Li 2920161e51SDennis Li enum SQ_INTERRUPT_WORD_ENCODING { 3020161e51SDennis Li SQ_INTERRUPT_WORD_ENCODING_AUTO = 0x0, 3120161e51SDennis Li SQ_INTERRUPT_WORD_ENCODING_INST, 3220161e51SDennis Li SQ_INTERRUPT_WORD_ENCODING_ERROR, 3320161e51SDennis Li }; 3420161e51SDennis Li 3520161e51SDennis Li enum SQ_INTERRUPT_ERROR_TYPE { 3620161e51SDennis Li SQ_INTERRUPT_ERROR_TYPE_EDC_FUE = 0x0, 3720161e51SDennis Li SQ_INTERRUPT_ERROR_TYPE_ILLEGAL_INST, 3820161e51SDennis Li SQ_INTERRUPT_ERROR_TYPE_MEMVIOL, 3920161e51SDennis Li SQ_INTERRUPT_ERROR_TYPE_EDC_FED, 4020161e51SDennis Li }; 4120161e51SDennis Li 4220161e51SDennis Li /* SQ_INTERRUPT_WORD_AUTO_CTXID */ 4320161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE__SHIFT 0 4420161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__WLT__SHIFT 1 4520161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE_BUF_FULL__SHIFT 2 4620161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__REG_TIMESTAMP__SHIFT 3 4720161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__CMD_TIMESTAMP__SHIFT 4 4820161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__HOST_CMD_OVERFLOW__SHIFT 5 4920161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__HOST_REG_OVERFLOW__SHIFT 6 5020161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__IMMED_OVERFLOW__SHIFT 7 5120161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE_UTC_ERROR__SHIFT 8 5220161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__SE_ID__SHIFT 24 5320161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__ENCODING__SHIFT 26 5420161e51SDennis Li 5520161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE_MASK 0x00000001 5620161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__WLT_MASK 0x00000002 5720161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE_BUF_FULL_MASK 0x00000004 5820161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__REG_TIMESTAMP_MASK 0x00000008 5920161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__CMD_TIMESTAMP_MASK 0x00000010 6020161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__HOST_CMD_OVERFLOW_MASK 0x00000020 6120161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__HOST_REG_OVERFLOW_MASK 0x00000040 6220161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__IMMED_OVERFLOW_MASK 0x00000080 6320161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__THREAD_TRACE_UTC_ERROR_MASK 0x00000100 6420161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__SE_ID_MASK 0x03000000 6520161e51SDennis Li #define SQ_INTERRUPT_WORD_AUTO_CTXID__ENCODING_MASK 0x0c000000 6620161e51SDennis Li 6720161e51SDennis Li /* SQ_INTERRUPT_WORD_WAVE_CTXID */ 6820161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__DATA__SHIFT 0 6920161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SH_ID__SHIFT 12 7020161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__PRIV__SHIFT 13 7120161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__WAVE_ID__SHIFT 14 7220161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SIMD_ID__SHIFT 18 7320161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__CU_ID__SHIFT 20 7420161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SE_ID__SHIFT 24 7520161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__ENCODING__SHIFT 26 7620161e51SDennis Li 7720161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__DATA_MASK 0x00000fff 7820161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SH_ID_MASK 0x00001000 7920161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__PRIV_MASK 0x00002000 8020161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__WAVE_ID_MASK 0x0003c000 8120161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SIMD_ID_MASK 0x000c0000 8220161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__CU_ID_MASK 0x00f00000 8320161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__SE_ID_MASK 0x03000000 8420161e51SDennis Li #define SQ_INTERRUPT_WORD_WAVE_CTXID__ENCODING_MASK 0x0c000000 8520161e51SDennis Li 8620161e51SDennis Li #define KFD_CONTEXT_ID_GET_SQ_INT_DATA(ctx0, ctx1) \ 8720161e51SDennis Li ((ctx0 & 0xfff) | ((ctx0 >> 16) & 0xf000) | ((ctx1 << 16) & 0xff0000)) 8820161e51SDennis Li 8920161e51SDennis Li #define KFD_SQ_INT_DATA__ERR_TYPE_MASK 0xF00000 9020161e51SDennis Li #define KFD_SQ_INT_DATA__ERR_TYPE__SHIFT 20 91ca750681SFelix Kuehling 92ca750681SFelix Kuehling static bool event_interrupt_isr_v9(struct kfd_dev *dev, 9358e69886SLan Xiao const uint32_t *ih_ring_entry, 9458e69886SLan Xiao uint32_t *patched_ihre, 9558e69886SLan Xiao bool *patched_flag) 96ca750681SFelix Kuehling { 97ca750681SFelix Kuehling uint16_t source_id, client_id, pasid, vmid; 98c129db12SFelix Kuehling const uint32_t *data = ih_ring_entry; 99c129db12SFelix Kuehling 100c129db12SFelix Kuehling /* Only handle interrupts from KFD VMIDs */ 101c129db12SFelix Kuehling vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); 102c129db12SFelix Kuehling if (vmid < dev->vm_info.first_vmid_kfd || 103c129db12SFelix Kuehling vmid > dev->vm_info.last_vmid_kfd) 1048c8e1f69SAishwarya Ramakrishnan return false; 105c129db12SFelix Kuehling 106ca750681SFelix Kuehling source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry); 107ca750681SFelix Kuehling client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry); 10800557f41SYong Zhao pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); 109ca750681SFelix Kuehling 110ae279f69SAlex Deucher /* Only handle clients we care about */ 111ae279f69SAlex Deucher if (client_id != SOC15_IH_CLIENTID_GRBM_CP && 112ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA0 && 113ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA1 && 114ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA2 && 115ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA3 && 116ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA4 && 117ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA5 && 118ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA6 && 119ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_SDMA7 && 120ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_VMC && 121ae279f69SAlex Deucher client_id != SOC15_IH_CLIENTID_VMC1 && 1227af103eaSTao Zhou client_id != SOC15_IH_CLIENTID_UTCL2 && 1237af103eaSTao Zhou client_id != SOC15_IH_CLIENTID_SE0SH && 1247af103eaSTao Zhou client_id != SOC15_IH_CLIENTID_SE1SH && 1257af103eaSTao Zhou client_id != SOC15_IH_CLIENTID_SE2SH && 1267af103eaSTao Zhou client_id != SOC15_IH_CLIENTID_SE3SH) 127ae279f69SAlex Deucher return false; 128ae279f69SAlex Deucher 129a53a11a8SYong Zhao /* This is a known issue for gfx9. Under non HWS, pasid is not set 130a53a11a8SYong Zhao * in the interrupt payload, so we need to find out the pasid on our 131a53a11a8SYong Zhao * own. 132a53a11a8SYong Zhao */ 133a53a11a8SYong Zhao if (!pasid && dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) { 134a53a11a8SYong Zhao const uint32_t pasid_mask = 0xffff; 135a53a11a8SYong Zhao 136a53a11a8SYong Zhao *patched_flag = true; 137a53a11a8SYong Zhao memcpy(patched_ihre, ih_ring_entry, 138a53a11a8SYong Zhao dev->device_info->ih_ring_entry_size); 139a53a11a8SYong Zhao 1403fe023d4SYong Zhao pasid = dev->dqm->vmid_pasid[vmid]; 141a53a11a8SYong Zhao 142a53a11a8SYong Zhao /* Patch the pasid field */ 143a53a11a8SYong Zhao patched_ihre[3] = cpu_to_le32((le32_to_cpu(patched_ihre[3]) 144a53a11a8SYong Zhao & ~pasid_mask) | pasid); 145a53a11a8SYong Zhao } 146a53a11a8SYong Zhao 14700557f41SYong Zhao pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw data:\n", 14800557f41SYong Zhao client_id, source_id, vmid, pasid); 149ca750681SFelix Kuehling pr_debug("%8X, %8X, %8X, %8X, %8X, %8X, %8X, %8X.\n", 150ca750681SFelix Kuehling data[0], data[1], data[2], data[3], 151ca750681SFelix Kuehling data[4], data[5], data[6], data[7]); 152ca750681SFelix Kuehling 153a53a11a8SYong Zhao /* If there is no valid PASID, it's likely a bug */ 154a53a11a8SYong Zhao if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) 1558c8e1f69SAishwarya Ramakrishnan return false; 15600557f41SYong Zhao 157c129db12SFelix Kuehling /* Interrupt types we care about: various signals and faults. 158c129db12SFelix Kuehling * They will be forwarded to a work queue (see below). 159c129db12SFelix Kuehling */ 160c129db12SFelix Kuehling return source_id == SOC15_INTSRC_CP_END_OF_PIPE || 161ca750681SFelix Kuehling source_id == SOC15_INTSRC_SDMA_TRAP || 162ca750681SFelix Kuehling source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG || 1632640c3faSshaoyunl source_id == SOC15_INTSRC_CP_BAD_OPCODE || 1646d909c5dSOak Zeng ((client_id == SOC15_IH_CLIENTID_VMC || 1650ad8c5e2SYong Zhao client_id == SOC15_IH_CLIENTID_VMC1 || 1666d909c5dSOak Zeng client_id == SOC15_IH_CLIENTID_UTCL2) && 1676d909c5dSOak Zeng !amdgpu_no_queue_eviction_on_vm_fault); 168ca750681SFelix Kuehling } 169ca750681SFelix Kuehling 170ca750681SFelix Kuehling static void event_interrupt_wq_v9(struct kfd_dev *dev, 171ca750681SFelix Kuehling const uint32_t *ih_ring_entry) 172ca750681SFelix Kuehling { 173ca750681SFelix Kuehling uint16_t source_id, client_id, pasid, vmid; 17420161e51SDennis Li uint32_t context_id0, context_id1; 17520161e51SDennis Li uint32_t sq_intr_err, sq_int_data, encoding; 176ca750681SFelix Kuehling 177ca750681SFelix Kuehling source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry); 178ca750681SFelix Kuehling client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry); 179ca750681SFelix Kuehling pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); 180ca750681SFelix Kuehling vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); 18120161e51SDennis Li context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); 18220161e51SDennis Li context_id1 = SOC15_CONTEXT_ID1_FROM_IH_ENTRY(ih_ring_entry); 183ca750681SFelix Kuehling 1847af103eaSTao Zhou if (client_id == SOC15_IH_CLIENTID_GRBM_CP || 1857af103eaSTao Zhou client_id == SOC15_IH_CLIENTID_SE0SH || 1867af103eaSTao Zhou client_id == SOC15_IH_CLIENTID_SE1SH || 1877af103eaSTao Zhou client_id == SOC15_IH_CLIENTID_SE2SH || 1887af103eaSTao Zhou client_id == SOC15_IH_CLIENTID_SE3SH) { 189ca750681SFelix Kuehling if (source_id == SOC15_INTSRC_CP_END_OF_PIPE) 19020161e51SDennis Li kfd_signal_event_interrupt(pasid, context_id0, 32); 19120161e51SDennis Li else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG) { 19220161e51SDennis Li sq_int_data = KFD_CONTEXT_ID_GET_SQ_INT_DATA(context_id0, context_id1); 19320161e51SDennis Li encoding = REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, ENCODING); 19420161e51SDennis Li switch (encoding) { 19520161e51SDennis Li case SQ_INTERRUPT_WORD_ENCODING_AUTO: 19620161e51SDennis Li pr_debug( 19720161e51SDennis Li "sq_intr: auto, se %d, ttrace %d, wlt %d, ttrac_buf_full %d, reg_tms %d, cmd_tms %d, host_cmd_ovf %d, host_reg_ovf %d, immed_ovf %d, ttrace_utc_err %d\n", 19820161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, SE_ID), 19920161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE), 20020161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, WLT), 20120161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE_BUF_FULL), 20220161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, REG_TIMESTAMP), 20320161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, CMD_TIMESTAMP), 20420161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, HOST_CMD_OVERFLOW), 20520161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, HOST_REG_OVERFLOW), 20620161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, IMMED_OVERFLOW), 20720161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_AUTO_CTXID, THREAD_TRACE_UTC_ERROR)); 20820161e51SDennis Li break; 20920161e51SDennis Li case SQ_INTERRUPT_WORD_ENCODING_INST: 21020161e51SDennis Li pr_debug("sq_intr: inst, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, intr_data 0x%x\n", 21120161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID), 21220161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA), 21320161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID), 21420161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, PRIV), 21520161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, WAVE_ID), 21620161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SIMD_ID), 21720161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, CU_ID), 21820161e51SDennis Li sq_int_data); 21920161e51SDennis Li break; 22020161e51SDennis Li case SQ_INTERRUPT_WORD_ENCODING_ERROR: 22120161e51SDennis Li sq_intr_err = REG_GET_FIELD(sq_int_data, KFD_SQ_INT_DATA, ERR_TYPE); 22220161e51SDennis Li pr_warn("sq_intr: error, se %d, data 0x%x, sh %d, priv %d, wave_id %d, simd_id %d, cu_id %d, err_type %d\n", 22320161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SE_ID), 22420161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, DATA), 22520161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SH_ID), 22620161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, PRIV), 22720161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, WAVE_ID), 22820161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, SIMD_ID), 22920161e51SDennis Li REG_GET_FIELD(context_id0, SQ_INTERRUPT_WORD_WAVE_CTXID, CU_ID), 23020161e51SDennis Li sq_intr_err); 23120161e51SDennis Li if (sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_ILLEGAL_INST && 23220161e51SDennis Li sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_MEMVIOL) { 233e2b1f9f5SDennis Li kfd_signal_poison_consumed_event(dev, pasid); 23420161e51SDennis Li amdgpu_amdkfd_gpu_reset(dev->kgd); 23520161e51SDennis Li return; 23620161e51SDennis Li } 23720161e51SDennis Li break; 23820161e51SDennis Li default: 23920161e51SDennis Li break; 24020161e51SDennis Li } 24120161e51SDennis Li kfd_signal_event_interrupt(pasid, context_id0 & 0xffffff, 24); 24220161e51SDennis Li } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) 243ca750681SFelix Kuehling kfd_signal_hw_exception_event(pasid); 244ae279f69SAlex Deucher } else if (client_id == SOC15_IH_CLIENTID_SDMA0 || 245ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA1 || 246ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA2 || 247ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA3 || 248ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA4 || 249ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA5 || 250ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA6 || 251ae279f69SAlex Deucher client_id == SOC15_IH_CLIENTID_SDMA7) { 252*4a1d4b6dSHawking Zhang if (source_id == SOC15_INTSRC_SDMA_TRAP) { 25320161e51SDennis Li kfd_signal_event_interrupt(pasid, context_id0 & 0xfffffff, 28); 254*4a1d4b6dSHawking Zhang } else if (source_id == SOC15_INTSRC_SDMA_ECC) { 255*4a1d4b6dSHawking Zhang kfd_signal_poison_consumed_event(dev, pasid); 256*4a1d4b6dSHawking Zhang amdgpu_amdkfd_gpu_reset(dev->kgd); 257*4a1d4b6dSHawking Zhang return; 258*4a1d4b6dSHawking Zhang } 259ae279f69SAlex Deucher } else if (client_id == SOC15_IH_CLIENTID_VMC || 2600ad8c5e2SYong Zhao client_id == SOC15_IH_CLIENTID_VMC1 || 261ca750681SFelix Kuehling client_id == SOC15_IH_CLIENTID_UTCL2) { 2622640c3faSshaoyunl struct kfd_vm_fault_info info = {0}; 2632640c3faSshaoyunl uint16_t ring_id = SOC15_RING_ID_FROM_IH_ENTRY(ih_ring_entry); 2642640c3faSshaoyunl 2652640c3faSshaoyunl info.vmid = vmid; 2662640c3faSshaoyunl info.mc_id = client_id; 2672640c3faSshaoyunl info.page_addr = ih_ring_entry[4] | 2682640c3faSshaoyunl (uint64_t)(ih_ring_entry[5] & 0xf) << 32; 2692640c3faSshaoyunl info.prot_valid = ring_id & 0x08; 2702640c3faSshaoyunl info.prot_read = ring_id & 0x10; 2712640c3faSshaoyunl info.prot_write = ring_id & 0x20; 2722640c3faSshaoyunl 273938a0650SAmber Lin kfd_smi_event_update_vmfault(dev, pasid); 2742640c3faSshaoyunl kfd_process_vm_fault(dev->dqm, pasid); 2752640c3faSshaoyunl kfd_signal_vm_fault_event(dev, pasid, &info); 276ca750681SFelix Kuehling } 277ca750681SFelix Kuehling } 278ca750681SFelix Kuehling 279ca750681SFelix Kuehling const struct kfd_event_interrupt_class event_interrupt_class_v9 = { 280ca750681SFelix Kuehling .interrupt_isr = event_interrupt_isr_v9, 281ca750681SFelix Kuehling .interrupt_wq = event_interrupt_wq_v9, 282ca750681SFelix Kuehling }; 283