Thread (34 messages) 34 messages, 7 authors, 2025-10-06

Re: [PATCH v1 5/9] sparc64: Use physical address DMA mapping

From: Jason Gunthorpe <jgg@nvidia.com>
Date: 2025-10-03 15:16:16
Also in: linux-alpha, linux-iommu, linux-mips, lkml, sparclinux, virtualization, xen-devel

On Sun, Sep 28, 2025 at 06:02:25PM +0300, Leon Romanovsky wrote:
quoted hunk ↗ jump to hunk
@@ -273,13 +272,16 @@ static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page,
 	u32 bus_addr, ret;
 	unsigned long iopte_protection;
 
+	if (attrs & DMA_ATTR_MMIO)
+		goto bad_no_ctx;
+
 	iommu = dev->archdata.iommu;
 	strbuf = dev->archdata.stc;
 
 	if (unlikely(direction == DMA_NONE))
 		goto bad_no_ctx;
 
-	oaddr = (unsigned long)(page_address(page) + offset);
+	oaddr = (unsigned long)(phys_to_virt(phys));
 	npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
 	npages >>= IO_PAGE_SHIFT;
This should be cleaned up some more:

	oaddr = (unsigned long)(page_address(page) + offset);
	ret = bus_addr | (oaddr & ~IO_PAGE_MASK);

	base_paddr = __pa(oaddr & IO_PAGE_MASK);

Makes no sense to phys_to_virt() then __pa() on that result. Drop oaddr.

Then I would copy and paste the comment from mips about DMA_ATTR_MMIO
quoted hunk ↗ jump to hunk
@@ -367,13 +366,16 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page,
 	dma_addr_t bus_addr, ret;
 	long entry;
 
+	if (attrs & DMA_ATTR_MMIO)
+		goto bad;
+
 	iommu = dev->archdata.iommu;
 	atu = iommu->atu;
 
 	if (unlikely(direction == DMA_NONE))
 		goto bad;
 
-	oaddr = (unsigned long)(page_address(page) + offset);
+	oaddr = (unsigned long)(phys_to_virt(phys));
 	npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
 	npages >>= IO_PAGE_SHIFT;
Same remarks here
+static dma_addr_t iounit_map_phys(struct device *dev, phys_addr_t phys,
+		size_t len, enum dma_data_direction dir, unsigned long attrs)
 {
-	void *vaddr = page_address(page) + offset;
+	void *vaddr = phys_to_virt(phys);
 	struct iounit_struct *iounit = dev->archdata.iommu;
 	unsigned long ret, flags;
iounit_get_area() does not seem to need vaddr:

        npages = ((vaddr & ~PAGE_MASK) + size + (PAGE_SIZE-1)) >> PAGE_SHIFT;

~PAGE_MASK is page_offset()

	iopte = MKIOPTE(__pa(vaddr & PAGE_MASK));

__pa(phys_to_virt(pa)) again:
  iopte = MKIOPTE(PAGE_ALIGN(pa));

	vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK);

page_offset, then it replaces vaddr.

So I'd tidy this too.
quoted hunk ↗ jump to hunk
@@ -202,10 +204,10 @@ static dma_addr_t __sbus_iommu_map_page(struct device *dev, struct page *page,
 * We expect unmapped highmem pages to be not in the cache.
 	 * XXX Is this a good assumption?
 	 * XXX What if someone else unmaps it here and races us?
 	 */
At least ARM32 has code that seems to say these assumptions are not
always true.. Oh well.

Jason
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help