2019-10-25 08:50:41

by Laurentiu Tudor

[permalink] [raw]
Subject: [PATCH 0/3] dma-mapping: introduce new dma unmap and sync variants

From: Laurentiu Tudor <[email protected]>

This series introduces a few new dma unmap and sync api variants that,
on top of what the originals do, return the physical address
corresponding to the input dma address. In order to do that a new dma
map op is added, .get_phys_addr that takes the input dma address and
returns the physical address backing it up.
The second patch adds an implementation for this new dma map op in the
generic iommu dma glue code and wires it in.
The third patch updates the dpaa2-eth driver to use the new apis.

Context: https://lkml.org/lkml/2019/5/31/684

Changes since RFC
* completely changed the approach: added unmap and sync variants that
return the phys addr instead of adding a new dma to phys conversion
function

Laurentiu Tudor (3):
dma-mapping: introduce new dma unmap and sync api variants
iommu/dma: wire-up new dma map op .get_phys_addr
dpaa2_eth: use new unmap and sync dma api variants

drivers/iommu/dma-iommu.c | 12 ++++
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++---------
.../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 1 -
include/linux/dma-mapping.h | 55 +++++++++++++++++++
4 files changed, 85 insertions(+), 26 deletions(-)

--
2.17.1


2019-10-25 08:51:56

by Laurentiu Tudor

[permalink] [raw]
Subject: [PATCH 3/3] dpaa2_eth: use new unmap and sync dma api variants

From: Laurentiu Tudor <[email protected]>

Convert this driver to usage of the newly introduced dma unmap and
sync DMA APIs. This will get rid of the unsupported direct usage of
iommu_iova_to_phys() API.

Signed-off-by: Laurentiu Tudor <[email protected]>
---
.../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++-----------
.../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 1 -
2 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 19379bae0144..bd43bfcb3126 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -29,16 +29,6 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");

-static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
- dma_addr_t iova_addr)
-{
- phys_addr_t phys_addr;
-
- phys_addr = domain ? iommu_iova_to_phys(domain, iova_addr) : iova_addr;
-
- return phys_to_virt(phys_addr);
-}
-
static void validate_rx_csum(struct dpaa2_eth_priv *priv,
u32 fd_status,
struct sk_buff *skb)
@@ -85,9 +75,10 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv,
sgt = vaddr + dpaa2_fd_get_offset(fd);
for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
addr = dpaa2_sg_get_addr(&sgt[i]);
- sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
- dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_BIDIRECTIONAL);
+ sg_vaddr = phys_to_virt
+ (dma_unmap_page_phys(dev, addr,
+ DPAA2_ETH_RX_BUF_SIZE,
+ DMA_BIDIRECTIONAL));

free_pages((unsigned long)sg_vaddr, 0);
if (dpaa2_sg_is_final(&sgt[i]))
@@ -143,9 +134,10 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,

/* Get the address and length from the S/G entry */
sg_addr = dpaa2_sg_get_addr(sge);
- sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr);
- dma_unmap_page(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_BIDIRECTIONAL);
+ sg_vaddr = phys_to_virt
+ (dma_unmap_page_phys(dev, sg_addr,
+ DPAA2_ETH_RX_BUF_SIZE,
+ DMA_BIDIRECTIONAL));

sg_length = dpaa2_sg_get_len(sge);

@@ -210,9 +202,9 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
int i;

for (i = 0; i < count; i++) {
- vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
- dma_unmap_page(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
- DMA_BIDIRECTIONAL);
+ vaddr = phys_to_virt(dma_unmap_page_phys(dev, buf_array[i],
+ DPAA2_ETH_RX_BUF_SIZE,
+ DMA_BIDIRECTIONAL));
free_pages((unsigned long)vaddr, 0);
}
}
@@ -369,9 +361,9 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
/* Tracing point */
trace_dpaa2_rx_fd(priv->net_dev, fd);

- vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
- dma_sync_single_for_cpu(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_BIDIRECTIONAL);
+ vaddr = phys_to_virt(dma_sync_single_for_cpu_phys(dev, addr,
+ DPAA2_ETH_RX_BUF_SIZE,
+ DMA_BIDIRECTIONAL));

fas = dpaa2_get_fas(vaddr, false);
prefetch(fas);
@@ -682,7 +674,10 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
u32 fd_len = dpaa2_fd_get_len(fd);

fd_addr = dpaa2_fd_get_addr(fd);
- buffer_start = dpaa2_iova_to_virt(priv->iommu_domain, fd_addr);
+ buffer_start = phys_to_virt
+ (dma_sync_single_for_cpu_phys(dev, fd_addr,
+ sizeof(*swa),
+ DMA_BIDIRECTIONAL));
swa = (struct dpaa2_eth_swa *)buffer_start;

if (fd_format == dpaa2_fd_single) {
@@ -3448,8 +3443,6 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
priv = netdev_priv(net_dev);
priv->net_dev = net_dev;

- priv->iommu_domain = iommu_get_domain_for_dev(dev);
-
/* Obtain a MC portal */
err = fsl_mc_portal_allocate(dpni_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
&priv->mc_io);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 8a0e65b3267f..4e5183617ebd 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -374,7 +374,6 @@ struct dpaa2_eth_priv {

struct fsl_mc_device *dpbp_dev;
u16 bpid;
- struct iommu_domain *iommu_domain;

bool tx_tstamp; /* Tx timestamping enabled */
bool rx_tstamp; /* Rx timestamping enabled */
--
2.17.1

2019-10-25 09:44:02

by Laurentiu Tudor

[permalink] [raw]
Subject: [PATCH 2/3] iommu/dma: wire-up new dma map op .get_phys_addr

From: Laurentiu Tudor <[email protected]>

Add an implementation of the newly introduced dma map op in the
generic DMA IOMMU generic glue layer and wire it up.

Signed-off-by: Laurentiu Tudor <[email protected]>
---
drivers/iommu/dma-iommu.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index f321279baf9e..e4e2bde586e0 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1091,6 +1091,17 @@ static unsigned long iommu_dma_get_merge_boundary(struct device *dev)
return (1UL << __ffs(domain->pgsize_bitmap)) - 1;
}

+static phys_addr_t iommu_dma_get_phys_addr(struct device *dev,
+ dma_addr_t dma_handle)
+{
+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+
+ if (domain)
+ return iommu_iova_to_phys(domain, dma_handle);
+
+ return 0;
+}
+
static const struct dma_map_ops iommu_dma_ops = {
.alloc = iommu_dma_alloc,
.free = iommu_dma_free,
@@ -1107,6 +1118,7 @@ static const struct dma_map_ops iommu_dma_ops = {
.map_resource = iommu_dma_map_resource,
.unmap_resource = iommu_dma_unmap_resource,
.get_merge_boundary = iommu_dma_get_merge_boundary,
+ .get_phys_addr = iommu_dma_get_phys_addr,
};

/*
--
2.17.1