iommu/amd: Improve page fault error reporting
authorVasant Hegde <vasant.hegde@amd.com>
Wed, 15 Feb 2023 05:26:42 +0000 (05:26 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 08:34:28 +0000 (09:34 +0100)
commit 996d120b4de2b0d6b592bd9fbbe6e244b81ab3cc upstream.

If IOMMU domain for device group is not setup properly then we may hit
IOMMU page fault. Current page fault handler assumes that domain is
always setup and it will hit NULL pointer derefence (see below sample log).

Lets check whether domain is setup or not and log appropriate message.

Sample log:
----------
 amdgpu 0000:00:01.0: amdgpu: SE 1, SH per SE 1, CU per SH 8, active_cu_number 6
 BUG: kernel NULL pointer dereference, address: 0000000000000058
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x0000) - not-present page
 PGD 0 P4D 0
 Oops: 0000 [#1] PREEMPT SMP NOPTI
 CPU: 2 PID: 56 Comm: irq/24-AMD-Vi Not tainted 6.2.0-rc2+ #89
 Hardware name: xxx
 RIP: 0010:report_iommu_fault+0x11/0x90
 [...]
 Call Trace:
  <TASK>
  amd_iommu_int_thread+0x60c/0x760
  ? __pfx_irq_thread_fn+0x10/0x10
  irq_thread_fn+0x1f/0x60
  irq_thread+0xea/0x1a0
  ? preempt_count_add+0x6a/0xa0
  ? __pfx_irq_thread_dtor+0x10/0x10
  ? __pfx_irq_thread+0x10/0x10
  kthread+0xe9/0x110
  ? __pfx_kthread+0x10/0x10
  ret_from_fork+0x2c/0x50
  </TASK>

Reported-by: Matt Fagnani <matt.fagnani@bell.net>
Suggested-by: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216865
Link: https://lore.kernel.org/lkml/15d0f9ff-2a56-b3e9-5b45-e6b23300ae3b@leemhuis.info/
Link: https://lore.kernel.org/r/20230215052642.6016-3-vasant.hegde@amd.com
Cc: stable@vger.kernel.org
[joro: Edit commit message]
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iommu/amd/iommu.c

index 46bf074..968e5e6 100644 (file)
@@ -558,6 +558,15 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
                 * prevent logging it.
                 */
                if (IS_IOMMU_MEM_TRANSACTION(flags)) {
+                       /* Device not attached to domain properly */
+                       if (dev_data->domain == NULL) {
+                               pr_err_ratelimited("Event logged [Device not attached to domain properly]\n");
+                               pr_err_ratelimited("  device=%04x:%02x:%02x.%x domain=0x%04x\n",
+                                                  iommu->pci_seg->id, PCI_BUS_NUM(devid), PCI_SLOT(devid),
+                                                  PCI_FUNC(devid), domain_id);
+                               goto out;
+                       }
+
                        if (!report_iommu_fault(&dev_data->domain->domain,
                                                &pdev->dev, address,
                                                IS_WRITE_REQUEST(flags) ?