hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
....@@ -23,7 +23,8 @@
2323 #include "kfd_priv.h"
2424 #include "kfd_events.h"
2525 #include "soc15_int.h"
26
-
26
+#include "kfd_device_queue_manager.h"
27
+#include "kfd_smi_events.h"
2728
2829 static bool event_interrupt_isr_v9(struct kfd_dev *dev,
2930 const uint32_t *ih_ring_entry,
....@@ -37,21 +38,39 @@
3738 vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry);
3839 if (vmid < dev->vm_info.first_vmid_kfd ||
3940 vmid > dev->vm_info.last_vmid_kfd)
40
- return 0;
41
-
42
- /* If there is no valid PASID, it's likely a firmware bug */
43
- pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
44
- if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt"))
45
- return 0;
41
+ return false;
4642
4743 source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry);
4844 client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry);
45
+ pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry);
4946
50
- pr_debug("client id 0x%x, source id %d, pasid 0x%x. raw data:\n",
51
- client_id, source_id, pasid);
47
+ /* This is a known issue for gfx9. Under non HWS, pasid is not set
48
+ * in the interrupt payload, so we need to find out the pasid on our
49
+ * own.
50
+ */
51
+ if (!pasid && dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
52
+ const uint32_t pasid_mask = 0xffff;
53
+
54
+ *patched_flag = true;
55
+ memcpy(patched_ihre, ih_ring_entry,
56
+ dev->device_info->ih_ring_entry_size);
57
+
58
+ pasid = dev->dqm->vmid_pasid[vmid];
59
+
60
+ /* Patch the pasid field */
61
+ patched_ihre[3] = cpu_to_le32((le32_to_cpu(patched_ihre[3])
62
+ & ~pasid_mask) | pasid);
63
+ }
64
+
65
+ pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw data:\n",
66
+ client_id, source_id, vmid, pasid);
5267 pr_debug("%8X, %8X, %8X, %8X, %8X, %8X, %8X, %8X.\n",
5368 data[0], data[1], data[2], data[3],
5469 data[4], data[5], data[6], data[7]);
70
+
71
+ /* If there is no valid PASID, it's likely a bug */
72
+ if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt"))
73
+ return false;
5574
5675 /* Interrupt types we care about: various signals and faults.
5776 * They will be forwarded to a work queue (see below).
....@@ -61,6 +80,7 @@
6180 source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG ||
6281 source_id == SOC15_INTSRC_CP_BAD_OPCODE ||
6382 client_id == SOC15_IH_CLIENTID_VMC ||
83
+ client_id == SOC15_IH_CLIENTID_VMC1 ||
6484 client_id == SOC15_IH_CLIENTID_UTCL2;
6585 }
6686
....@@ -85,6 +105,7 @@
85105 else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
86106 kfd_signal_hw_exception_event(pasid);
87107 else if (client_id == SOC15_IH_CLIENTID_VMC ||
108
+ client_id == SOC15_IH_CLIENTID_VMC1 ||
88109 client_id == SOC15_IH_CLIENTID_UTCL2) {
89110 struct kfd_vm_fault_info info = {0};
90111 uint16_t ring_id = SOC15_RING_ID_FROM_IH_ENTRY(ih_ring_entry);
....@@ -97,6 +118,7 @@
97118 info.prot_read = ring_id & 0x10;
98119 info.prot_write = ring_id & 0x20;
99120
121
+ kfd_smi_event_update_vmfault(dev, pasid);
100122 kfd_process_vm_fault(dev->dqm, pasid);
101123 kfd_signal_vm_fault_event(dev, pasid, &info);
102124 }