From 297f7f82636115d6db4211b8d81764223baf2908 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 10 Jul 2020 15:34:21 -0700 Subject: swiotlb-xen: add struct device * parameter to xen_dma_sync_for_cpu No functional changes. The parameter is unused in this patch but will be used by next patches. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Tested-by: Corey Minyard Tested-by: Roman Shaposhnik Link: https://lore.kernel.org/r/20200710223427.6897-5-sstabellini@kernel.org Signed-off-by: Juergen Gross --- arch/arm/xen/mm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index d40e9e5fc52b..1a00e8003c64 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -71,8 +71,9 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) * pfn_valid returns true the pages is local and we can use the native * dma-direct functions, otherwise we call the Xen specific version. */ -void xen_dma_sync_for_cpu(dma_addr_t handle, phys_addr_t paddr, size_t size, - enum dma_data_direction dir) +void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, + phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { if (pfn_valid(PFN_DOWN(handle))) arch_sync_dma_for_cpu(paddr, size, dir); -- cgit v1.2.3 From 995d3556694edd3c6dda7671b46ad4a6b3043f2f Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 10 Jul 2020 15:34:22 -0700 Subject: swiotlb-xen: add struct device * parameter to xen_dma_sync_for_device No functional changes. The parameter is unused in this patch but will be used by next patches. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Tested-by: Corey Minyard Tested-by: Roman Shaposhnik Link: https://lore.kernel.org/r/20200710223427.6897-6-sstabellini@kernel.org Signed-off-by: Juergen Gross --- arch/arm/xen/mm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index 1a00e8003c64..f2414ea40a79 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -81,8 +81,9 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); } -void xen_dma_sync_for_device(dma_addr_t handle, phys_addr_t paddr, size_t size, - enum dma_data_direction dir) +void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, + phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { if (pfn_valid(PFN_DOWN(handle))) arch_sync_dma_for_device(paddr, size, dir); -- cgit v1.2.3 From 63f0620cc552c4cd5bb2747f77efce407487cb12 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 10 Jul 2020 15:34:26 -0700 Subject: xen/arm: introduce phys/dma translations in xen_dma_sync_for_* xen_dma_sync_for_cpu, xen_dma_sync_for_device, xen_arch_need_swiotlb are getting called passing dma addresses. On some platforms dma addresses could be different from physical addresses. Before doing any operations on these addresses we need to convert them back to physical addresses using dma_to_phys. Move the arch_sync_dma_for_cpu and arch_sync_dma_for_device calls from xen_dma_sync_for_cpu/device to swiotlb-xen.c, and add a call dma_to_phys to do address translations there. dma_cache_maint is fixed by the next patch. Signed-off-by: Stefano Stabellini Tested-by: Corey Minyard Tested-by: Roman Shaposhnik Acked-by: Juergen Gross Link: https://lore.kernel.org/r/20200710223427.6897-10-sstabellini@kernel.org Signed-off-by: Juergen Gross --- arch/arm/xen/mm.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index f2414ea40a79..a8251a70f442 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include #include #include @@ -72,22 +73,16 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) * dma-direct functions, otherwise we call the Xen specific version. */ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, - phys_addr_t paddr, size_t size, - enum dma_data_direction dir) + size_t size, enum dma_data_direction dir) { - if (pfn_valid(PFN_DOWN(handle))) - arch_sync_dma_for_cpu(paddr, size, dir); - else if (dir != DMA_TO_DEVICE) + if (dir != DMA_TO_DEVICE) dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); } void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, - phys_addr_t paddr, size_t size, - enum dma_data_direction dir) + size_t size, enum dma_data_direction dir) { - if (pfn_valid(PFN_DOWN(handle))) - arch_sync_dma_for_device(paddr, size, dir); - else if (dir == DMA_FROM_DEVICE) + if (dir == DMA_FROM_DEVICE) dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); else dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN); @@ -98,7 +93,7 @@ bool xen_arch_need_swiotlb(struct device *dev, dma_addr_t dev_addr) { unsigned int xen_pfn = XEN_PFN_DOWN(phys); - unsigned int bfn = XEN_PFN_DOWN(dev_addr); + unsigned int bfn = XEN_PFN_DOWN(dma_to_phys(dev, dev_addr)); /* * The swiotlb buffer should be used if -- cgit v1.2.3 From d7b461caa6cc64dd190577b46b0ec892a8d5e7c0 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 10 Jul 2020 15:34:27 -0700 Subject: xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint dma_cache_maint is getting called passing a dma address which could be different from a physical address. Add a struct device* parameter to dma_cache_maint. Translate the dma_addr_t parameter of dma_cache_maint by calling dma_to_phys. Do it for the first page and all the following pages, in case of multipage handling. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Tested-by: Corey Minyard Tested-by: Roman Shaposhnik Link: https://lore.kernel.org/r/20200710223427.6897-11-sstabellini@kernel.org Signed-off-by: Juergen Gross --- arch/arm/xen/mm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index a8251a70f442..396797ffe2b1 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -43,15 +43,18 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order) static bool hypercall_cflush = false; /* buffers in highmem or foreign pages cannot cross page boundaries */ -static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) +static void dma_cache_maint(struct device *dev, dma_addr_t handle, + size_t size, u32 op) { struct gnttab_cache_flush cflush; - cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK; cflush.offset = xen_offset_in_page(handle); cflush.op = op; + handle &= XEN_PAGE_MASK; do { + cflush.a.dev_bus_addr = dma_to_phys(dev, handle); + if (size + cflush.offset > XEN_PAGE_SIZE) cflush.length = XEN_PAGE_SIZE - cflush.offset; else @@ -60,7 +63,7 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1); cflush.offset = 0; - cflush.a.dev_bus_addr += cflush.length; + handle += cflush.length; size -= cflush.length; } while (size); } @@ -76,16 +79,16 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { if (dir != DMA_TO_DEVICE) - dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL); } void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { if (dir == DMA_FROM_DEVICE) - dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL); else - dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN); + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_CLEAN); } bool xen_arch_need_swiotlb(struct device *dev, -- cgit v1.2.3