[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] swiotlb-xen question



On Tue, 1 Apr 2014, Oleksandr Dmytryshyn wrote:
> Hi to all. I've investigated my issue deeper.
> 
> Currently we use mmap in 2 cases: video-in (camera) and video-out (display).
> 
> In case video-out all is working because mmap callback in the video-out device
> leads to the remap_pfn_range() function (this function doesn't use 
> unimplemented
> .mmap callback in the swiotlb-xen.c file).
> 
> In case video-out mmap callback in the video-in device leads to the .mmap
> callback from the dma ops (unimplemented callback in the swiotlb-xen.c file)
> 
> I've investigated kernel code. We have patch from the Stefano Stabellini
> (068a6e62 - arm/xen: get_dma_ops: return xen_dma_ops if we are running as
> xen_initial_domain)
> 
> Before this patch the function *get_dma_ops() always returned
> __generic_dma_ops()
> which returned &arm_dma_ops (if archdata.dma_ops is absent). In this case
> for arm architecture .mmap callback is arm_dma_mmap() function.
> 
> After this patch for domU all is the same as before this patch. But in case
> dom0 kernel uses xen_dma_ops with unimplemented .mmap callback. If some
> function tries to use .mmap callback in dom0 then kernel calls generic
> function dma_common_mmap() which doesn't work properly.
> 
> May be some mechanism for swiotlb-xen should be implemented for unimplemented
> callbacks: if callback is not implemented then right architectural callback
> should be used (.mmap - arm_dma_mmap() for ARM)?

I understand now. Thanks for investingating!
I think that we'll have to introduce our own version of .mmap,
because dma_to_pfn doesn't work correctly on Xen on ARM.
The implementation would be something like (untested):

int xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma,
                 void *cpu_addr, dma_addr_t dma_addr, size_t size,
                 struct dma_attrs *attrs)
{
        int ret = -ENXIO;
#ifdef CONFIG_MMU
        unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> 
PAGE_SHIFT;
        unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
        unsigned long pfn = PFN_DOWN(xen_bus_to_phys(dev, dma_addr));
        unsigned long off = vma->vm_pgoff;

        vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);

        if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
                return ret;

        if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
                ret = remap_pfn_range(vma, vma->vm_start,
                                      pfn + off,
                                      vma->vm_end - vma->vm_start,
                                      vma->vm_page_prot);
        }
#endif  /* CONFIG_MMU */

        return ret;
}

then we can add the function to xen_swiotlb_dma_ops.
Would you be up for coming up with a proper patch?

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.