Librtlsdr zerocopy buffers not working on Tinkerboard Armbian

Steve Markgraf steve at
Tue Oct 9 19:21:13 UTC 2018


so it turned out that this is indeed a Kernel issue. I have implemented
a crude workaround for both rtl-sdr and osmo-fl2k to detect the bug, and
fall back to buffers in userspace if it is present.

I've sent the mail below to the linux-usb list, but didn't get any reply
so far. Let's see.

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
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

Best Regards,
Steve Markgraf

More information about the osmocom-sdr mailing list