DMA into nVIDIA allocated pinned memory

We want to execute DMA from our FG (frame grabber card) into NVIDIA driver allocated pinned memory. That is, the user space program ask the driver to allocate such pinned memory, get the virtual pointer to this memory and pass it into FG device driver. All I need to do is to get physical address of this pointer, to fill scatter-gather table (in case the of non contiguous phys memory) and start DMA.

I try to get physical address of this virtual pointer by using get_user_pages. It failed with -14 (-EFAULT) return code. The reason to failure is VM_IO or VM_RESERVES flags of vm_area_struct that this virtual pointer belongs to (It generally means, that the mmaped meory is IO memory or driver alloacated memory). The question is how I can get a physical address of virtual pointer that points to NVIDIA allocated pinned memory?

The user space programm:

cl_mem cmPinnedBufIn  = clCreateBuffer(clCtx, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, ImgSize_ub, NULL, &ciErrNum); 
clf_CheckError(ciErrNum, CL_SUCCESS);

// Get mapped pointers for writing to pinned input and output host image pointers 
unsigned char *h_I = (unsigned char*)clEnqueueMapBuffer(clCommandQueue, cmPinnedBufIn , CL_TRUE, CL_MAP_WRITE, 0, ImgSize_ub, 0, NULL, NULL, &ciErrNum);
clf_CheckError(ciErrNum, CL_SUCCESS);

    // Pass pointer to pinned memory to FG driver
device.setUserAllocatedBuffer(h_I, ImgSize_ub);

The FG driver setUserAllocatedBuffer ioctl implementation:

down_read(&current->mm->mmap_sem) ;

// Just to get vm area flags
vma = find_vma(current->mm, user_buffer.virt_address);
if (vma) {
vm_io = vma->vm_flags & VM_IO;
vm_reserved = vma->vm_flags & VM_RESERVED;
printk(KERN_ERR "MVC:  VM_IO - %d VM_RESERVED - %d \n", vm_io, vm_reserved);
}

int ret;
ret = [b]get_user_pages[/b](current, current->mm, first_page_start, npages, 1, 0, pages, NULL);

if ( npages < 0) {
printk(KERN_ERR ": get_user_page() returned with error %d \n", -ret);
kfree(pages);
    return -EFAULT ;
}

if( npages != ret) {
printk(KERN_ERR "num of pages less than requested -  %d\n", ret);
kfree(pages);
    return -EFAULT ;
    
}
up_read(&current->mm->mmap_sem) ;

I’m having a similar problem, did you find a solution?

Thanks,

Pepe