Skip to contentSkip to conversation

Unable to map uncached buffer for PCI DMA to userspace on Cortex-A53

DISCUSSION Mike Campin 1 participant 1 message Oct 7, 2019

lore
Share & tools
lore
#0 lore raw

I've been trying for several days to map an uncached buffer for PCI DMA in userspace without luck. The only way I can get the DMA transfer to work is to wrap it with __builtin___clear_cache().

Details.
- 96boards SC2A11 with Cortex-A53 with my device plugged into a PCIe slot.
- Kernel 5.2.13-200.fc30.aarch64 (Fedora 30).
- /proc/cmdline

      BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.2.13-200.fc30.aarch64 root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap
  - Simplified code:
      init_dma_attrs(&attrs);
      dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS,  &attrs);
      dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
      dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
      vaddr = dma_alloc_attrs(dev, size, &iaddr, GFP_KERNEL | __GFP_ZERO, &attrs);
 
      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
      dma_mmap_attrs(dev, vma, vaddr, iaddr, size, &attrs);

I've tried several permutations. Here's a few examples:
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- vma->vm_flags |= VM_IO;
- With and without DMA_ATTR_NO_KERNEL_MAPPING.
- remap_pfn_range(vma, vma->vm_start, iaddr >> PAGE_SHIFT, size, vma->vm_page_prot);
- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
- Even tried using get_arch_dma_ops() to get a pointer to arm_dma_ops.

Signature · 7 lines
Mike Campin
arm at timequake dot net

_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel