From: Jeremy Linton <jeremy.linton@arm.com> To: linux-usb@vger.kernel.org Cc: gregkh@linuxfoundation.org, stern@rowland.harvard.edu, git@thegavinli.com, jarkko.sakkinen@linux.intel.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, maz@kernel.org, robin.murphy@arm.com, Jeremy Linton <jeremy.linton@arm.com> Subject: [PATCH v2] usb: usbfs: correct kernel->user page attribute mismatch Date: Mon, 4 May 2020 15:13:48 -0500 [thread overview] Message-ID: <20200504201348.1183246-1-jeremy.linton@arm.com> (raw) On some architectures (e.g. arm64) requests for IO coherent memory may use non-cachable attributes if the relevant device isn't cache coherent. If these pages are then remapped into userspace as cacheable, they may not be coherent with the non-cacheable mappings. In particular this happens with libusb, when it attempts to create zero-copy buffers for use by rtl-sdr (https://github.com/osmocom/rtl-sdr/). On low end arm devices with non-coherent USB ports, the application will be unexpectedly killed, while continuing to work fine on arm machines with coherent USB controllers. This bug has been discovered/reported a few times over the last few years. In the case of rtl-sdr a compile time option to enable/disable zero copy was implemented to work around it. Rather than relaying on application specific workarounds, dma_mmap_coherent() can be used instead of remap_pfn_range(). The page cache/etc attributes will then be correctly set in userspace to match the kernel mapping. Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> --- v1->v2: Update commit message and change to dma_mmap_coherent() from dma_mmap_attr(,,,0) which are the same. drivers/usb/core/devio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6833c918abce..b9db9812d6c5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) { struct usb_memory *usbm = NULL; struct usb_dev_state *ps = file->private_data; + struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); size_t size = vma->vm_end - vma->vm_start; void *mem; unsigned long flags; @@ -250,9 +251,7 @@ 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) { + if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { dec_usb_memory_use_count(usbm, &usbm->vma_use_count); return -EAGAIN; } -- 2.24.1
WARNING: multiple messages have this Message-ID (diff)
From: Jeremy Linton <jeremy.linton@arm.com> To: linux-usb@vger.kernel.org Cc: mark.rutland@arm.com, git@thegavinli.com, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, jarkko.sakkinen@linux.intel.com, stern@rowland.harvard.edu, Jeremy Linton <jeremy.linton@arm.com>, maz@kernel.org, robin.murphy@arm.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH v2] usb: usbfs: correct kernel->user page attribute mismatch Date: Mon, 4 May 2020 15:13:48 -0500 [thread overview] Message-ID: <20200504201348.1183246-1-jeremy.linton@arm.com> (raw) On some architectures (e.g. arm64) requests for IO coherent memory may use non-cachable attributes if the relevant device isn't cache coherent. If these pages are then remapped into userspace as cacheable, they may not be coherent with the non-cacheable mappings. In particular this happens with libusb, when it attempts to create zero-copy buffers for use by rtl-sdr (https://github.com/osmocom/rtl-sdr/). On low end arm devices with non-coherent USB ports, the application will be unexpectedly killed, while continuing to work fine on arm machines with coherent USB controllers. This bug has been discovered/reported a few times over the last few years. In the case of rtl-sdr a compile time option to enable/disable zero copy was implemented to work around it. Rather than relaying on application specific workarounds, dma_mmap_coherent() can be used instead of remap_pfn_range(). The page cache/etc attributes will then be correctly set in userspace to match the kernel mapping. Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> --- v1->v2: Update commit message and change to dma_mmap_coherent() from dma_mmap_attr(,,,0) which are the same. drivers/usb/core/devio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6833c918abce..b9db9812d6c5 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) { struct usb_memory *usbm = NULL; struct usb_dev_state *ps = file->private_data; + struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); size_t size = vma->vm_end - vma->vm_start; void *mem; unsigned long flags; @@ -250,9 +251,7 @@ 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) { + if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { dec_usb_memory_use_count(usbm, &usbm->vma_use_count); return -EAGAIN; } -- 2.24.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next reply other threads:[~2020-05-04 20:14 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-05-04 20:13 Jeremy Linton [this message] 2020-05-04 20:13 ` [PATCH v2] usb: usbfs: correct kernel->user page attribute mismatch Jeremy Linton 2020-05-06 7:51 ` Peter Chen 2020-05-06 7:51 ` Peter Chen
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200504201348.1183246-1-jeremy.linton@arm.com \ --to=jeremy.linton@arm.com \ --cc=git@thegavinli.com \ --cc=gregkh@linuxfoundation.org \ --cc=jarkko.sakkinen@linux.intel.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-usb@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=maz@kernel.org \ --cc=robin.murphy@arm.com \ --cc=stern@rowland.harvard.edu \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.