From: Logan Gunthorpe <logang@deltatee.com>
To: Jason Gunthorpe <jgg@nvidia.com>
Cc: "Leon Romanovsky" <leon@kernel.org>,
"Christoph Hellwig" <hch@lst.de>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Christian König" <christian.koenig@amd.com>,
dri-devel@lists.freedesktop.org, iommu@lists.linux.dev,
"Jens Axboe" <axboe@kernel.dk>,
"Jérôme Glisse" <jglisse@redhat.com>,
"Joerg Roedel" <joro@8bytes.org>,
kvm@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-media@vger.kernel.org, linux-mm@kvack.org,
linux-pci@vger.kernel.org,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"Robin Murphy" <robin.murphy@arm.com>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Vivek Kasireddy" <vivek.kasireddy@intel.com>,
"Will Deacon" <will@kernel.org>
Subject: Re: [PATCH 05/10] PCI/P2PDMA: Export pci_p2pdma_map_type() function
Date: Tue, 29 Jul 2025 14:54:13 -0600 [thread overview]
Message-ID: <f332e2b9-151f-49ca-ac0c-8c9494c38027@deltatee.com> (raw)
In-Reply-To: <20250728231107.GE36037@nvidia.com>
On 2025-07-28 17:11, Jason Gunthorpe wrote:
>> If the dma mapping for P2P memory doesn't need to create an iommu
>> mapping then that's fine. But it should be the dma-iommu layer to decide
>> that.
>
> So above, we can't use dma-iommu.c, it might not be compiled into the
> kernel but the dma_map_phys() path is still valid.
This is an easily solved problem. I did a very rough sketch below to say
it's really not that hard. (Note it has some rough edges that could be
cleaned up and I based it off Leon's git repo which appears to not be
the same as what was posted, but the core concept is sound).
Logan
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 1853a969e197..da1a6003620a 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1806,6 +1806,22 @@ bool dma_iova_try_alloc(struct device *dev,
struct dma_iova_state *state,
}
EXPORT_SYMBOL_GPL(dma_iova_try_alloc);
+void dma_iova_try_alloc_p2p(struct p2pdma_provider *provider, struct
device *dev,
+ struct dma_iova_state *state, phys_addr_t phys, size_t size)
+{
+ switch (pci_p2pdma_map_type(provider, dev)) {
+ case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
+ dma_iova_try_alloc(dev, state, phys, size);
+ return;
+ case PCI_P2PDMA_MAP_BUS_ADDR:
+ state->bus_addr = true;
+ return;
+ default:
+ return;
+ }
+}
+EXPORT_SYMBOL_GPL(dma_iova_try_alloc_p2p);
+
/**
* dma_iova_free - Free an IOVA space
* @dev: Device to free the IOVA space for
diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c
b/drivers/vfio/pci/vfio_pci_dmabuf.c
index 455541d21538..5749be3a9b58 100644
--- a/drivers/vfio/pci/vfio_pci_dmabuf.c
+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
@@ -30,25 +30,12 @@ static int vfio_pci_dma_buf_attach(struct dma_buf
*dmabuf,
if (priv->revoked)
return -ENODEV;
- switch (pci_p2pdma_map_type(priv->vdev->provider, attachment->dev)) {
- case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE:
- break;
- case PCI_P2PDMA_MAP_BUS_ADDR:
- /*
- * There is no need in IOVA at all for this flow.
- * We rely on attachment->priv == NULL as a marker
- * for this mode.
- */
- return 0;
- default:
- return -EINVAL;
- }
-
attachment->priv = kzalloc(sizeof(struct dma_iova_state), GFP_KERNEL);
if (!attachment->priv)
return -ENOMEM;
- dma_iova_try_alloc(attachment->dev, attachment->priv, 0, priv->size);
+ dma_iova_try_alloc_p2p(priv->vdev->provider, attachment->dev,
+ attachment->priv, 0, priv->size);
return 0;
}
@@ -98,26 +85,11 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment
*attachment,
sgl = sgt->sgl;
for (i = 0; i < priv->nr_ranges; i++) {
- if (!state) {
- addr = pci_p2pdma_bus_addr_map(provider,
- phys_vec[i].paddr);
- } else if (dma_use_iova(state)) {
- ret = dma_iova_link(attachment->dev, state,
- phys_vec[i].paddr, 0,
- phys_vec[i].len, dir, attrs);
- if (ret)
- goto err_unmap_dma;
-
- mapped_len += phys_vec[i].len;
- } else {
- addr = dma_map_phys(attachment->dev, phys_vec[i].paddr,
- phys_vec[i].len, dir, attrs);
- ret = dma_mapping_error(attachment->dev, addr);
- if (ret)
- goto err_unmap_dma;
- }
+ addr = dma_map_phys_prealloc(attachment->dev, phys_vec[i].paddr,
+ phys_vec[i].len, dir, attrs, state,
+ provider);
- if (!state || !dma_use_iova(state)) {
+ if (addr != DMA_MAPPING_USE_IOVA) {
/*
* In IOVA case, there is only one SG entry which spans
* for whole IOVA address space. So there is no need
@@ -128,7 +100,7 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment
*attachment,
}
}
- if (state && dma_use_iova(state)) {
+ if (addr == DMA_MAPPING_USE_IOVA) {
WARN_ON_ONCE(mapped_len != priv->size);
ret = dma_iova_sync(attachment->dev, state, 0, mapped_len);
if (ret)
@@ -139,7 +111,7 @@ vfio_pci_dma_buf_map(struct dma_buf_attachment
*attachment,
return sgt;
err_unmap_dma:
- if (!i || !state)
+ if (!i || state->bus_addr)
; /* Do nothing */
else if (dma_use_iova(state))
dma_iova_destroy(attachment->dev, state, mapped_len, dir,
@@ -164,7 +136,7 @@ static void vfio_pci_dma_buf_unmap(struct
dma_buf_attachment *attachment,
struct scatterlist *sgl;
int i;
- if (!state)
+ if (state->bus_addr)
; /* Do nothing */
else if (dma_use_iova(state))
dma_iova_destroy(attachment->dev, state, priv->size, dir,
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index ba54bbeca861..675e5ac13265 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -70,11 +70,14 @@
*/
#define DMA_MAPPING_ERROR (~(dma_addr_t)0)
+#define DMA_MAPPING_USE_IOVA ((dma_addr_t)-2)
+
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
struct dma_iova_state {
dma_addr_t addr;
u64 __size;
+ bool bus_addr;
};
/*
@@ -120,6 +123,12 @@ void dma_unmap_page_attrs(struct device *dev,
dma_addr_t addr, size_t size,
enum dma_data_direction dir, unsigned long attrs);
dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
enum dma_data_direction dir, unsigned long attrs);
+
+struct p2pdma_provider;
+dma_addr_t dma_map_phys_prealloc(struct device *dev, phys_addr_t phys,
size_t size,
+ enum dma_data_direction dir, unsigned long attrs,
+ struct dma_iova_state *state, struct p2pdma_provider *provider);
+
void dma_unmap_phys(struct device *dev, dma_addr_t addr, size_t size,
enum dma_data_direction dir, unsigned long attrs);
unsigned int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
@@ -321,6 +330,8 @@ static inline bool dma_use_iova(struct
dma_iova_state *state)
bool dma_iova_try_alloc(struct device *dev, struct dma_iova_state *state,
phys_addr_t phys, size_t size);
+void dma_iova_try_alloc_p2p(struct p2pdma_provider *provider, struct
device *dev,
+ struct dma_iova_state *state, phys_addr_t phys, size_t size);
void dma_iova_free(struct device *dev, struct dma_iova_state *state);
void dma_iova_destroy(struct device *dev, struct dma_iova_state *state,
size_t mapped_len, enum dma_data_direction dir,
@@ -343,6 +354,11 @@ static inline bool dma_iova_try_alloc(struct device
*dev,
{
return false;
}
+static inline void dma_iova_try_alloc_p2p(struct p2pdma_provider *provider,
+ struct device *dev, struct dma_iova_state *state, phys_addr_t phys,
+ size_t size)
+{
+}
static inline void dma_iova_free(struct device *dev,
struct dma_iova_state *state)
{
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index e1586eb52ab3..b2110098a29b 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -13,6 +13,7 @@
#include <linux/iommu-dma.h>
#include <linux/kmsan.h>
#include <linux/of_device.h>
+#include <linux/pci-p2pdma.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include "debug.h"
@@ -202,6 +203,27 @@ dma_addr_t dma_map_phys(struct device *dev,
phys_addr_t phys, size_t size,
}
EXPORT_SYMBOL_GPL(dma_map_phys);
+dma_addr_t dma_map_phys_prealloc(struct device *dev, phys_addr_t phys,
size_t size,
+ enum dma_data_direction dir, unsigned long attrs,
+ struct dma_iova_state *state, struct p2pdma_provider *provider)
+{
+ int ret;
+
+ if (state->bus_addr)
+ return pci_p2pdma_bus_addr_map(provider, phys);
+
+ if (dma_use_iova(state)) {
+ ret = dma_iova_link(dev, state, phys, 0, size, dir, attrs);
+ if (ret)
+ return DMA_MAPPING_ERROR;
+
+ return DMA_MAPPING_USE_IOVA;
+ }
+
+ return dma_map_phys(dev, phys, size, dir, attrs);
+}
+EXPORT_SYMBOL_GPL(dma_map_phys_prealloc);
+
dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page,
size_t offset, size_t size, enum dma_data_direction dir,
unsigned long attrs)
next prev parent reply other threads:[~2025-07-29 20:54 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-23 13:00 [PATCH 00/10] vfio/pci: Allow MMIO regions to be exported through dma-buf Leon Romanovsky
2025-07-23 13:00 ` [PATCH 01/10] PCI/P2PDMA: Remove redundant bus_offset from map state Leon Romanovsky
2025-07-24 7:50 ` Christoph Hellwig
2025-07-23 13:00 ` [PATCH 02/10] PCI/P2PDMA: Introduce p2pdma_provider structure for cleaner abstraction Leon Romanovsky
2025-07-24 7:51 ` Christoph Hellwig
2025-07-24 7:55 ` Leon Romanovsky
2025-07-24 7:59 ` Christoph Hellwig
2025-07-24 8:07 ` Leon Romanovsky
2025-07-27 18:51 ` Jason Gunthorpe
2025-07-29 7:52 ` Christoph Hellwig
2025-07-29 8:53 ` Leon Romanovsky
2025-07-29 10:41 ` Christoph Hellwig
2025-07-29 11:39 ` Leon Romanovsky
2025-07-29 13:15 ` Jason Gunthorpe
2025-07-29 16:12 ` Jason Gunthorpe
2025-07-23 13:00 ` [PATCH 03/10] PCI/P2PDMA: Simplify bus address mapping API Leon Romanovsky
2025-07-24 7:52 ` Christoph Hellwig
2025-07-23 13:00 ` [PATCH 04/10] PCI/P2PDMA: Refactor to separate core P2P functionality from memory allocation Leon Romanovsky
2025-07-23 13:00 ` [PATCH 05/10] PCI/P2PDMA: Export pci_p2pdma_map_type() function Leon Romanovsky
2025-07-24 8:03 ` Christoph Hellwig
2025-07-24 8:13 ` Leon Romanovsky
2025-07-25 16:30 ` Logan Gunthorpe
2025-07-25 18:54 ` Leon Romanovsky
2025-07-25 19:12 ` Logan Gunthorpe
2025-07-27 6:01 ` Leon Romanovsky
2025-07-27 19:05 ` Jason Gunthorpe
2025-07-28 16:12 ` Logan Gunthorpe
2025-07-28 16:41 ` Leon Romanovsky
2025-07-28 17:07 ` Logan Gunthorpe
2025-07-28 23:11 ` Jason Gunthorpe
2025-07-29 20:54 ` Logan Gunthorpe [this message]
2025-07-29 22:14 ` Jason Gunthorpe
2025-07-30 8:03 ` Leon Romanovsky
2025-07-29 7:52 ` Christoph Hellwig
2025-07-29 8:45 ` Leon Romanovsky
2025-07-27 19:02 ` Jason Gunthorpe
2025-07-23 13:00 ` [PATCH 06/10] types: move phys_vec definition to common header Leon Romanovsky
2025-07-23 13:00 ` [PATCH 07/10] vfio: Export vfio device get and put registration helpers Leon Romanovsky
2025-07-23 13:00 ` [PATCH 08/10] vfio/pci: Enable peer-to-peer DMA transactions by default Leon Romanovsky
2025-07-23 13:00 ` [PATCH 09/10] vfio/pci: Share the core device pointer while invoking feature functions Leon Romanovsky
2025-07-28 20:55 ` Alex Williamson
2025-07-29 8:39 ` Leon Romanovsky
2025-07-23 13:00 ` [PATCH 10/10] vfio/pci: Add dma-buf export support for MMIO regions Leon Romanovsky
2025-07-24 5:13 ` Kasireddy, Vivek
2025-07-24 5:44 ` Leon Romanovsky
2025-07-25 5:34 ` Kasireddy, Vivek
2025-07-27 6:16 ` Leon Romanovsky
2025-07-29 19:44 ` Robin Murphy
2025-07-29 20:13 ` Jason Gunthorpe
2025-07-30 9:32 ` Leon Romanovsky
2025-07-30 14:49 ` Robin Murphy
2025-07-30 16:01 ` Jason Gunthorpe
2025-07-30 19:58 ` [PATCH 00/10] vfio/pci: Allow MMIO regions to be exported through dma-buf Alex Williamson
2025-07-31 0:21 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f332e2b9-151f-49ca-ac0c-8c9494c38027@deltatee.com \
--to=logang@deltatee.com \
--cc=akpm@linux-foundation.org \
--cc=alex.williamson@redhat.com \
--cc=axboe@kernel.dk \
--cc=bhelgaas@google.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=hch@lst.de \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jglisse@redhat.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=leon@kernel.org \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-pci@vger.kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=robin.murphy@arm.com \
--cc=sumit.semwal@linaro.org \
--cc=vivek.kasireddy@intel.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®