Message ID | 20200507005647.172515-1-gavinli@thegavinli.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] usb: devio: fix mmap() on non-coherent DMA architectures | expand |
Resubmitting this patch from a few months ago now that the "x86/PAT: ... map pfn RAM range req uncached-minus" warning mentioned earlier seems to have been fixed. On Wed, May 6, 2020 at 5:57 PM <gavinli@thegavinli.com> wrote: > > From: Gavin Li <gavinli@thegavinli.com> > > On architectures that are not (or are optionally) DMA coherent, > dma_alloc_coherent() returns an address into the vmalloc space, > and calling virt_to_phys() on this address returns an unusable > physical address. > > This patch replaces the raw remap_pfn_range() call with a call to > dmap_mmap_coherent(), which takes care of the differences between > coherent and non-coherent code paths. > > Tested on an arm64 rk3399 board. > --- > drivers/usb/core/devio.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c > index 6833c918abce..9d0043dd8e64 100644 > --- a/drivers/usb/core/devio.c > +++ b/drivers/usb/core/devio.c > @@ -250,11 +250,10 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) > usbm->vma_use_count = 1; > INIT_LIST_HEAD(&usbm->memlist); > > - if (remap_pfn_range(vma, vma->vm_start, > - virt_to_phys(usbm->mem) >> PAGE_SHIFT, > - size, vma->vm_page_prot) < 0) { > + ret = dma_mmap_coherent(ps->dev->bus->sysdev, vma, mem, dma_handle, size); > + if (ret) { > dec_usb_memory_use_count(usbm, &usbm->vma_use_count); > - return -EAGAIN; > + return ret; > } > > vma->vm_flags |= VM_IO; > -- > 2.26.2 >
On Wed, May 06, 2020 at 05:56:47PM -0700, gavinli@thegavinli.com wrote: > From: Gavin Li <gavinli@thegavinli.com> > > On architectures that are not (or are optionally) DMA coherent, > dma_alloc_coherent() returns an address into the vmalloc space, > and calling virt_to_phys() on this address returns an unusable > physical address. > > This patch replaces the raw remap_pfn_range() call with a call to > dmap_mmap_coherent(), which takes care of the differences between > coherent and non-coherent code paths. > > Tested on an arm64 rk3399 board. > --- > drivers/usb/core/devio.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) I don't think you ran checkpatch.pl on your patch :( Also, please see 2bef9aed6f0e ("usb: usbfs: correct kernel->user page attribute mismatch") in linux-next, does that resolve this problem for you? I think it does the same thing as your patch does... thanks, greg k-h
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6833c918abce..9d0043dd8e64 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -250,11 +250,10 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) usbm->vma_use_count = 1; INIT_LIST_HEAD(&usbm->memlist); - if (remap_pfn_range(vma, vma->vm_start, - virt_to_phys(usbm->mem) >> PAGE_SHIFT, - size, vma->vm_page_prot) < 0) { + ret = dma_mmap_coherent(ps->dev->bus->sysdev, vma, mem, dma_handle, size); + if (ret) { dec_usb_memory_use_count(usbm, &usbm->vma_use_count); - return -EAGAIN; + return ret; } vma->vm_flags |= VM_IO;
From: Gavin Li <gavinli@thegavinli.com> On architectures that are not (or are optionally) DMA coherent, dma_alloc_coherent() returns an address into the vmalloc space, and calling virt_to_phys() on this address returns an unusable physical address. This patch replaces the raw remap_pfn_range() call with a call to dmap_mmap_coherent(), which takes care of the differences between coherent and non-coherent code paths. Tested on an arm64 rk3399 board. --- drivers/usb/core/devio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)