2

I'm adding IOMMU support in my linux driver and notice the IOMMU groups are assigned to the device during boot:

[ 0.942274] iommu: Adding device 0000:03:00.0 to group 28

Although, when I try to iommu_attach_device() inside the driver, it fails. I found it's failing when it calls iommu_group_get() for my device.

How do I get the assigned group for my device and use it inside my driver?
I'm using Ubuntu 4.15.0-45-generic kernel.

Edit:
iommu_group_get() fails when struct device field iommu_group is not initialized. Also, I'm manually loading the driver after boot.

Edit2: I do see the device added to group 28 in dmesg output. I've the following sequence in my driver probe routine which I got by referring to existing kernel driver sources:

if iommu_present()
    iommu_domain_alloc(&pci_bus_type) 
    iommu_set_fault_handler() 
    group = iommu_group_get(); 
    // added group check since iommu_attach_device is failing 
    // group is NULL, was expecting group_28 
    iommu_attach_device() 
    init_iova_domain() 

I've IOCTL calls for pinning the userspace virtual address (get_user_pages_fast) and performing iommu_map. Is this valid for enabling DMA to the device using userspace region?

JustCoding
  • 21
  • 1
  • 4
  • Which platform you are on? Attaching to iommu is typically not driver's job but platform's. For device tree based platform, you should device iommu setup in device tree. – Nikita Yushchenko Feb 23 '19 at 15:56
  • @NikitaYushchenko I'm using Ubuntu 18.04.1. Yes, I do see the device added to `group 28` in `dmesg` output. I've the following sequence in my driver probe routine which I got by referring to existing kernel driver sources: ``` if iommu_present() iommu_domain_alloc(&pci_bus_type) iommu_set_fault_handler() group = iommu_group_get(); // added group check since iommu_attach_device is failing // group is NULL, was expecting group_28 iommu_attach_device() init_iova_domain() ``` – JustCoding Feb 24 '19 at 07:48
  • @NikitaYushchenko I've IOCTL calls for pinning the userspace virtual address (`get_user_pages_fast`) and performing `iommu_map`. The goal is to use this mapped space for DMA to device memory. – JustCoding Feb 24 '19 at 07:48
  • You do not need to explicitly bother with iommu. Just get pages, convert to scatterlist, dma_map_sg() and run you DMA. Platform will set up iommu transparently for you. – Nikita Yushchenko Feb 24 '19 at 19:00
  • I am trying to do a direct DMA from the user allocated space to device. So, I want to setup iommu with a contiguous view of the DMA'able space for the device. – JustCoding Feb 25 '19 at 03:24
  • To do that, just pin pages (get_user_pages*()), dma-map them (dma_map_sg()), and run DMA. Setting up iommu is not your driver's job. – Nikita Yushchenko Feb 25 '19 at 04:32
  • Platform will set up iommu for you, that will happen inside dma_map_sg(). – Nikita Yushchenko Feb 25 '19 at 04:33
  • Thanks, I'll try your suggestion. – JustCoding Feb 25 '19 at 05:32
  • Nikita, dma_map_sg in my case hangs the system with crash trace pointing to `intel_map_sg() -> domain_get_iommu()`. I'm using the following sequence: `get_user_pages_fast() ; sg_alloc_table_from_pages() ; dma_map_sg()`. – JustCoding Dec 03 '19 at 09:45
  • Please post your entire source code and complete crash log. – Nikita Yushchenko Dec 04 '19 at 18:45

0 Answers0