0003-iommu-intel-do-deep-dma-unmapping-to-avoid-kernel-fl.patch 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. From 8ae0cfc0b59cd1462ca6cd819878933d357d01a7 Mon Sep 17 00:00:00 2001
  2. From: Ajay Garg <ajaygargnsit@gmail.com>
  3. Date: Tue, 12 Oct 2021 19:26:53 +0530
  4. Subject: [PATCH 3/6] iommu: intel: do deep dma-unmapping, to avoid
  5. kernel-flooding.
  6. Origins at :
  7. https://lists.linuxfoundation.org/pipermail/iommu/2021-October/thread.html
  8. === Changes from v1 => v2 ===
  9. a)
  10. Improved patch-description.
  11. b)
  12. A more root-level fix, as suggested by
  13. 1.
  14. Alex Williamson <alex.williamson@redhat.com>
  15. 2.
  16. Lu Baolu <baolu.lu@linux.intel.com>
  17. === Issue ===
  18. Kernel-flooding is seen, when an x86_64 L1 guest (Ubuntu-21) is booted in qemu/kvm
  19. on a x86_64 host (Ubuntu-21), with a host-pci-device attached.
  20. Following kind of logs, along with the stacktraces, cause the flood :
  21. ......
  22. DMAR: ERROR: DMA PTE for vPFN 0x428ec already set (to 3f6ec003 not 3f6ec003)
  23. DMAR: ERROR: DMA PTE for vPFN 0x428ed already set (to 3f6ed003 not 3f6ed003)
  24. DMAR: ERROR: DMA PTE for vPFN 0x428ee already set (to 3f6ee003 not 3f6ee003)
  25. DMAR: ERROR: DMA PTE for vPFN 0x428ef already set (to 3f6ef003 not 3f6ef003)
  26. DMAR: ERROR: DMA PTE for vPFN 0x428f0 already set (to 3f6f0003 not 3f6f0003)
  27. ......
  28. === Current Behaviour, leading to the issue ===
  29. Currently, when we do a dma-unmapping, we unmap/unlink the mappings, but
  30. the pte-entries are not cleared.
  31. Thus, following sequencing would flood the kernel-logs :
  32. i)
  33. A dma-unmapping makes the real/leaf-level pte-slot invalid, but the
  34. pte-content itself is not cleared.
  35. ii)
  36. Now, during some later dma-mapping procedure, as the pte-slot is about
  37. to hold a new pte-value, the intel-iommu checks if a prior
  38. pte-entry exists in the pte-slot. If it exists, it logs a kernel-error,
  39. along with a corresponding stacktrace.
  40. iii)
  41. Step ii) runs in abundance, and the kernel-logs run insane.
  42. === Fix ===
  43. We ensure that as part of a dma-unmapping, each (unmapped) pte-slot
  44. is also cleared of its value/content (at the leaf-level, where the
  45. real mapping from a iova => pfn mapping is stored).
  46. This completes a "deep" dma-unmapping.
  47. Signed-off-by: Ajay Garg <ajaygargnsit@gmail.com>
  48. Link: https://lore.kernel.org/linux-iommu/20211012135653.3852-1-ajaygargnsit@gmail.com/
  49. ---
  50. drivers/iommu/intel/iommu.c | 2 ++
  51. 1 file changed, 2 insertions(+)
  52. diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
  53. index 78f8c8e6803e..d8da48a91ba3 100644
  54. --- a/drivers/iommu/intel/iommu.c
  55. +++ b/drivers/iommu/intel/iommu.c
  56. @@ -5092,6 +5092,8 @@ static size_t intel_iommu_unmap(struct iommu_domain *domain,
  57. gather->freelist = domain_unmap(dmar_domain, start_pfn,
  58. last_pfn, gather->freelist);
  59. + dma_pte_clear_range(dmar_domain, start_pfn, last_pfn);
  60. +
  61. if (dmar_domain->max_addr == iova + size)
  62. dmar_domain->max_addr = iova;
  63. --
  64. 2.34.1