addr = (u64)entry->src_data[0] << 12;
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
- if (retry_fault && amdgpu_gmc_filter_faults(adev, addr, entry->pasid,
- entry->timestamp))
- return 1; /* This also prevents sending it to KFD */
-
- /* If it's the first fault for this address, process it normally */
- if (retry_fault && !in_interrupt() &&
- amdgpu_vm_handle_fault(adev, entry->pasid, addr))
- return 1; /* This also prevents sending it to KFD */
+ if (retry_fault) {
+ /* Returning 1 here also prevents sending the IV to the KFD */
+
+ /* Process it onyl if it's the first fault for this address */
+ if (entry->ih != &adev->irq.ih_soft &&
+ amdgpu_gmc_filter_faults(adev, addr, entry->pasid,
+ entry->timestamp))
+ return 1;
+
+ /* Delegate it to a different ring if the hardware hasn't
+ * already done it.
+ */
+ if (in_interrupt()) {
+ amdgpu_irq_delegate(adev, entry, 8);
+ return 1;
+ }
+
+ /* Try to handle the recoverable page faults by filling page
+ * tables
+ */
+ if (amdgpu_vm_handle_fault(adev, entry->pasid, addr))
+ return 1;
+ }
if (!printk_ratelimit())
return 0;