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

Re: [Xen-devel] swiotlb-xen question



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

Oleksandr Dmytryshyn | Product Engineering and Development
GlobalLogic
M +38.067.382.2525
www.globallogic.com

http://www.globallogic.com/email_disclaimer.txt


On Thu, Mar 27, 2014 at 12:11 PM, Oleksandr Dmytryshyn
<oleksandr.dmytryshyn@xxxxxxxxxxxxxxx> wrote:
> Hi, Stefano.
>
> Thank You for advice.
>
> I'll try this few days later.
>
> Oleksandr Dmytryshyn | Product Engineering and Development
> GlobalLogic
> M +38.067.382.2525
> www.globallogic.com
>
> http://www.globallogic.com/email_disclaimer.txt
>
>
> On Wed, Mar 26, 2014 at 8:49 PM, Stefano Stabellini
> <stefano.stabellini@xxxxxxxxxxxxx> wrote:
>> On Wed, 26 Mar 2014, Oleksandr Dmytryshyn wrote:
>>> On Wed, Mar 26, 2014 at 4:46 PM, Konrad Rzeszutek Wilk
>>> <konrad.wilk@xxxxxxxxxx> wrote:
>>> > On Wed, Mar 26, 2014 at 12:35:12PM +0200, Oleksandr Dmytryshyn wrote:
>>> >> Hi to all.
>>> >>
>>> >> Currently I'm using hypervisor on ARM Cortex A15 processor (DRA7xx
>>> >> Jacinto 6 processor). I'm using mainline xen 4.4 with some patches on
>>> >> top plus dom0 and domU linux kernel 3.8.
>>> >>
>>> >> I've written a hack to make a camera working on my board in dom0
>>> >> (drivers for camera and display system are in dom0). An user-space
>>> >> application in dom0 is used to test camera (it reads camera captured
>>> >> data and sends it to the framebuffer). In the kernel code I've 
>>> >> implemented
>>> >> .mmap callback function in the swiotlb-xen.c file (like 
>>> >> xen_swiotlb_mmap())
>>> >> and copied to this new callback all content from the original function
>>> >> 'arm_dma_mmap()' from the kernel. This function creates userspace
>>> >> mapping for the DMA-coherent memory. With this hack camera is working
>>> >> (I can see captured video on display).
>>> >
>>> > Why can't you use the v4l API? Won't that work?
>>> >
>>> Currently we are using v4l api. swiotlb-xen doesnt have mmap callback
>>> implemented,
>>> so kernel use standard function dma_common_mmap() to map memory. But this
>>> function doesn't work correctly. We've also tried to use arm_dma_mmap() 
>>> function
>>> instead of the dma_common_mmap() (HACK in the file
>>> include/asm-generic/dma-mapping-common.h only for dom0) and all is working
>>> in this case.
>>
>> This is not a Xen specific issue.
>> In fact unless some of the dma pages involved could be foreign guest
>> pages (for example because you have a PV framebuffer frontend in a guest
>> sharing pages with a framebuffer backend in Dom0, and these pages are
>> used directly in your camera driver), swiotlb-xen shouldn't even be
>> involved.
>>
>> The problem is that on ARM, when you call virt_to_phys on a virtual
>> address returned by dma_alloc_from_coherent, it doesn't return the right
>> physical address.
>> For example:
>>
>> virt_address = dma_alloc_from_coherent(dev, size, dma_addr, &ret);
>> virt_to_phys(virt_address) != dma_addr
>>
>> The issue is not that bus addresses are different from physical
>> addresses. The problem is that the virtual address is an ioremap address
>> therefore virt_to_phys and virt_to_page don't work as expected.
>>
>> To fix your problem you can simply:
>>
>> diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
>> index 0ce39a3..052a5ed 100644
>> --- a/drivers/base/dma-mapping.c
>> +++ b/drivers/base/dma-mapping.c
>> @@ -248,7 +248,7 @@ int dma_common_mmap(struct device *dev, struct 
>> vm_area_struct *vma,
>>  #ifdef CONFIG_MMU
>>         unsigned long user_count = (vma->vm_end - vma->vm_start) >> 
>> PAGE_SHIFT;
>>         unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
>> -       unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
>> +       unsigned long pfn = dma_addr >> PAGE_SHIFT;
>>         unsigned long off = vma->vm_pgoff;
>>
>>         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
>>
>> however that would cause problems on architectures for which bus
>> addresses are different from physical addresses.
>> Alternatively you could:
>>
>> +       unsigned long pfn = bus_to_phys(dma_addr) >> PAGE_SHIFT;
>>
>> however bus_to_phys is not defined on all architectures.
>> I am not sure what is the best way to fix this in common code such us
>> drivers/base/dma-mapping.c.

_______________________________________________
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®.