On Sun, 7 Oct 2018, Steve Markgraf wrote:
> Hi,
>
> I'm the author of a userspace library that makes use of the usbfs
> zerocopy-feature via libusb-1.0, and recently received a bug report that
> garbage data is received with bulk transfers on ARM-based systems.
>
> When I debugged the issue, I found out that the Kernel maps seemingly
> random memory to my transfer buffers, containing memory of other
> processes or even the Kernel itself.
>
> The code that does the mapping in drivers/usb/core/devio.c:
> (line 243 in v4.19-rc7)
>
> > if (remap_pfn_range(vma, vma->vm_start,
> > virt_to_phys(usbm->mem) >> PAGE_SHIFT,
> > size, vma->vm_page_prot) < 0) {
>
> With the following change the issue is fixed for ARM systems, but it
> breaks x86 systems:
>
> - virt_to_phys(usbm->mem) >> PAGE_SHIFT,
> + page_to_pfn(virt_to_page(dma_addr)),
>
> Both usbm->mem and dma_addr are returned by the previous call to
> usb_alloc_coherent().
> Here's an example of the pointers generated by the two macros on an
> ARM64 system for the same buffer:
>
> virt_to_phys(usbm->mem) >> PAGE_SHIFT: 00000000808693ce
> page_to_pfn(virt_to_page(dma_addr)): 000000009775a856
>
> From what I read so far I got the impression that the 'proper' way would
> be to use dma_mmap_coherent() with dma_addr instead of
> remap_pfn_range(), however, I did not get it to work. Can anyone help
> out?
This is question is more about the kernel's architecture-specific
design than about USB. You should ask on the
[email protected], [email protected], and
[email protected] mailing lists.
Alan Stern