[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v1 3/9] parisc: Convert DMA map_page to map_phys interface
On Fri, Oct 03, 2025 at 12:01:44PM -0300, Jason Gunthorpe wrote: > On Sun, Sep 28, 2025 at 06:02:23PM +0300, Leon Romanovsky wrote: > > +ccio_map_phys(struct device *dev, phys_addr_t phys, size_t size, > > + enum dma_data_direction direction, unsigned long attrs) > > { > > - return ccio_map_single(dev, page_address(page) + offset, size, > > - direction); > > + if (attrs & DMA_ATTR_MMIO) > > + return DMA_MAPPING_ERROR; > > + > > + return ccio_map_single(dev, phys_to_virt(phys), size, direction); > > This doesn't actually use the virt at all: > > offset = ((unsigned long) addr) & ~IOVP_MASK; > if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES)) > ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned > long)addr, hint); > > And ccio_io_pdir_entry(): > pa = lpa(vba); > > Is a special instruction that uses virt but AI tells me that special > LPA instruction is returning phys. Not sure if that is a different > value than virt_to_phys().. > > IDK, I'm not feeling brave enough to drop the LPA but maybe include > this note in the commit message. > It looks like I was chosen as a volunteer to do so. WDYT? diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index b00f6fc49063..4d73e67fbd54 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -517,10 +517,10 @@ static u32 hint_lookup[] = { * ccio_io_pdir_entry - Initialize an I/O Pdir. * @pdir_ptr: A pointer into I/O Pdir. * @sid: The Space Identifier. - * @vba: The virtual address. + * @pba: The physical address. * @hints: The DMA Hint. * - * Given a virtual address (vba, arg2) and space id, (sid, arg1), + * Given a physical address (pba, arg2) and space id, (sid, arg1), * load the I/O PDIR entry pointed to by pdir_ptr (arg0). Each IO Pdir * entry consists of 8 bytes as shown below (MSB == bit 0): * @@ -543,7 +543,7 @@ static u32 hint_lookup[] = { * index are bits 12:19 of the value returned by LCI. */ static void -ccio_io_pdir_entry(__le64 *pdir_ptr, space_t sid, unsigned long vba, +ccio_io_pdir_entry(__le64 *pdir_ptr, space_t sid, phys_addr_t pba, unsigned long hints) { register unsigned long pa; @@ -557,7 +557,7 @@ ccio_io_pdir_entry(__le64 *pdir_ptr, space_t sid, unsigned long vba, ** "hints" parm includes the VALID bit! ** "dep" clobbers the physical address offset bits as well. */ - pa = lpa(vba); + pa = pba; asm volatile("depw %1,31,12,%0" : "+r" (pa) : "r" (hints)); ((u32 *)pdir_ptr)[1] = (u32) pa; @@ -582,7 +582,7 @@ ccio_io_pdir_entry(__le64 *pdir_ptr, space_t sid, unsigned long vba, ** Grab virtual index [0:11] ** Deposit virt_idx bits into I/O PDIR word */ - asm volatile ("lci %%r0(%1), %0" : "=r" (ci) : "r" (vba)); + asm volatile ("lci %%r0(%1), %0" : "=r" (ci) : "r" (pba)); asm volatile ("extru %1,19,12,%0" : "+r" (ci) : "r" (ci)); asm volatile ("depw %1,15,12,%0" : "+r" (pa) : "r" (ci)); @@ -704,14 +704,14 @@ ccio_dma_supported(struct device *dev, u64 mask) /** * ccio_map_single - Map an address range into the IOMMU. * @dev: The PCI device. - * @addr: The start address of the DMA region. + * @addr: The physical address of the DMA region. * @size: The length of the DMA region. * @direction: The direction of the DMA transaction (to/from device). * * This function implements the pci_map_single function. */ static dma_addr_t -ccio_map_single(struct device *dev, void *addr, size_t size, +ccio_map_single(struct device *dev, phys_addr_t addr, size_t size, enum dma_data_direction direction) { int idx; @@ -730,7 +730,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, BUG_ON(size <= 0); /* save offset bits */ - offset = ((unsigned long) addr) & ~IOVP_MASK; + offset = offset_in_page(addr); /* round up to nearest IOVP_SIZE */ size = ALIGN(size + offset, IOVP_SIZE); @@ -746,15 +746,15 @@ ccio_map_single(struct device *dev, void *addr, size_t size, pdir_start = &(ioc->pdir_base[idx]); - DBG_RUN("%s() %px -> %#lx size: %zu\n", - __func__, addr, (long)(iovp | offset), size); + DBG_RUN("%s() %pa -> %#lx size: %zu\n", + __func__, &addr, (long)(iovp | offset), size); /* If not cacheline aligned, force SAFE_DMA on the whole mess */ - if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES)) + if((size % L1_CACHE_BYTES) || (addr % L1_CACHE_BYTES)) hint |= HINT_SAFE_DMA; while(size > 0) { - ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long)addr, hint); + ccio_io_pdir_entry(pdir_start, KERNEL_SPACE, addr, hint); DBG_RUN(" pdir %p %08x%08x\n", pdir_start, @@ -779,7 +779,7 @@ ccio_map_phys(struct device *dev, phys_addr_t phys, size_t size, if (unlikely(attrs & DMA_ATTR_MMIO)) return DMA_MAPPING_ERROR; - return ccio_map_single(dev, phys_to_virt(phys), size, direction); + return ccio_map_single(dev, phys, size, direction); } @@ -854,7 +854,8 @@ ccio_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag, if (ret) { memset(ret, 0, size); - *dma_handle = ccio_map_single(dev, ret, size, DMA_BIDIRECTIONAL); + *dma_handle = ccio_map_single(dev, virt_to_phys(ret), size, + DMA_BIDIRECTIONAL); } return ret; @@ -921,7 +922,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, /* Fast path single entry scatterlists. */ if (nents == 1) { sg_dma_address(sglist) = ccio_map_single(dev, - sg_virt(sglist), sglist->length, + sg_phys(sglist), sglist->length, direction); sg_dma_len(sglist) = sglist->length; return 1; > > Jason >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |