From 498e47cd1d1f3e0a870a29d1b28093e64db52fd2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 27 Mar 2024 09:48:47 -0700 Subject: [PATCH] Fix build errors due to new UIO_MEM_DMA_COHERENT mess 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 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 Cc: Chris Leech Cc: Nilesh Javali Cc: Christoph Hellwig Signed-off-by: Linus Torvalds --- drivers/uio/uio.c | 2 +- drivers/uio/uio_dmem_genirq.c | 4 ++-- drivers/uio/uio_pruss.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index bb77de6fa067..009158fef2a8 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -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, diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index d5f9384df125..13cc35ab5d29 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -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; diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index 72b33f7d4c40..f67881cba645 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -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;