diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2014-11-21 11:05:39 +0000 |
---|---|---|
committer | David Vrabel <david.vrabel@citrix.com> | 2014-12-04 12:41:52 +0000 |
commit | 3567258d281b5b515d5165ed23851d9f84087e7d (patch) | |
tree | 69da5f20e5354507e3219eaeb6e72b7e5e93f58d /arch/arm/xen | |
parent | a0f2dee0cd651efb5fac6a1d35b0a14460ebcdd4 (diff) | |
download | linux-3567258d281b5b515d5165ed23851d9f84087e7d.tar.bz2 |
xen/arm: use hypercall to flush caches in map_page
In xen_dma_map_page, if the page is a local page, call the native
map_page dma_ops. If the page is foreign, call __xen_dma_map_page that
issues any required cache maintenane operations via hypercall.
The reason for doing this is that the native dma_ops map_page could
allocate buffers than need to be freed. If the page is foreign we don't
call the native unmap_page dma_ops function, resulting in a memory leak.
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/xen')
-rw-r--r-- | arch/arm/xen/mm32.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/arm/xen/mm32.c b/arch/arm/xen/mm32.c index 3ce9dc1efb0c..c86919bbea83 100644 --- a/arch/arm/xen/mm32.c +++ b/arch/arm/xen/mm32.c @@ -43,6 +43,18 @@ static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle, dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP); } +void __xen_dma_map_page(struct device *hwdev, struct page *page, + dma_addr_t dev_addr, unsigned long offset, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ + if (is_device_dma_coherent(hwdev)) + return; + if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) + return; + + __xen_dma_page_cpu_to_dev(hwdev, dev_addr, size, dir); +} + void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) |