aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2013-10-10 09:40:44 -0400
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2013-10-10 09:40:44 -0400
commit83862ccfc0a03212fde43b4ac29c28381828768b (patch)
treef750d82b6d3162d066687d55de2bce0cf48e0b43
parent69908907b02efee31377af0cefbcd5a3ba66334a (diff)
xen/arm,arm64: enable SWIOTLB_XEN
Xen on arm and arm64 needs SWIOTLB_XEN: when running on Xen we need to program the hardware with mfns rather than pfns for dma addresses. Remove SWIOTLB_XEN dependency on X86 and PCI and make XEN select SWIOTLB_XEN on arm and arm64. At the moment always rely on swiotlb-xen, but when Xen starts supporting hardware IOMMUs we'll be able to avoid it conditionally on the presence of an IOMMU on the platform. Implement xen_create_contiguous_region on arm and arm64: for the moment we assume that dom0 has been mapped 1:1 (physical addresses == machine addresses) therefore we don't need to call XENMEM_exchange. Simply return the physical address as dma address. Initialize the xen-swiotlb from xen_early_init (before the native dma_ops are initialized), set xen_dma_ops to &xen_swiotlb_dma_ops. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Changes in v8: - assume dom0 is mapped 1:1, no need to call XENMEM_exchange. Changes in v7: - call __set_phys_to_machine_multi from xen_create_contiguous_region and xen_destroy_contiguous_region to update the P2M; - don't call XENMEM_unpin, it has been removed; - call XENMEM_exchange instead of XENMEM_exchange_and_pin; - set nr_exchanged to 0 before calling the hypercall. Changes in v6: - introduce and export xen_dma_ops; - call xen_mm_init from as arch_initcall. Changes in v4: - remove redefinition of DMA_ERROR_CODE; - update the code to use XENMEM_exchange_and_pin and XENMEM_unpin; - add a note about hardware IOMMU in the commit message. Changes in v3: - code style changes; - warn on XENMEM_put_dma_buf failures.
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/include/asm/xen/hypervisor.h2
-rw-r--r--arch/arm/include/asm/xen/page.h1
-rw-r--r--arch/arm/xen/Makefile2
-rw-r--r--arch/arm/xen/mm.c64
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/xen/Makefile2
-rw-r--r--drivers/xen/Kconfig1
-rw-r--r--drivers/xen/swiotlb-xen.c15
9 files changed, 86 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b08374f8fe3b..01f7013c85c7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1888,6 +1888,7 @@ config XEN
1888 depends on CPU_V7 && !CPU_V6 1888 depends on CPU_V7 && !CPU_V6
1889 depends on !GENERIC_ATOMIC64 1889 depends on !GENERIC_ATOMIC64
1890 select ARM_PSCI 1890 select ARM_PSCI
1891 select SWIOTLB_XEN
1891 help 1892 help
1892 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. 1893 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
1893 1894
diff --git a/arch/arm/include/asm/xen/hypervisor.h b/arch/arm/include/asm/xen/hypervisor.h
index d7ab99a0c9eb..1317ee40f4df 100644
--- a/arch/arm/include/asm/xen/hypervisor.h
+++ b/arch/arm/include/asm/xen/hypervisor.h
@@ -16,4 +16,6 @@ static inline enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
16 return PARAVIRT_LAZY_NONE; 16 return PARAVIRT_LAZY_NONE;
17} 17}
18 18
19extern struct dma_map_ops *xen_dma_ops;
20
19#endif /* _ASM_ARM_XEN_HYPERVISOR_H */ 21#endif /* _ASM_ARM_XEN_HYPERVISOR_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index d1b5dd566472..5d0e4c5dc711 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/pfn.h> 7#include <linux/pfn.h>
8#include <linux/types.h> 8#include <linux/types.h>
9#include <linux/dma-mapping.h>
9 10
10#include <xen/xen.h> 11#include <xen/xen.h>
11#include <xen/interface/grant_table.h> 12#include <xen/interface/grant_table.h>
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 21e6ff503178..12969523414c 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1 @@
obj-y := enlighten.o hypercall.o grant-table.o p2m.o obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
new file mode 100644
index 000000000000..d56b8c6e4fbb
--- /dev/null
+++ b/arch/arm/xen/mm.c
@@ -0,0 +1,64 @@
1#include <linux/bootmem.h>
2#include <linux/gfp.h>
3#include <linux/export.h>
4#include <linux/slab.h>
5#include <linux/types.h>
6#include <linux/dma-mapping.h>
7#include <linux/vmalloc.h>
8#include <linux/swiotlb.h>
9
10#include <xen/xen.h>
11#include <xen/interface/memory.h>
12#include <xen/swiotlb-xen.h>
13
14#include <asm/cacheflush.h>
15#include <asm/xen/page.h>
16#include <asm/xen/hypercall.h>
17#include <asm/xen/interface.h>
18
19int xen_create_contiguous_region(unsigned long vstart, unsigned int order,
20 unsigned int address_bits,
21 dma_addr_t *dma_handle)
22{
23 if (!xen_initial_domain())
24 return -EINVAL;
25
26 /* we assume that dom0 is mapped 1:1 for now */
27 *dma_handle = virt_to_phys(pstart);
28 return 0;
29}
30EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
31
32void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
33{
34 return;
35}
36EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
37
38struct dma_map_ops *xen_dma_ops;
39EXPORT_SYMBOL_GPL(xen_dma_ops);
40
41static struct dma_map_ops xen_swiotlb_dma_ops = {
42 .mapping_error = xen_swiotlb_dma_mapping_error,
43 .alloc = xen_swiotlb_alloc_coherent,
44 .free = xen_swiotlb_free_coherent,
45 .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
46 .sync_single_for_device = xen_swiotlb_sync_single_for_device,
47 .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
48 .sync_sg_for_device = xen_swiotlb_sync_sg_for_device,
49 .map_sg = xen_swiotlb_map_sg_attrs,
50 .unmap_sg = xen_swiotlb_unmap_sg_attrs,
51 .map_page = xen_swiotlb_map_page,
52 .unmap_page = xen_swiotlb_unmap_page,
53 .dma_supported = xen_swiotlb_dma_supported,
54};
55
56int __init xen_mm_init(void)
57{
58 if (!xen_initial_domain())
59 return 0;
60 xen_swiotlb_init(1, false);
61 xen_dma_ops = &xen_swiotlb_dma_ops;
62 return 0;
63}
64arch_initcall(xen_mm_init);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c04454876bcb..04ffafb6fbe9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -211,6 +211,7 @@ config XEN_DOM0
211config XEN 211config XEN
212 bool "Xen guest support on ARM64 (EXPERIMENTAL)" 212 bool "Xen guest support on ARM64 (EXPERIMENTAL)"
213 depends on ARM64 && OF 213 depends on ARM64 && OF
214 select SWIOTLB_XEN
214 help 215 help
215 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64. 216 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.
216 217
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index cd866b0c619b..74a8d87e542b 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,2 @@
1xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o) 1xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
2obj-y := xen-arm.o hypercall.o 2obj-y := xen-arm.o hypercall.o
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 23eae5cb69c2..c794ea182140 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -140,7 +140,6 @@ config XEN_GRANT_DEV_ALLOC
140 140
141config SWIOTLB_XEN 141config SWIOTLB_XEN
142 def_bool y 142 def_bool y
143 depends on PCI && X86
144 select SWIOTLB 143 select SWIOTLB
145 144
146config XEN_TMEM 145config XEN_TMEM
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index b72f31c1e018..f0fc1a4f565a 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -42,12 +42,27 @@
42#include <xen/page.h> 42#include <xen/page.h>
43#include <xen/xen-ops.h> 43#include <xen/xen-ops.h>
44#include <xen/hvc-console.h> 44#include <xen/hvc-console.h>
45#include <asm/dma-mapping.h>
45/* 46/*
46 * Used to do a quick range check in swiotlb_tbl_unmap_single and 47 * Used to do a quick range check in swiotlb_tbl_unmap_single and
47 * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this 48 * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this
48 * API. 49 * API.
49 */ 50 */
50 51
52#ifndef CONFIG_X86
53static unsigned long dma_alloc_coherent_mask(struct device *dev,
54 gfp_t gfp)
55{
56 unsigned long dma_mask = 0;
57
58 dma_mask = dev->coherent_dma_mask;
59 if (!dma_mask)
60 dma_mask = (gfp & GFP_DMA) ? DMA_BIT_MASK(24) : DMA_BIT_MASK(32);
61
62 return dma_mask;
63}
64#endif
65
51static char *xen_io_tlb_start, *xen_io_tlb_end; 66static char *xen_io_tlb_start, *xen_io_tlb_end;
52static unsigned long xen_io_tlb_nslabs; 67static unsigned long xen_io_tlb_nslabs;
53/* 68/*