mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] drm/amdgpu: check importer DMA addressing for P2P DMA-buf attachments
@ 2026-11-04  2:03 Sabuj Pattanayek
  0 siblings, 0 replies; only message in thread
From: Sabuj Pattanayek @ 2026-11-04  2:03 UTC (permalink / raw)
  To: Alex Deucher, Christian König
  Cc: amd-gfx, dri-devel, linux-kernel, David Airlie, Simona Vetter,
	stable, Sabuj Pattanayek

amdgpu_dma_buf_attach() currently keeps attach->peer2peer enabled for
non-XGMI attachments whenever pci_p2pdma_distance() returns >= 0.
However, pci_p2pdma_distance() only verifies PCIe bridge topology and
does not check whether the importing device can DMA-address the
exporter's VRAM BAR physical address range.

When amdgpu_dma_buf_map() maps a VRAM BO for P2P via
amdgpu_vram_mgr_alloc_sgt() -> dma_map_resource(), if the importing
device is not behind a translating IOMMU DMA domain (IOMMU_DOMAIN_DMA or
IOMMU_DOMAIN_DMA_FQ) -- for example, when booted with iommu=pt or when
quirks_force_identity_mapping() places a GPU connected directly to an
AMD root port into IOMMU_DOMAIN_IDENTITY -- dma_direct_map_phys() checks
dma_capable() against the importer's DMA mask.

On systems where the exporter's 64-bit VRAM BAR is mapped above the
importer's DMA mask (such as a Radeon PRO W6400 with BAR 0 at
0x48030000000 paired with a 40-bit DMA mask Radeon PRO WX 3200 / Polaris
12 importer), dma_direct_map_phys() fails with DMA_MAPPING_ERROR and
warns:

[   18.421053] amdgpu 0000:c1:00.0: DMA addr 0x0000048038000000+8388608 overflow (mask ffffffffff, bus limit 0)

Because attach->peer2peer remained true, amdgpu_dma_buf_map() attempts
VRAM P2P mapping and fails with -EBUSY instead of falling back to GTT.
In multi-GPU desktop setups driving displays across both GPUs, this
breaks cross-GPU PRIME buffer sharing and causes compositors such as
gnome-shell and Xorg to fail command submission or crash on startup,
leaving the desktop unusable without manual IOMMU or sysfs workarounds.

Mirror the IOMMU remapping and BAR DMA mask check from
amdgpu_device_is_peer_accessible() (commit 75f0efbc4b3b ("drm/amdgpu:
Take IOMMU remapping into account for p2p checks")) in
amdgpu_dma_buf_attach() via a new amdgpu_dma_buf_is_p2p_addressable()
helper. Disabling attach->peer2peer when the importer cannot address the
exporter's VRAM aperture allows amdgpu_dma_buf_pin() and
amdgpu_dma_buf_map() to transparently fall back to GTT (system memory),
eliminating the DMA mapping overflow and restoring working multi-GPU
PRIME buffer sharing out of the box.

Fixes: 48262cd9499c ("drm/amdgpu: add checks if DMA-buf P2P is supported")
Cc: stable@vger.kernel.org
Signed-off-by: Sabuj Pattanayek <sabujp@google.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 31 ++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index bbe518757907..837330831eb2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -42,6 +42,7 @@
 #include <drm/ttm/ttm_tt.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-fence-array.h>
+#include <linux/iommu.h>
 #include <linux/pci-p2pdma.h>
 #include <linux/pm_runtime.h>
 
@@ -68,6 +69,33 @@ static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *atta
 	return NULL;
 }
 
+/**
+ * amdgpu_dma_buf_is_p2p_addressable - Check if importer can DMA-map exporter BAR
+ *
+ * @adev: exporter amdgpu_device
+ * @attach: DMA-buf attachment
+ *
+ * Returns:
+ * True if the importing device can address the exporter's CPU-visible VRAM
+ * aperture either via IOMMU DMA remapping or directly within its DMA mask.
+ */
+static bool amdgpu_dma_buf_is_p2p_addressable(struct amdgpu_device *adev,
+					      struct dma_buf_attachment *attach)
+{
+	struct iommu_domain *domain = iommu_get_domain_for_dev(attach->dev);
+	resource_size_t aper_limit;
+
+	if (domain && (domain->type == IOMMU_DOMAIN_DMA ||
+		       domain->type == IOMMU_DOMAIN_DMA_FQ))
+		return true;
+
+	if (!adev->gmc.aper_size)
+		return false;
+
+	aper_limit = adev->gmc.aper_base + adev->gmc.aper_size - 1;
+	return aper_limit <= dma_get_mask(attach->dev);
+}
+
 /**
  * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation
  *
@@ -98,7 +126,8 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
 		attach->peer2peer = false;
 
 	if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) &&
-	    pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
+	    (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0 ||
+	     !amdgpu_dma_buf_is_p2p_addressable(adev, attach)))
 		attach->peer2peer = false;
 
 	/*
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-04  2:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04  2:03 [PATCH] drm/amdgpu: check importer DMA addressing for P2P DMA-buf attachments Sabuj Pattanayek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®