linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] fix swiotlb-xen for RPi4
@ 2020-05-20 23:45 Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Stefano Stabellini
                   ` (11 more replies)
  0 siblings, 12 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, tamas, roman

Hi all,

This series is a collection of fixes to get Linux running on the RPi4 as
dom0.

Conceptually there are only two significant changes:

- make sure not to call virt_to_page on vmalloc virt addresses (patch
  #1)
- use phys_to_dma and dma_to_phys to translate phys to/from dma
  addresses (all other patches)

In particular in regards to the second part, the RPi4 is the first
board where Xen can run that has the property that dma addresses are
different from physical addresses, and swiotlb-xen was written with the
assumption that phys addr == dma addr.

This series adds the phys_to_dma and dma_to_phys calls to make it work.


Cheers,

Stefano

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-21  8:01   ` Julien Grall
  2020-05-20 23:45 ` [PATCH 02/10] swiotlb-xen: remove start_dma_addr Stefano Stabellini
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Boris Ostrovsky <boris.ostrovsky@oracle.com>

Don't just assume that virt_to_page works on all virtual addresses.
Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc
virt addresses.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index b6d27762c6f8..a42129cba36e 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -335,6 +335,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 	int order = get_order(size);
 	phys_addr_t phys;
 	u64 dma_mask = DMA_BIT_MASK(32);
+	struct page *pg;
 
 	if (hwdev && hwdev->coherent_dma_mask)
 		dma_mask = hwdev->coherent_dma_mask;
@@ -346,9 +347,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 	/* Convert the size to actually allocated. */
 	size = 1UL << (order + XEN_PAGE_SHIFT);
 
+	pg = is_vmalloc_addr(vaddr) ? vmalloc_to_page(vaddr) :
+				      virt_to_page(vaddr);
 	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
 		     range_straddles_page_boundary(phys, size)) &&
-	    TestClearPageXenRemapped(virt_to_page(vaddr)))
+	    TestClearPageXenRemapped(pg))
 		xen_destroy_contiguous_region(phys, order);
 
 	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/10] swiotlb-xen: remove start_dma_addr
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-21  8:05   ` Julien Grall
  2020-05-20 23:45 ` [PATCH 03/10] swiotlb-xen: add struct device* parameter to xen_phys_to_bus Stefano Stabellini
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

It is not strictly needed. Call virt_to_phys on xen_io_tlb_start
instead. It will be useful not to have a start_dma_addr around with the
next patches.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index a42129cba36e..b5e0492b07b9 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs;
  * Quick lookup value of the bus address of the IOTLB.
  */
 
-static u64 start_dma_addr;
-
 /*
  * Both of these functions should avoid XEN_PFN_PHYS because phys_addr_t
  * can be 32bit when dma_addr_t is 64bit leading to a loss in
@@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early)
 		m_ret = XEN_SWIOTLB_EFIXUP;
 		goto error;
 	}
-	start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
 	if (early) {
 		if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs,
 			 verbose))
@@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 	 */
 	trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
 
-	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
+	map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start), phys,
 				     size, size, dir, attrs);
 	if (map == (phys_addr_t)DMA_MAPPING_ERROR)
 		return DMA_MAPPING_ERROR;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/10] swiotlb-xen: add struct device* parameter to xen_phys_to_bus
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 02/10] swiotlb-xen: remove start_dma_addr Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 04/10] swiotlb-xen: add struct device* parameter to xen_bus_to_phys Stefano Stabellini
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

The parameter is unused in this patch.
No functional changes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index b5e0492b07b9..958ee5517e0b 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -57,7 +57,7 @@ static unsigned long xen_io_tlb_nslabs;
  * can be 32bit when dma_addr_t is 64bit leading to a loss in
  * information if the shift is done before casting to 64bit.
  */
-static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
+static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
 {
 	unsigned long bfn = pfn_to_bfn(XEN_PFN_DOWN(paddr));
 	dma_addr_t dma = (dma_addr_t)bfn << XEN_PAGE_SHIFT;
@@ -78,9 +78,9 @@ static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
 	return paddr;
 }
 
-static inline dma_addr_t xen_virt_to_bus(void *address)
+static inline dma_addr_t xen_virt_to_bus(struct device *dev, void *address)
 {
-	return xen_phys_to_bus(virt_to_phys(address));
+	return xen_phys_to_bus(dev, virt_to_phys(address));
 }
 
 static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
@@ -309,7 +309,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 	 * Do not use virt_to_phys(ret) because on ARM it doesn't correspond
 	 * to *dma_handle. */
 	phys = *dma_handle;
-	dev_addr = xen_phys_to_bus(phys);
+	dev_addr = xen_phys_to_bus(hwdev, phys);
 	if (((dev_addr + size - 1 <= dma_mask)) &&
 	    !range_straddles_page_boundary(phys, size))
 		*dma_handle = dev_addr;
@@ -367,7 +367,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				unsigned long attrs)
 {
 	phys_addr_t map, phys = page_to_phys(page) + offset;
-	dma_addr_t dev_addr = xen_phys_to_bus(phys);
+	dma_addr_t dev_addr = xen_phys_to_bus(dev, phys);
 
 	BUG_ON(dir == DMA_NONE);
 	/*
@@ -392,7 +392,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 		return DMA_MAPPING_ERROR;
 
 	phys = map;
-	dev_addr = xen_phys_to_bus(map);
+	dev_addr = xen_phys_to_bus(dev, map);
 
 	/*
 	 * Ensure that the address returned is DMA'ble
@@ -536,7 +536,7 @@ xen_swiotlb_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
 static int
 xen_swiotlb_dma_supported(struct device *hwdev, u64 mask)
 {
-	return xen_virt_to_bus(xen_io_tlb_end - 1) <= mask;
+	return xen_virt_to_bus(hwdev, xen_io_tlb_end - 1) <= mask;
 }
 
 const struct dma_map_ops xen_swiotlb_dma_ops = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/10] swiotlb-xen: add struct device* parameter to xen_bus_to_phys
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (2 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 03/10] swiotlb-xen: add struct device* parameter to xen_phys_to_bus Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 05/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_cpu Stefano Stabellini
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

The parameter is unused in this patch.
No functional changes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 958ee5517e0b..9b4306a56feb 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -67,7 +67,7 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
 	return dma;
 }
 
-static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
+static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
 {
 	unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr));
 	dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT;
@@ -339,7 +339,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 
 	/* do not use virt_to_phys because on ARM it doesn't return you the
 	 * physical address */
-	phys = xen_bus_to_phys(dev_addr);
+	phys = xen_bus_to_phys(hwdev, dev_addr);
 
 	/* Convert the size to actually allocated. */
 	size = 1UL << (order + XEN_PAGE_SHIFT);
@@ -420,7 +420,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 		size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
-	phys_addr_t paddr = xen_bus_to_phys(dev_addr);
+	phys_addr_t paddr = xen_bus_to_phys(hwdev, dev_addr);
 
 	BUG_ON(dir == DMA_NONE);
 
@@ -436,7 +436,7 @@ static void
 xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr,
 		size_t size, enum dma_data_direction dir)
 {
-	phys_addr_t paddr = xen_bus_to_phys(dma_addr);
+	phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr);
 
 	if (!dev_is_dma_coherent(dev))
 		xen_dma_sync_for_cpu(dma_addr, paddr, size, dir);
@@ -449,7 +449,7 @@ static void
 xen_swiotlb_sync_single_for_device(struct device *dev, dma_addr_t dma_addr,
 		size_t size, enum dma_data_direction dir)
 {
-	phys_addr_t paddr = xen_bus_to_phys(dma_addr);
+	phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr);
 
 	if (is_xen_swiotlb_buffer(dma_addr))
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_DEVICE);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_cpu
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (3 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 04/10] swiotlb-xen: add struct device* parameter to xen_bus_to_phys Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 06/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_device Stefano Stabellini
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

The parameter is unused in this patch.
No functional changes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 arch/arm/xen/mm.c         | 5 +++--
 drivers/xen/swiotlb-xen.c | 4 ++--
 include/xen/swiotlb-xen.h | 5 +++--
 3 files changed, 8 insertions(+), 6 deletions(-)

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);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 9b4306a56feb..f9aa932973dd 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -425,7 +425,7 @@ static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 	BUG_ON(dir == DMA_NONE);
 
 	if (!dev_is_dma_coherent(hwdev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-		xen_dma_sync_for_cpu(dev_addr, paddr, size, dir);
+		xen_dma_sync_for_cpu(hwdev, dev_addr, paddr, size, dir);
 
 	/* NOTE: We use dev_addr here, not paddr! */
 	if (is_xen_swiotlb_buffer(dev_addr))
@@ -439,7 +439,7 @@ xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr,
 	phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr);
 
 	if (!dev_is_dma_coherent(dev))
-		xen_dma_sync_for_cpu(dma_addr, paddr, size, dir);
+		xen_dma_sync_for_cpu(dev, dma_addr, paddr, size, dir);
 
 	if (is_xen_swiotlb_buffer(dma_addr))
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_CPU);
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index ffc0d3902b71..f62d1854780b 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -4,8 +4,9 @@
 
 #include <linux/swiotlb.h>
 
-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);
 void xen_dma_sync_for_device(dma_addr_t handle, phys_addr_t paddr, size_t size,
 		enum dma_data_direction dir);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_device
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (4 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 05/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_cpu Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 07/10] swiotlb-xen: add struct device* parameter to is_xen_swiotlb_buffer Stefano Stabellini
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

The parameter is unused in this patch.
No functional changes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 arch/arm/xen/mm.c         | 5 +++--
 drivers/xen/swiotlb-xen.c | 4 ++--
 include/xen/swiotlb-xen.h | 5 +++--
 3 files changed, 8 insertions(+), 6 deletions(-)

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);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index f9aa932973dd..ef58f05ae445 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -405,7 +405,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 
 done:
 	if (!dev_is_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-		xen_dma_sync_for_device(dev_addr, phys, size, dir);
+		xen_dma_sync_for_device(dev, dev_addr, phys, size, dir);
 	return dev_addr;
 }
 
@@ -455,7 +455,7 @@ xen_swiotlb_sync_single_for_device(struct device *dev, dma_addr_t dma_addr,
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_DEVICE);
 
 	if (!dev_is_dma_coherent(dev))
-		xen_dma_sync_for_device(dma_addr, paddr, size, dir);
+		xen_dma_sync_for_device(dev, dma_addr, paddr, size, dir);
 }
 
 /*
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index f62d1854780b..6d235fe2b92d 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -7,8 +7,9 @@
 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);
-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);
 
 extern int xen_swiotlb_init(int verbose, bool early);
 extern const struct dma_map_ops xen_swiotlb_dma_ops;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/10] swiotlb-xen: add struct device* parameter to is_xen_swiotlb_buffer
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (5 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 06/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_device Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-20 23:45 ` [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations Stefano Stabellini
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

The parameter is unused in this patch.
No functional changes.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index ef58f05ae445..c50448fd9b75 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -97,7 +97,7 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
 	return 0;
 }
 
-static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
+static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr)
 {
 	unsigned long bfn = XEN_PFN_DOWN(dma_addr);
 	unsigned long xen_pfn = bfn_to_local_pfn(bfn);
@@ -428,7 +428,7 @@ static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 		xen_dma_sync_for_cpu(hwdev, dev_addr, paddr, size, dir);
 
 	/* NOTE: We use dev_addr here, not paddr! */
-	if (is_xen_swiotlb_buffer(dev_addr))
+	if (is_xen_swiotlb_buffer(hwdev, dev_addr))
 		swiotlb_tbl_unmap_single(hwdev, paddr, size, size, dir, attrs);
 }
 
@@ -441,7 +441,7 @@ xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr,
 	if (!dev_is_dma_coherent(dev))
 		xen_dma_sync_for_cpu(dev, dma_addr, paddr, size, dir);
 
-	if (is_xen_swiotlb_buffer(dma_addr))
+	if (is_xen_swiotlb_buffer(dev, dma_addr))
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_CPU);
 }
 
@@ -451,7 +451,7 @@ xen_swiotlb_sync_single_for_device(struct device *dev, dma_addr_t dma_addr,
 {
 	phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr);
 
-	if (is_xen_swiotlb_buffer(dma_addr))
+	if (is_xen_swiotlb_buffer(dev, dma_addr))
 		swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_DEVICE);
 
 	if (!dev_is_dma_coherent(dev))
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (6 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 07/10] swiotlb-xen: add struct device* parameter to is_xen_swiotlb_buffer Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-21  8:07   ` Julien Grall
  2020-05-21 22:59   ` Boris Ostrovsky
  2020-05-20 23:45 ` [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_* Stefano Stabellini
                   ` (3 subsequent siblings)
  11 siblings, 2 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

Call dma_to_phys in is_xen_swiotlb_buffer.
Call phys_to_dma in xen_phys_to_bus.
Call dma_to_phys in xen_bus_to_phys.

Everything is taken care of by these changes except for
xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a
few explicit phys_to_dma/dma_to_phys calls.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 drivers/xen/swiotlb-xen.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index c50448fd9b75..d011c4c7aa72 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
 
 	dma |= paddr & ~XEN_PAGE_MASK;
 
-	return dma;
+	return phys_to_dma(dev, dma);
 }
 
-static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
+static inline phys_addr_t xen_bus_to_phys(struct device *dev,
+					  dma_addr_t dma_addr)
 {
+	phys_addr_t baddr = dma_to_phys(dev, dma_addr);
 	unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr));
-	dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT;
-	phys_addr_t paddr = dma;
+	phys_addr_t paddr = (xen_pfn << XEN_PAGE_SHIFT) |
+			    (baddr & ~XEN_PAGE_MASK);
 
 	paddr |= baddr & ~XEN_PAGE_MASK;
 
@@ -99,7 +101,7 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
 
 static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr)
 {
-	unsigned long bfn = XEN_PFN_DOWN(dma_addr);
+	unsigned long bfn = XEN_PFN_DOWN(dma_to_phys(dev, dma_addr));
 	unsigned long xen_pfn = bfn_to_local_pfn(bfn);
 	phys_addr_t paddr = XEN_PFN_PHYS(xen_pfn);
 
@@ -304,11 +306,11 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 	if (hwdev && hwdev->coherent_dma_mask)
 		dma_mask = hwdev->coherent_dma_mask;
 
-	/* At this point dma_handle is the physical address, next we are
+	/* At this point dma_handle is the dma address, next we are
 	 * going to set it to the machine address.
 	 * Do not use virt_to_phys(ret) because on ARM it doesn't correspond
 	 * to *dma_handle. */
-	phys = *dma_handle;
+	phys = dma_to_phys(hwdev, *dma_handle);
 	dev_addr = xen_phys_to_bus(hwdev, phys);
 	if (((dev_addr + size - 1 <= dma_mask)) &&
 	    !range_straddles_page_boundary(phys, size))
@@ -319,6 +321,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			xen_free_coherent_pages(hwdev, size, ret, (dma_addr_t)phys, attrs);
 			return NULL;
 		}
+		*dma_handle = phys_to_dma(hwdev, *dma_handle);
 		SetPageXenRemapped(virt_to_page(ret));
 	}
 	memset(ret, 0, size);
@@ -351,7 +354,8 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 	    TestClearPageXenRemapped(pg))
 		xen_destroy_contiguous_region(phys, order);
 
-	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
+	xen_free_coherent_pages(hwdev, size, vaddr, phys_to_dma(hwdev, phys),
+				attrs);
 }
 
 /*
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_*
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (7 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-21  8:18   ` Julien Grall
  2020-05-20 23:45 ` [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint Stefano Stabellini
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

Add phys_to_dma/dma_to_phys calls to
xen_dma_sync_for_cpu, xen_dma_sync_for_device, and
xen_arch_need_swiotlb.

In xen_arch_need_swiotlb, take the opportunity to switch to the simpler
pfn_valid check we use everywhere else.

dma_cache_maint is fixed by the next patch.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 arch/arm/xen/mm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index f2414ea40a79..7639251bcc79 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 <linux/cpu.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-noncoherent.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
@@ -75,7 +76,7 @@ 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)))
+	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
 		arch_sync_dma_for_cpu(paddr, size, dir);
 	else if (dir != DMA_TO_DEVICE)
 		dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
@@ -85,7 +86,7 @@ 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)))
+	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
 		arch_sync_dma_for_device(paddr, size, dir);
 	else if (dir == DMA_FROM_DEVICE)
 		dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
@@ -97,8 +98,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
 			   phys_addr_t phys,
 			   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
@@ -115,7 +115,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
 	 * require a bounce buffer because the device doesn't support coherent
 	 * memory and we are not able to flush the cache.
 	 */
-	return (!hypercall_cflush && (xen_pfn != bfn) &&
+	return (!hypercall_cflush && !pfn_valid(bfn) &&
 		!dev_is_dma_coherent(dev));
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (8 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_* Stefano Stabellini
@ 2020-05-20 23:45 ` Stefano Stabellini
  2020-05-21  8:25   ` Julien Grall
  2020-05-20 23:51 ` [PATCH 00/10] fix swiotlb-xen for RPi4 Roman Shaposhnik
  2020-06-02 21:51 ` Stefano Stabellini
  11 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:45 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: sstabellini, xen-devel, linux-kernel, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

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 <stefano.stabellini@xilinx.com>
---
 arch/arm/xen/mm.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 7639251bcc79..6ddf3b3c1ab5 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);
 }
@@ -79,7 +82,7 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
 	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
 		arch_sync_dma_for_cpu(paddr, size, dir);
 	else 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,
@@ -89,9 +92,9 @@ void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
 	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
 		arch_sync_dma_for_device(paddr, size, dir);
 	else 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,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/10] fix swiotlb-xen for RPi4
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (9 preceding siblings ...)
  2020-05-20 23:45 ` [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint Stefano Stabellini
@ 2020-05-20 23:51 ` Roman Shaposhnik
  2020-05-20 23:56   ` Stefano Stabellini
  2020-06-02 21:51 ` Stefano Stabellini
  11 siblings, 1 reply; 31+ messages in thread
From: Roman Shaposhnik @ 2020-05-20 23:51 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Juergen Gross, Boris Ostrovsky, Konrad Wilk, Xen-devel,
	linux-kernel, tamas

On Wed, May 20, 2020 at 4:45 PM Stefano Stabellini
<sstabellini@kernel.org> wrote:
>
> Hi all,
>
> This series is a collection of fixes to get Linux running on the RPi4 as
> dom0.
>
> Conceptually there are only two significant changes:
>
> - make sure not to call virt_to_page on vmalloc virt addresses (patch
>   #1)
> - use phys_to_dma and dma_to_phys to translate phys to/from dma
>   addresses (all other patches)
>
> In particular in regards to the second part, the RPi4 is the first
> board where Xen can run that has the property that dma addresses are
> different from physical addresses, and swiotlb-xen was written with the
> assumption that phys addr == dma addr.
>
> This series adds the phys_to_dma and dma_to_phys calls to make it work.

Great to see this! Stefano, any chance you can put it in a branch some place
so I can test the final version?

Thanks,
Roman.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/10] fix swiotlb-xen for RPi4
  2020-05-20 23:51 ` [PATCH 00/10] fix swiotlb-xen for RPi4 Roman Shaposhnik
@ 2020-05-20 23:56   ` Stefano Stabellini
  0 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-20 23:56 UTC (permalink / raw)
  To: Roman Shaposhnik
  Cc: Stefano Stabellini, Juergen Gross, Boris Ostrovsky, Konrad Wilk,
	Xen-devel, linux-kernel, tamas

On Wed, 20 May 2020, Roman Shaposhnik wrote:
> On Wed, May 20, 2020 at 4:45 PM Stefano Stabellini
> <sstabellini@kernel.org> wrote:
> >
> > Hi all,
> >
> > This series is a collection of fixes to get Linux running on the RPi4 as
> > dom0.
> >
> > Conceptually there are only two significant changes:
> >
> > - make sure not to call virt_to_page on vmalloc virt addresses (patch
> >   #1)
> > - use phys_to_dma and dma_to_phys to translate phys to/from dma
> >   addresses (all other patches)
> >
> > In particular in regards to the second part, the RPi4 is the first
> > board where Xen can run that has the property that dma addresses are
> > different from physical addresses, and swiotlb-xen was written with the
> > assumption that phys addr == dma addr.
> >
> > This series adds the phys_to_dma and dma_to_phys calls to make it work.
> 
> Great to see this! Stefano, any chance you can put it in a branch some place
> so I can test the final version?

Here it is, but keep in mind that it is based on Linux master (because
it is meant to go upstream):

  git://git.kernel.org/pub/scm/linux/kernel/git/sstabellini/xen.git fix-rip4-v1

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses
  2020-05-20 23:45 ` [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Stefano Stabellini
@ 2020-05-21  8:01   ` Julien Grall
  2020-05-22  3:54     ` Stefano Stabellini
  0 siblings, 1 reply; 31+ messages in thread
From: Julien Grall @ 2020-05-21  8:01 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini

Hi,

On 21/05/2020 00:45, Stefano Stabellini wrote:
> From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> 
> Don't just assume that virt_to_page works on all virtual addresses.
> Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc
> virt addresses.

Can you provide an example where swiotlb is used with vmalloc()?

> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>   drivers/xen/swiotlb-xen.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index b6d27762c6f8..a42129cba36e 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -335,6 +335,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
>   	int order = get_order(size);
>   	phys_addr_t phys;
>   	u64 dma_mask = DMA_BIT_MASK(32);
> +	struct page *pg;
>   
>   	if (hwdev && hwdev->coherent_dma_mask)
>   		dma_mask = hwdev->coherent_dma_mask;
> @@ -346,9 +347,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
>   	/* Convert the size to actually allocated. */
>   	size = 1UL << (order + XEN_PAGE_SHIFT);
>   
> +	pg = is_vmalloc_addr(vaddr) ? vmalloc_to_page(vaddr) :
> +				      virt_to_page(vaddr);

Common DMA code seems to protect this check with CONFIG_DMA_REMAP. Is it 
something we want to do it here as well? Or is there any other condition 
where vmalloc can happen?

>   	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
>   		     range_straddles_page_boundary(phys, size)) &&
> -	    TestClearPageXenRemapped(virt_to_page(vaddr)))
> +	    TestClearPageXenRemapped(pg))
>   		xen_destroy_contiguous_region(phys, order);
>   
>   	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
> 

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/10] swiotlb-xen: remove start_dma_addr
  2020-05-20 23:45 ` [PATCH 02/10] swiotlb-xen: remove start_dma_addr Stefano Stabellini
@ 2020-05-21  8:05   ` Julien Grall
  2020-05-22  3:55     ` Stefano Stabellini
  0 siblings, 1 reply; 31+ messages in thread
From: Julien Grall @ 2020-05-21  8:05 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini

Hi,

On 21/05/2020 00:45, Stefano Stabellini wrote:
> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> 
> It is not strictly needed. Call virt_to_phys on xen_io_tlb_start
> instead. It will be useful not to have a start_dma_addr around with the
> next patches.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>   drivers/xen/swiotlb-xen.c | 5 +----
>   1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index a42129cba36e..b5e0492b07b9 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs;
>    * Quick lookup value of the bus address of the IOTLB.
>    */
>   
> -static u64 start_dma_addr;
> -
>   /*
>    * Both of these functions should avoid XEN_PFN_PHYS because phys_addr_t
>    * can be 32bit when dma_addr_t is 64bit leading to a loss in
> @@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early)
>   		m_ret = XEN_SWIOTLB_EFIXUP;
>   		goto error;
>   	}
> -	start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
>   	if (early) {
>   		if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs,
>   			 verbose))
> @@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
>   	 */
>   	trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
>   
> -	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
> +	map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start), phys,

xen_virt_to_bus() is implemented as xen_phys_to_bus(virt_to_phys()). Can 
you explain how the two are equivalent?

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations
  2020-05-20 23:45 ` [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations Stefano Stabellini
@ 2020-05-21  8:07   ` Julien Grall
  2020-05-21 22:59   ` Boris Ostrovsky
  1 sibling, 0 replies; 31+ messages in thread
From: Julien Grall @ 2020-05-21  8:07 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini

Hi,

On 21/05/2020 00:45, Stefano Stabellini wrote:
> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> 
> Call dma_to_phys in is_xen_swiotlb_buffer.
> Call phys_to_dma in xen_phys_to_bus.
> Call dma_to_phys in xen_bus_to_phys.
> 
> Everything is taken care of by these changes except for
> xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a
> few explicit phys_to_dma/dma_to_phys calls.

The commit message explains what the code is doing but doesn't explain 
why this is needed.

> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>   drivers/xen/swiotlb-xen.c | 20 ++++++++++++--------
>   1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index c50448fd9b75..d011c4c7aa72 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
>   
>   	dma |= paddr & ~XEN_PAGE_MASK;
>   
> -	return dma;
> +	return phys_to_dma(dev, dma);
>   }
>   
> -static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
> +static inline phys_addr_t xen_bus_to_phys(struct device *dev,
> +					  dma_addr_t dma_addr)
>   {
> +	phys_addr_t baddr = dma_to_phys(dev, dma_addr);
>   	unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr));
> -	dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT;
> -	phys_addr_t paddr = dma;
> +	phys_addr_t paddr = (xen_pfn << XEN_PAGE_SHIFT) |
> +			    (baddr & ~XEN_PAGE_MASK);
>   
>   	paddr |= baddr & ~XEN_PAGE_MASK;
>   
> @@ -99,7 +101,7 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
>   
>   static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr)
>   {
> -	unsigned long bfn = XEN_PFN_DOWN(dma_addr);
> +	unsigned long bfn = XEN_PFN_DOWN(dma_to_phys(dev, dma_addr));
>   	unsigned long xen_pfn = bfn_to_local_pfn(bfn);
>   	phys_addr_t paddr = XEN_PFN_PHYS(xen_pfn);
>   
> @@ -304,11 +306,11 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>   	if (hwdev && hwdev->coherent_dma_mask)
>   		dma_mask = hwdev->coherent_dma_mask;
>   
> -	/* At this point dma_handle is the physical address, next we are
> +	/* At this point dma_handle is the dma address, next we are
>   	 * going to set it to the machine address.
>   	 * Do not use virt_to_phys(ret) because on ARM it doesn't correspond
>   	 * to *dma_handle. */
> -	phys = *dma_handle;
> +	phys = dma_to_phys(hwdev, *dma_handle);
>   	dev_addr = xen_phys_to_bus(hwdev, phys);
>   	if (((dev_addr + size - 1 <= dma_mask)) &&
>   	    !range_straddles_page_boundary(phys, size))
> @@ -319,6 +321,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
>   			xen_free_coherent_pages(hwdev, size, ret, (dma_addr_t)phys, attrs);
>   			return NULL;
>   		}
> +		*dma_handle = phys_to_dma(hwdev, *dma_handle);
>   		SetPageXenRemapped(virt_to_page(ret));
>   	}
>   	memset(ret, 0, size);
> @@ -351,7 +354,8 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
>   	    TestClearPageXenRemapped(pg))
>   		xen_destroy_contiguous_region(phys, order);
>   
> -	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
> +	xen_free_coherent_pages(hwdev, size, vaddr, phys_to_dma(hwdev, phys),
> +				attrs);
>   }
>   
>   /*
> 

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_*
  2020-05-20 23:45 ` [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_* Stefano Stabellini
@ 2020-05-21  8:18   ` Julien Grall
  2020-05-21 20:08     ` Stefano Stabellini
  0 siblings, 1 reply; 31+ messages in thread
From: Julien Grall @ 2020-05-21  8:18 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini

Hi,

On 21/05/2020 00:45, Stefano Stabellini wrote:
> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> 
> Add phys_to_dma/dma_to_phys calls to
> xen_dma_sync_for_cpu, xen_dma_sync_for_device, and
> xen_arch_need_swiotlb.
> 
> In xen_arch_need_swiotlb, take the opportunity to switch to the simpler
> pfn_valid check we use everywhere else.
> 
> dma_cache_maint is fixed by the next patch.

Like patch #8, this explains what the code is doing not why this is 
necessary.

> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>   arch/arm/xen/mm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index f2414ea40a79..7639251bcc79 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 <linux/cpu.h>
> +#include <linux/dma-direct.h>
>   #include <linux/dma-noncoherent.h>
>   #include <linux/gfp.h>
>   #include <linux/highmem.h>
> @@ -75,7 +76,7 @@ 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)))
> +	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
>   		arch_sync_dma_for_cpu(paddr, size, dir);
>   	else if (dir != DMA_TO_DEVICE)
>   		dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
> @@ -85,7 +86,7 @@ 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)))
> +	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
>   		arch_sync_dma_for_device(paddr, size, dir);
>   	else if (dir == DMA_FROM_DEVICE)
>   		dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
> @@ -97,8 +98,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
>   			   phys_addr_t phys,
>   			   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
> @@ -115,7 +115,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
>   	 * require a bounce buffer because the device doesn't support coherent
>   	 * memory and we are not able to flush the cache.
>   	 */
> -	return (!hypercall_cflush && (xen_pfn != bfn) &&
> +	return (!hypercall_cflush && !pfn_valid(bfn) &&

I believe this change is incorrect. The bfn is a frame based on Xen page 
granularity (always 4K) while pfn_valid() is expecting a frame based on 
the Kernel page granularity.

>   		!dev_is_dma_coherent(dev));
>   }
>   
> 

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint
  2020-05-20 23:45 ` [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint Stefano Stabellini
@ 2020-05-21  8:25   ` Julien Grall
  0 siblings, 0 replies; 31+ messages in thread
From: Julien Grall @ 2020-05-21  8:25 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini



On 21/05/2020 00:45, Stefano Stabellini wrote:
> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> 
> 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.

The term 'page' is confusing here. Are we referring to Xen page or Linux 
page?

Also, same as patch #8 and #9 regarding the commit message.

> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>   arch/arm/xen/mm.c | 15 +++++++++------
>   1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index 7639251bcc79..6ddf3b3c1ab5 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);
>   }
> @@ -79,7 +82,7 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
>   	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
>   		arch_sync_dma_for_cpu(paddr, size, dir);
>   	else 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,
> @@ -89,9 +92,9 @@ void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
>   	if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle))))
>   		arch_sync_dma_for_device(paddr, size, dir);
>   	else 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,
> 

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_*
  2020-05-21  8:18   ` Julien Grall
@ 2020-05-21 20:08     ` Stefano Stabellini
  2020-05-21 20:17       ` Julien Grall
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-21 20:08 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk,
	xen-devel, linux-kernel, Stefano Stabellini

On Thu, 21 May 2020, Julien Grall wrote:
> > @@ -97,8 +98,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
> >   			   phys_addr_t phys,
> >   			   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
> > @@ -115,7 +115,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
> >   	 * require a bounce buffer because the device doesn't support coherent
> >   	 * memory and we are not able to flush the cache.
> >   	 */
> > -	return (!hypercall_cflush && (xen_pfn != bfn) &&
> > +	return (!hypercall_cflush && !pfn_valid(bfn) &&
> 
> I believe this change is incorrect. The bfn is a frame based on Xen page
> granularity (always 4K) while pfn_valid() is expecting a frame based on the
> Kernel page granularity.

Given that kernel granularity >= xen granularity it looks like it would
be safe to use PFN_DOWN instead of XEN_PFN_DOWN:

  unsigned int bfn = PFN_DOWN(dma_to_phys(dev, dev_addr));
  return (!hypercall_cflush && !pfn_valid(bfn) &&

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_*
  2020-05-21 20:08     ` Stefano Stabellini
@ 2020-05-21 20:17       ` Julien Grall
  0 siblings, 0 replies; 31+ messages in thread
From: Julien Grall @ 2020-05-21 20:17 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Jürgen Groß,
	Boris Ostrovsky, Konrad Rzeszutek Wilk, xen-devel, linux-kernel,
	Stefano Stabellini

On Thu, 21 May 2020 at 21:08, Stefano Stabellini <sstabellini@kernel.org> wrote:
>
> On Thu, 21 May 2020, Julien Grall wrote:
> > > @@ -97,8 +98,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
> > >                        phys_addr_t phys,
> > >                        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
> > > @@ -115,7 +115,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
> > >      * require a bounce buffer because the device doesn't support coherent
> > >      * memory and we are not able to flush the cache.
> > >      */
> > > -   return (!hypercall_cflush && (xen_pfn != bfn) &&
> > > +   return (!hypercall_cflush && !pfn_valid(bfn) &&
> >
> > I believe this change is incorrect. The bfn is a frame based on Xen page
> > granularity (always 4K) while pfn_valid() is expecting a frame based on the
> > Kernel page granularity.
>
> Given that kernel granularity >= xen granularity it looks like it would
> be safe to use PFN_DOWN instead of XEN_PFN_DOWN:
>
>   unsigned int bfn = PFN_DOWN(dma_to_phys(dev, dev_addr));

Yes. But is the change worth it though? pfn_valid() is definitely
going to be more expensive than the current check.

Cheers,

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations
  2020-05-20 23:45 ` [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations Stefano Stabellini
  2020-05-21  8:07   ` Julien Grall
@ 2020-05-21 22:59   ` Boris Ostrovsky
  2020-05-22 17:34     ` Stefano Stabellini
  1 sibling, 1 reply; 31+ messages in thread
From: Boris Ostrovsky @ 2020-05-21 22:59 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, konrad.wilk
  Cc: xen-devel, linux-kernel, Stefano Stabellini

On 5/20/20 7:45 PM, Stefano Stabellini wrote:
> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
>
> Call dma_to_phys in is_xen_swiotlb_buffer.
> Call phys_to_dma in xen_phys_to_bus.
> Call dma_to_phys in xen_bus_to_phys.
>
> Everything is taken care of by these changes except for
> xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a
> few explicit phys_to_dma/dma_to_phys calls.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> ---
>  drivers/xen/swiotlb-xen.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index c50448fd9b75..d011c4c7aa72 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
>  
>  	dma |= paddr & ~XEN_PAGE_MASK;
>  
> -	return dma;
> +	return phys_to_dma(dev, dma);
>  }
>  
> -static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
> +static inline phys_addr_t xen_bus_to_phys(struct device *dev,
> +					  dma_addr_t dma_addr)


Since now dma address != bus address this is no longer
xen_bus_to_phys(). (And I guess the same is rue for xen_phys_to_bus()).


>  {
> +	phys_addr_t baddr = dma_to_phys(dev, dma_addr);
>  	unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr));
> -	dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT;
> -	phys_addr_t paddr = dma;
> +	phys_addr_t paddr = (xen_pfn << XEN_PAGE_SHIFT) |
> +			    (baddr & ~XEN_PAGE_MASK);
>  
>  	paddr |= baddr & ~XEN_PAGE_MASK;


This line needs to go, no?


-boris


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses
  2020-05-21  8:01   ` Julien Grall
@ 2020-05-22  3:54     ` Stefano Stabellini
  2020-05-22 18:11       ` Julien Grall
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-22  3:54 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk,
	xen-devel, linux-kernel, Stefano Stabellini

On Thu, 21 May 2020, Julien Grall wrote:
> Hi,
> 
> On 21/05/2020 00:45, Stefano Stabellini wrote:
> > From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > 
> > Don't just assume that virt_to_page works on all virtual addresses.
> > Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc
> > virt addresses.
> 
> Can you provide an example where swiotlb is used with vmalloc()?

The issue was reported here happening on the Rasperry Pi 4:
https://marc.info/?l=xen-devel&m=158862573216800

If you are asking where in the Linux codebase the vmalloc is happening
specifically, I don't know for sure, my information is limited to the
stack trace that you see in the link (I don't have a Rasperry Pi 4 yet
but I shall have one soon.)


> > Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > ---
> >   drivers/xen/swiotlb-xen.c | 5 ++++-
> >   1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> > index b6d27762c6f8..a42129cba36e 100644
> > --- a/drivers/xen/swiotlb-xen.c
> > +++ b/drivers/xen/swiotlb-xen.c
> > @@ -335,6 +335,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t
> > size, void *vaddr,
> >   	int order = get_order(size);
> >   	phys_addr_t phys;
> >   	u64 dma_mask = DMA_BIT_MASK(32);
> > +	struct page *pg;
> >     	if (hwdev && hwdev->coherent_dma_mask)
> >   		dma_mask = hwdev->coherent_dma_mask;
> > @@ -346,9 +347,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t
> > size, void *vaddr,
> >   	/* Convert the size to actually allocated. */
> >   	size = 1UL << (order + XEN_PAGE_SHIFT);
> >   +	pg = is_vmalloc_addr(vaddr) ? vmalloc_to_page(vaddr) :
> > +				      virt_to_page(vaddr);
> 
> Common DMA code seems to protect this check with CONFIG_DMA_REMAP. Is it
> something we want to do it here as well? Or is there any other condition where
> vmalloc can happen?

I can see it in dma_direct_free_pages:

	if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr))
		vunmap(cpu_addr);

I wonder why the common DMA code does that. is_vmalloc_addr should work
regardless of CONFIG_DMA_REMAP. Maybe just for efficiency?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/10] swiotlb-xen: remove start_dma_addr
  2020-05-21  8:05   ` Julien Grall
@ 2020-05-22  3:55     ` Stefano Stabellini
  2020-05-22 18:16       ` Julien Grall
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-22  3:55 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk,
	xen-devel, linux-kernel, Stefano Stabellini

On Thu, 21 May 2020, Julien Grall wrote:
> Hi,
> 
> On 21/05/2020 00:45, Stefano Stabellini wrote:
> > From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > 
> > It is not strictly needed. Call virt_to_phys on xen_io_tlb_start
> > instead. It will be useful not to have a start_dma_addr around with the
> > next patches.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > ---
> >   drivers/xen/swiotlb-xen.c | 5 +----
> >   1 file changed, 1 insertion(+), 4 deletions(-)
> > 
> > diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> > index a42129cba36e..b5e0492b07b9 100644
> > --- a/drivers/xen/swiotlb-xen.c
> > +++ b/drivers/xen/swiotlb-xen.c
> > @@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs;
> >    * Quick lookup value of the bus address of the IOTLB.
> >    */
> >   -static u64 start_dma_addr;
> > -
> >   /*
> >    * Both of these functions should avoid XEN_PFN_PHYS because phys_addr_t
> >    * can be 32bit when dma_addr_t is 64bit leading to a loss in
> > @@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early)
> >   		m_ret = XEN_SWIOTLB_EFIXUP;
> >   		goto error;
> >   	}
> > -	start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
> >   	if (early) {
> >   		if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs,
> >   			 verbose))
> > @@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device
> > *dev, struct page *page,
> >   	 */
> >   	trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
> >   -	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
> > +	map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start),
> > phys,
> 
> xen_virt_to_bus() is implemented as xen_phys_to_bus(virt_to_phys()). Can you
> explain how the two are equivalent?

They are not equivalent. Looking at what swiotlb_tbl_map_single expects,
and also the implementation of swiotlb_init_with_tbl, I think
virt_to_phys is actually the one we want.

swiotlb_tbl_map_single compares the argument with __pa(tlb) which is
__pa(xen_io_tlb_start) which is virt_to_phys(xen_io_tlb_start).

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations
  2020-05-21 22:59   ` Boris Ostrovsky
@ 2020-05-22 17:34     ` Stefano Stabellini
  2020-05-22 18:29       ` Boris Ostrovsky
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-22 17:34 UTC (permalink / raw)
  To: Boris Ostrovsky
  Cc: Stefano Stabellini, jgross, konrad.wilk, xen-devel, linux-kernel,
	Stefano Stabellini

On Thu, 21 May 2020, Boris Ostrovsky wrote:
> On 5/20/20 7:45 PM, Stefano Stabellini wrote:
> > From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> >
> > Call dma_to_phys in is_xen_swiotlb_buffer.
> > Call phys_to_dma in xen_phys_to_bus.
> > Call dma_to_phys in xen_bus_to_phys.
> >
> > Everything is taken care of by these changes except for
> > xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a
> > few explicit phys_to_dma/dma_to_phys calls.
> >
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > ---
> >  drivers/xen/swiotlb-xen.c | 20 ++++++++++++--------
> >  1 file changed, 12 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> > index c50448fd9b75..d011c4c7aa72 100644
> > --- a/drivers/xen/swiotlb-xen.c
> > +++ b/drivers/xen/swiotlb-xen.c
> > @@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
> >  
> >  	dma |= paddr & ~XEN_PAGE_MASK;
> >  
> > -	return dma;
> > +	return phys_to_dma(dev, dma);
> >  }
> >  
> > -static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
> > +static inline phys_addr_t xen_bus_to_phys(struct device *dev,
> > +					  dma_addr_t dma_addr)
> 
> 
> Since now dma address != bus address this is no longer
> xen_bus_to_phys(). (And I guess the same is rue for xen_phys_to_bus()).

Should I rename them to xen_dma_to_phys and xen_phys_to_dma?

 
> >  {
> > +	phys_addr_t baddr = dma_to_phys(dev, dma_addr);
> >  	unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr));
> > -	dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT;
> > -	phys_addr_t paddr = dma;
> > +	phys_addr_t paddr = (xen_pfn << XEN_PAGE_SHIFT) |
> > +			    (baddr & ~XEN_PAGE_MASK);
> >  
> >  	paddr |= baddr & ~XEN_PAGE_MASK;
> 
> 
> This line needs to go, no?

Yes, good point

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses
  2020-05-22  3:54     ` Stefano Stabellini
@ 2020-05-22 18:11       ` Julien Grall
  2020-05-22 20:36         ` Stefano Stabellini
  0 siblings, 1 reply; 31+ messages in thread
From: Julien Grall @ 2020-05-22 18:11 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: jgross, boris.ostrovsky, konrad.wilk, xen-devel, linux-kernel,
	Stefano Stabellini

Hi Stefano,

On 22/05/2020 04:54, Stefano Stabellini wrote:
> On Thu, 21 May 2020, Julien Grall wrote:
>> Hi,
>>
>> On 21/05/2020 00:45, Stefano Stabellini wrote:
>>> From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
>>>
>>> Don't just assume that virt_to_page works on all virtual addresses.
>>> Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc
>>> virt addresses.
>>
>> Can you provide an example where swiotlb is used with vmalloc()?
> 
> The issue was reported here happening on the Rasperry Pi 4:
> https://marc.info/?l=xen-devel&m=158862573216800

Thanks, it would be good if the commit message contains a bit more details.

> 
> If you are asking where in the Linux codebase the vmalloc is happening
> specifically, I don't know for sure, my information is limited to the
> stack trace that you see in the link (I don't have a Rasperry Pi 4 yet
> but I shall have one soon.)

Looking at the code there is a comment in xen_swiotlb_alloc_coherent() 
suggesting that xen_alloc_coherent_pages() may return an ioremap'ped 
region on Arm. So it feels to me that commit 
b877ac9815a8fe7e5f6d7fdde3dc34652408840a "xen/swiotlb: remember having 
called xen_create_contiguous_region()" has always been broken on Arm.

As an aside, your commit message also suggests this is an issue for 
every virtual address used in swiotlb. But only the virt_to_page() call 
in xen_swiotlb_free_coherent() is modified. Is it intended? If yes, I 
think you want to update your commit message.

> 
> 
>>> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
>>> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
>>> ---
>>>    drivers/xen/swiotlb-xen.c | 5 ++++-
>>>    1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
>>> index b6d27762c6f8..a42129cba36e 100644
>>> --- a/drivers/xen/swiotlb-xen.c
>>> +++ b/drivers/xen/swiotlb-xen.c
>>> @@ -335,6 +335,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t
>>> size, void *vaddr,
>>>    	int order = get_order(size);
>>>    	phys_addr_t phys;
>>>    	u64 dma_mask = DMA_BIT_MASK(32);
>>> +	struct page *pg;
>>>      	if (hwdev && hwdev->coherent_dma_mask)
>>>    		dma_mask = hwdev->coherent_dma_mask;
>>> @@ -346,9 +347,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t
>>> size, void *vaddr,
>>>    	/* Convert the size to actually allocated. */
>>>    	size = 1UL << (order + XEN_PAGE_SHIFT);
>>>    +	pg = is_vmalloc_addr(vaddr) ? vmalloc_to_page(vaddr) :
>>> +				      virt_to_page(vaddr);
>>
>> Common DMA code seems to protect this check with CONFIG_DMA_REMAP. Is it
>> something we want to do it here as well? Or is there any other condition where
>> vmalloc can happen?
> 
> I can see it in dma_direct_free_pages:
> 
> 	if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr))
> 		vunmap(cpu_addr);
> 
> I wonder why the common DMA code does that. is_vmalloc_addr should work
> regardless of CONFIG_DMA_REMAP. Maybe just for efficiency?
is_vmalloc_addr() doesn't looks very expensive (although it is not an 
inline function). So I am not sure the reason behind it. It might be 
worth asking the author of the config.

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/10] swiotlb-xen: remove start_dma_addr
  2020-05-22  3:55     ` Stefano Stabellini
@ 2020-05-22 18:16       ` Julien Grall
  2020-05-22 20:47         ` Stefano Stabellini
  0 siblings, 1 reply; 31+ messages in thread
From: Julien Grall @ 2020-05-22 18:16 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: jgross, boris.ostrovsky, konrad.wilk, xen-devel, linux-kernel,
	Stefano Stabellini

Hi,

On 22/05/2020 04:55, Stefano Stabellini wrote:
> On Thu, 21 May 2020, Julien Grall wrote:
>> Hi,
>>
>> On 21/05/2020 00:45, Stefano Stabellini wrote:
>>> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
>>>
>>> It is not strictly needed. Call virt_to_phys on xen_io_tlb_start
>>> instead. It will be useful not to have a start_dma_addr around with the
>>> next patches.
>>>
>>> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
>>> ---
>>>    drivers/xen/swiotlb-xen.c | 5 +----
>>>    1 file changed, 1 insertion(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
>>> index a42129cba36e..b5e0492b07b9 100644
>>> --- a/drivers/xen/swiotlb-xen.c
>>> +++ b/drivers/xen/swiotlb-xen.c
>>> @@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs;
>>>     * Quick lookup value of the bus address of the IOTLB.
>>>     */
>>>    -static u64 start_dma_addr;
>>> -
>>>    /*
>>>     * Both of these functions should avoid XEN_PFN_PHYS because phys_addr_t
>>>     * can be 32bit when dma_addr_t is 64bit leading to a loss in
>>> @@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early)
>>>    		m_ret = XEN_SWIOTLB_EFIXUP;
>>>    		goto error;
>>>    	}
>>> -	start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
>>>    	if (early) {
>>>    		if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs,
>>>    			 verbose))
>>> @@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device
>>> *dev, struct page *page,
>>>    	 */
>>>    	trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
>>>    -	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
>>> +	map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start),
>>> phys,
>>
>> xen_virt_to_bus() is implemented as xen_phys_to_bus(virt_to_phys()). Can you
>> explain how the two are equivalent?
> 
> They are not equivalent. Looking at what swiotlb_tbl_map_single expects,
> and also the implementation of swiotlb_init_with_tbl, I think
> virt_to_phys is actually the one we want.
> 
> swiotlb_tbl_map_single compares the argument with __pa(tlb) which is
> __pa(xen_io_tlb_start) which is virt_to_phys(xen_io_tlb_start).

I can't find such check in master. What is your baseline? Could you 
point to the exact line of code?

Cheers,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations
  2020-05-22 17:34     ` Stefano Stabellini
@ 2020-05-22 18:29       ` Boris Ostrovsky
  0 siblings, 0 replies; 31+ messages in thread
From: Boris Ostrovsky @ 2020-05-22 18:29 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: jgross, konrad.wilk, xen-devel, linux-kernel, Stefano Stabellini

On 5/22/20 1:34 PM, Stefano Stabellini wrote:
> On Thu, 21 May 2020, Boris Ostrovsky wrote:
>> On 5/20/20 7:45 PM, Stefano Stabellini wrote:
>>> From: Stefano Stabellini <stefano.stabellini@xilinx.com>
>>>
>>> Call dma_to_phys in is_xen_swiotlb_buffer.
>>> Call phys_to_dma in xen_phys_to_bus.
>>> Call dma_to_phys in xen_bus_to_phys.
>>>
>>> Everything is taken care of by these changes except for
>>> xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a
>>> few explicit phys_to_dma/dma_to_phys calls.
>>>
>>> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
>>> ---
>>>  drivers/xen/swiotlb-xen.c | 20 ++++++++++++--------
>>>  1 file changed, 12 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
>>> index c50448fd9b75..d011c4c7aa72 100644
>>> --- a/drivers/xen/swiotlb-xen.c
>>> +++ b/drivers/xen/swiotlb-xen.c
>>> @@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr)
>>>  
>>>  	dma |= paddr & ~XEN_PAGE_MASK;
>>>  
>>> -	return dma;
>>> +	return phys_to_dma(dev, dma);
>>>  }
>>>  
>>> -static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr)
>>> +static inline phys_addr_t xen_bus_to_phys(struct device *dev,
>>> +					  dma_addr_t dma_addr)
>>
>> Since now dma address != bus address this is no longer
>> xen_bus_to_phys(). (And I guess the same is rue for xen_phys_to_bus()).
> Should I rename them to xen_dma_to_phys and xen_phys_to_dma?


Yes, please.


-boris



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses
  2020-05-22 18:11       ` Julien Grall
@ 2020-05-22 20:36         ` Stefano Stabellini
  0 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-22 20:36 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk,
	xen-devel, linux-kernel, Stefano Stabellini

On Fri, 22 May 2020, Julien Grall wrote:
> Hi Stefano,
> 
> On 22/05/2020 04:54, Stefano Stabellini wrote:
> > On Thu, 21 May 2020, Julien Grall wrote:
> > > Hi,
> > > 
> > > On 21/05/2020 00:45, Stefano Stabellini wrote:
> > > > From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > > > 
> > > > Don't just assume that virt_to_page works on all virtual addresses.
> > > > Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc
> > > > virt addresses.
> > > 
> > > Can you provide an example where swiotlb is used with vmalloc()?
> > 
> > The issue was reported here happening on the Rasperry Pi 4:
> > https://marc.info/?l=xen-devel&m=158862573216800
> 
> Thanks, it would be good if the commit message contains a bit more details.
> 
> > 
> > If you are asking where in the Linux codebase the vmalloc is happening
> > specifically, I don't know for sure, my information is limited to the
> > stack trace that you see in the link (I don't have a Rasperry Pi 4 yet
> > but I shall have one soon.)
> 
> Looking at the code there is a comment in xen_swiotlb_alloc_coherent()
> suggesting that xen_alloc_coherent_pages() may return an ioremap'ped region on
> Arm. So it feels to me that commit b877ac9815a8fe7e5f6d7fdde3dc34652408840a
> "xen/swiotlb: remember having called xen_create_contiguous_region()" has
> always been broken on Arm.

Yes, I think you are right


> As an aside, your commit message also suggests this is an issue for every
> virtual address used in swiotlb. But only the virt_to_page() call in
> xen_swiotlb_free_coherent() is modified. Is it intended? If yes, I think you
> want to update your commit message.

I see, yes I can explain better


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 02/10] swiotlb-xen: remove start_dma_addr
  2020-05-22 18:16       ` Julien Grall
@ 2020-05-22 20:47         ` Stefano Stabellini
  0 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2020-05-22 20:47 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, jgross, boris.ostrovsky, konrad.wilk,
	xen-devel, linux-kernel, Stefano Stabellini

On Fri, 22 May 2020, Julien Grall wrote:
> On 22/05/2020 04:55, Stefano Stabellini wrote:
> > On Thu, 21 May 2020, Julien Grall wrote:
> > > Hi,
> > > 
> > > On 21/05/2020 00:45, Stefano Stabellini wrote:
> > > > From: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > > > 
> > > > It is not strictly needed. Call virt_to_phys on xen_io_tlb_start
> > > > instead. It will be useful not to have a start_dma_addr around with the
> > > > next patches.
> > > > 
> > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
> > > > ---
> > > >    drivers/xen/swiotlb-xen.c | 5 +----
> > > >    1 file changed, 1 insertion(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> > > > index a42129cba36e..b5e0492b07b9 100644
> > > > --- a/drivers/xen/swiotlb-xen.c
> > > > +++ b/drivers/xen/swiotlb-xen.c
> > > > @@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs;
> > > >     * Quick lookup value of the bus address of the IOTLB.
> > > >     */
> > > >    -static u64 start_dma_addr;
> > > > -
> > > >    /*
> > > >     * Both of these functions should avoid XEN_PFN_PHYS because
> > > > phys_addr_t
> > > >     * can be 32bit when dma_addr_t is 64bit leading to a loss in
> > > > @@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early)
> > > >    		m_ret = XEN_SWIOTLB_EFIXUP;
> > > >    		goto error;
> > > >    	}
> > > > -	start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
> > > >    	if (early) {
> > > >    		if (swiotlb_init_with_tbl(xen_io_tlb_start,
> > > > xen_io_tlb_nslabs,
> > > >    			 verbose))
> > > > @@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device
> > > > *dev, struct page *page,
> > > >    	 */
> > > >    	trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
> > > >    -	map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
> > > > +	map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start),
> > > > phys,
> > > 
> > > xen_virt_to_bus() is implemented as xen_phys_to_bus(virt_to_phys()). Can
> > > you
> > > explain how the two are equivalent?
> > 
> > They are not equivalent. Looking at what swiotlb_tbl_map_single expects,
> > and also the implementation of swiotlb_init_with_tbl, I think
> > virt_to_phys is actually the one we want.
> > 
> > swiotlb_tbl_map_single compares the argument with __pa(tlb) which is
> > __pa(xen_io_tlb_start) which is virt_to_phys(xen_io_tlb_start).
> 
> I can't find such check in master. What is your baseline? Could you point to
> the exact line of code?

My base is b85051e755b0e9d6dd8f17ef1da083851b83287d, which is master
from a couple of days back.


xen_swiotlb_init calls swiotlb_init_with_tbl which takes a virt address
as a parameter (xen_io_tlb_start), it gets converted to phys and stored
in io_tlb_start as a physical address.

Later, xen_swiotlb_map_page calls swiotlb_tbl_map_single passing a
dma addr as parameter (tbl_dma_addr). tbl_dma_addr is used to calculate
the right slot in the swiotlb buffer to use. (Strangely tbl_dma_addr is
a dma_addr_t and it is not converted to phys_addr_t before doing
operations... I think tbl_dma_addr should be a phys addr.)

The comparison with io_tlb_start is done here:

	do {
		while (iommu_is_span_boundary(index, nslots, offset_slots,
					      max_slots)) {
			index += stride;
			if (index >= io_tlb_nslabs)
				index = 0;
			if (index == wrap)
				goto not_found;
		}

index is io_tlb_start and offset_slots is derived by tbl_dma_addr.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/10] fix swiotlb-xen for RPi4
  2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
                   ` (10 preceding siblings ...)
  2020-05-20 23:51 ` [PATCH 00/10] fix swiotlb-xen for RPi4 Roman Shaposhnik
@ 2020-06-02 21:51 ` Stefano Stabellini
  2020-06-03  0:15   ` Boris Ostrovsky
  11 siblings, 1 reply; 31+ messages in thread
From: Stefano Stabellini @ 2020-06-02 21:51 UTC (permalink / raw)
  To: jgross, boris.ostrovsky, konrad.wilk
  Cc: xen-devel, linux-kernel, tamas, roman, sstabellini

I would like to ask the maintainers, Juergen, Boris, Konrad, whether you
have any more feedback before I send v2 of the series.

Cheers,

Stefano


On Wed, 20 May 2020, Stefano Stabellini wrote:
> Hi all,
> 
> This series is a collection of fixes to get Linux running on the RPi4 as
> dom0.
> 
> Conceptually there are only two significant changes:
> 
> - make sure not to call virt_to_page on vmalloc virt addresses (patch
>   #1)
> - use phys_to_dma and dma_to_phys to translate phys to/from dma
>   addresses (all other patches)
> 
> In particular in regards to the second part, the RPi4 is the first
> board where Xen can run that has the property that dma addresses are
> different from physical addresses, and swiotlb-xen was written with the
> assumption that phys addr == dma addr.
> 
> This series adds the phys_to_dma and dma_to_phys calls to make it work.
> 
> 
> Cheers,
> 
> Stefano
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/10] fix swiotlb-xen for RPi4
  2020-06-02 21:51 ` Stefano Stabellini
@ 2020-06-03  0:15   ` Boris Ostrovsky
  0 siblings, 0 replies; 31+ messages in thread
From: Boris Ostrovsky @ 2020-06-03  0:15 UTC (permalink / raw)
  To: Stefano Stabellini, jgross, konrad.wilk
  Cc: xen-devel, linux-kernel, tamas, roman

On 6/2/20 5:51 PM, Stefano Stabellini wrote:
> I would like to ask the maintainers, Juergen, Boris, Konrad, whether you
> have any more feedback before I send v2 of the series.


I think I only had one comment and that's all. Most were from Julien.


-boris


>
> Cheers,
>
> Stefano
>
>
> On Wed, 20 May 2020, Stefano Stabellini wrote:
>> Hi all,
>>
>> This series is a collection of fixes to get Linux running on the RPi4 as
>> dom0.
>>
>> Conceptually there are only two significant changes:
>>
>> - make sure not to call virt_to_page on vmalloc virt addresses (patch
>>   #1)
>> - use phys_to_dma and dma_to_phys to translate phys to/from dma
>>   addresses (all other patches)
>>
>> In particular in regards to the second part, the RPi4 is the first
>> board where Xen can run that has the property that dma addresses are
>> different from physical addresses, and swiotlb-xen was written with the
>> assumption that phys addr == dma addr.
>>
>> This series adds the phys_to_dma and dma_to_phys calls to make it work.
>>
>>
>> Cheers,
>>
>> Stefano
>>


^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2020-06-03  0:15 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-20 23:45 [PATCH 00/10] fix swiotlb-xen for RPi4 Stefano Stabellini
2020-05-20 23:45 ` [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses Stefano Stabellini
2020-05-21  8:01   ` Julien Grall
2020-05-22  3:54     ` Stefano Stabellini
2020-05-22 18:11       ` Julien Grall
2020-05-22 20:36         ` Stefano Stabellini
2020-05-20 23:45 ` [PATCH 02/10] swiotlb-xen: remove start_dma_addr Stefano Stabellini
2020-05-21  8:05   ` Julien Grall
2020-05-22  3:55     ` Stefano Stabellini
2020-05-22 18:16       ` Julien Grall
2020-05-22 20:47         ` Stefano Stabellini
2020-05-20 23:45 ` [PATCH 03/10] swiotlb-xen: add struct device* parameter to xen_phys_to_bus Stefano Stabellini
2020-05-20 23:45 ` [PATCH 04/10] swiotlb-xen: add struct device* parameter to xen_bus_to_phys Stefano Stabellini
2020-05-20 23:45 ` [PATCH 05/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_cpu Stefano Stabellini
2020-05-20 23:45 ` [PATCH 06/10] swiotlb-xen: add struct device* parameter to xen_dma_sync_for_device Stefano Stabellini
2020-05-20 23:45 ` [PATCH 07/10] swiotlb-xen: add struct device* parameter to is_xen_swiotlb_buffer Stefano Stabellini
2020-05-20 23:45 ` [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys translations Stefano Stabellini
2020-05-21  8:07   ` Julien Grall
2020-05-21 22:59   ` Boris Ostrovsky
2020-05-22 17:34     ` Stefano Stabellini
2020-05-22 18:29       ` Boris Ostrovsky
2020-05-20 23:45 ` [PATCH 09/10] xen/arm: introduce phys/dma translations in xen_dma_sync_for_* Stefano Stabellini
2020-05-21  8:18   ` Julien Grall
2020-05-21 20:08     ` Stefano Stabellini
2020-05-21 20:17       ` Julien Grall
2020-05-20 23:45 ` [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter of dma_cache_maint Stefano Stabellini
2020-05-21  8:25   ` Julien Grall
2020-05-20 23:51 ` [PATCH 00/10] fix swiotlb-xen for RPi4 Roman Shaposhnik
2020-05-20 23:56   ` Stefano Stabellini
2020-06-02 21:51 ` Stefano Stabellini
2020-06-03  0:15   ` Boris Ostrovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).