Fix build errors due to new UIO_MEM_DMA_COHERENT mess
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Mar 2024 16:48:47 +0000 (09:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Mar 2024 16:48:47 +0000 (09:48 -0700)
Commit 576882ef5e7f ("uio: introduce UIO_MEM_DMA_COHERENT type")
introduced a new use-case for 'struct uio_mem' where the 'mem' field now
contains a kernel virtual address when 'memtype' is set to
UIO_MEM_DMA_COHERENT.

That in turn causes build errors, because 'mem' is of type
'phys_addr_t', and a virtual address is a pointer type.  When the code
just blindly uses cast to mix the two, it caused problems when
phys_addr_t isn't the same size as a pointer - notably on 32-bit
architectures with PHYS_ADDR_T_64BIT.

The proper thing to do would probably be to use a union member, and not
have any casts, and make the 'mem' member be a union of 'mem.physaddr'
and 'mem.vaddr', based on 'memtype'.

This is not that proper thing.  This is just fixing the ugly casts to be
even uglier, but at least not cause build errors on 32-bit platforms
with 64-bit physical addresses.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Fixes: 576882ef5e7f ("uio: introduce UIO_MEM_DMA_COHERENT type")
Fixes: 7722151e4651 ("uio_pruss: UIO_MEM_DMA_COHERENT conversion")
Fixes: 019947805a8d ("uio_dmem_genirq: UIO_MEM_DMA_COHERENT conversion")
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Chris Leech <cleech@redhat.com>
Cc: Nilesh Javali <njavali@marvell.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Linus Torvalds <torvalds@linuxfoundation.org>
drivers/uio/uio.c
drivers/uio/uio_dmem_genirq.c
drivers/uio/uio_pruss.c

index bb77de6fa067efe26280b24b0f62b54ba75bcbca..009158fef2a8f1ed82fb3fb7a4c4a9b5764e723b 100644 (file)
@@ -792,7 +792,7 @@ static int uio_mmap_dma_coherent(struct vm_area_struct *vma)
         */
        vma->vm_pgoff = 0;
 
-       addr = (void *)mem->addr;
+       addr = (void *)(uintptr_t)mem->addr;
        ret = dma_mmap_coherent(mem->dma_device,
                                vma,
                                addr,
index d5f9384df1255f241d27c80ae4cd40be8d1d2609..13cc35ab5d29a7ddc079883b8a853387fcdad63e 100644 (file)
@@ -60,7 +60,7 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode)
 
                addr = dma_alloc_coherent(&priv->pdev->dev, uiomem->size,
                                          &uiomem->dma_addr, GFP_KERNEL);
-               uiomem->addr = addr ? (phys_addr_t) addr : DMEM_MAP_ERROR;
+               uiomem->addr = addr ? (uintptr_t) addr : DMEM_MAP_ERROR;
                ++uiomem;
        }
        priv->refcnt++;
@@ -89,7 +89,7 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode)
                        break;
                if (uiomem->addr) {
                        dma_free_coherent(uiomem->dma_device, uiomem->size,
-                                         (void *) uiomem->addr,
+                                         (void *) (uintptr_t) uiomem->addr,
                                          uiomem->dma_addr);
                }
                uiomem->addr = DMEM_MAP_ERROR;
index 72b33f7d4c40fcc44bce35962a9b1ec6c2fc7701..f67881cba645ba3d68b8d1023e8008c1920a1e50 100644 (file)
@@ -191,7 +191,7 @@ static int pruss_probe(struct platform_device *pdev)
                p->mem[1].size = sram_pool_sz;
                p->mem[1].memtype = UIO_MEM_PHYS;
 
-               p->mem[2].addr = (phys_addr_t) gdev->ddr_vaddr;
+               p->mem[2].addr = (uintptr_t) gdev->ddr_vaddr;
                p->mem[2].dma_addr = gdev->ddr_paddr;
                p->mem[2].size = extram_pool_sz;
                p->mem[2].memtype = UIO_MEM_DMA_COHERENT;