diff options
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 40 |
2 files changed, 39 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c index 3d5ccb3755d4..49df6c791cfc 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c | |||
| @@ -27,18 +27,28 @@ | |||
| 27 | static bool cik_event_interrupt_isr(struct kfd_dev *dev, | 27 | static bool cik_event_interrupt_isr(struct kfd_dev *dev, |
| 28 | const uint32_t *ih_ring_entry) | 28 | const uint32_t *ih_ring_entry) |
| 29 | { | 29 | { |
| 30 | unsigned int pasid; | ||
| 31 | const struct cik_ih_ring_entry *ihre = | 30 | const struct cik_ih_ring_entry *ihre = |
| 32 | (const struct cik_ih_ring_entry *)ih_ring_entry; | 31 | (const struct cik_ih_ring_entry *)ih_ring_entry; |
| 32 | unsigned int vmid, pasid; | ||
| 33 | |||
| 34 | /* Only handle interrupts from KFD VMIDs */ | ||
| 35 | vmid = (ihre->ring_id & 0x0000ff00) >> 8; | ||
| 36 | if (vmid < dev->vm_info.first_vmid_kfd || | ||
| 37 | vmid > dev->vm_info.last_vmid_kfd) | ||
| 38 | return 0; | ||
| 33 | 39 | ||
| 40 | /* If there is no valid PASID, it's likely a firmware bug */ | ||
| 34 | pasid = (ihre->ring_id & 0xffff0000) >> 16; | 41 | pasid = (ihre->ring_id & 0xffff0000) >> 16; |
| 42 | if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt")) | ||
| 43 | return 0; | ||
| 35 | 44 | ||
| 36 | /* Do not process in ISR, just request it to be forwarded to WQ. */ | 45 | /* Interrupt types we care about: various signals and faults. |
| 37 | return (pasid != 0) && | 46 | * They will be forwarded to a work queue (see below). |
| 38 | (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE || | 47 | */ |
| 48 | return ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE || | ||
| 39 | ihre->source_id == CIK_INTSRC_SDMA_TRAP || | 49 | ihre->source_id == CIK_INTSRC_SDMA_TRAP || |
| 40 | ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG || | 50 | ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG || |
| 41 | ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE); | 51 | ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE; |
| 42 | } | 52 | } |
| 43 | 53 | ||
| 44 | static void cik_event_interrupt_wq(struct kfd_dev *dev, | 54 | static void cik_event_interrupt_wq(struct kfd_dev *dev, |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c index 39d41155581f..37029baa3346 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c | |||
| @@ -29,27 +29,35 @@ static bool event_interrupt_isr_v9(struct kfd_dev *dev, | |||
| 29 | const uint32_t *ih_ring_entry) | 29 | const uint32_t *ih_ring_entry) |
| 30 | { | 30 | { |
| 31 | uint16_t source_id, client_id, pasid, vmid; | 31 | uint16_t source_id, client_id, pasid, vmid; |
| 32 | const uint32_t *data = ih_ring_entry; | ||
| 32 | 33 | ||
| 33 | source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry); | 34 | /* Only handle interrupts from KFD VMIDs */ |
| 34 | client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry); | ||
| 35 | pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); | ||
| 36 | vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); | 35 | vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); |
| 36 | if (vmid < dev->vm_info.first_vmid_kfd || | ||
| 37 | vmid > dev->vm_info.last_vmid_kfd) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | /* If there is no valid PASID, it's likely a firmware bug */ | ||
| 41 | pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); | ||
| 42 | if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt")) | ||
| 43 | return 0; | ||
| 37 | 44 | ||
| 38 | if (pasid) { | 45 | source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry); |
| 39 | const uint32_t *data = ih_ring_entry; | 46 | client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry); |
| 40 | 47 | ||
| 41 | pr_debug("client id 0x%x, source id %d, pasid 0x%x. raw data:\n", | 48 | pr_debug("client id 0x%x, source id %d, pasid 0x%x. raw data:\n", |
| 42 | client_id, source_id, pasid); | 49 | client_id, source_id, pasid); |
| 43 | pr_debug("%8X, %8X, %8X, %8X, %8X, %8X, %8X, %8X.\n", | 50 | pr_debug("%8X, %8X, %8X, %8X, %8X, %8X, %8X, %8X.\n", |
| 44 | data[0], data[1], data[2], data[3], | 51 | data[0], data[1], data[2], data[3], |
| 45 | data[4], data[5], data[6], data[7]); | 52 | data[4], data[5], data[6], data[7]); |
| 46 | } | ||
| 47 | 53 | ||
| 48 | return (pasid != 0) && | 54 | /* Interrupt types we care about: various signals and faults. |
| 49 | (source_id == SOC15_INTSRC_CP_END_OF_PIPE || | 55 | * They will be forwarded to a work queue (see below). |
| 50 | source_id == SOC15_INTSRC_SDMA_TRAP || | 56 | */ |
| 51 | source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG || | 57 | return source_id == SOC15_INTSRC_CP_END_OF_PIPE || |
| 52 | source_id == SOC15_INTSRC_CP_BAD_OPCODE); | 58 | source_id == SOC15_INTSRC_SDMA_TRAP || |
| 59 | source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG || | ||
| 60 | source_id == SOC15_INTSRC_CP_BAD_OPCODE; | ||
| 53 | } | 61 | } |
| 54 | 62 | ||
| 55 | static void event_interrupt_wq_v9(struct kfd_dev *dev, | 63 | static void event_interrupt_wq_v9(struct kfd_dev *dev, |
