[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] swiotlb-xen question
On Wed, Mar 26, 2014 at 06:49:57PM +0000, Stefano Stabellini 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. Ugh. Usually drivers have an 'dma_addr_t[]' array to go along with the virtual addresses (or the array of the 'struct page'.). That way they have both the CPU and the bus addresses for the same region. Could that be used here? _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |