aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r--arch/arm/include/asm/cacheflush.h10
-rw-r--r--arch/arm/include/asm/device.h1
-rw-r--r--arch/arm/include/asm/dma-mapping.h7
-rw-r--r--arch/arm/include/asm/fixmap.h31
-rw-r--r--arch/arm/include/asm/hw_irq.h1
-rw-r--r--arch/arm/include/asm/mcpm.h17
-rw-r--r--arch/arm/include/asm/percpu.h4
-rw-r--r--arch/arm/include/asm/pgalloc.h10
-rw-r--r--arch/arm/include/asm/pgtable-2level-hwdef.h2
-rw-r--r--arch/arm/include/asm/pgtable-3level-hwdef.h1
-rw-r--r--arch/arm/include/asm/pgtable.h62
-rw-r--r--arch/arm/include/asm/ptrace.h5
-rw-r--r--arch/arm/include/asm/thread_info.h9
-rw-r--r--arch/arm/include/asm/vfp.h5
-rw-r--r--arch/arm/include/asm/xen/page-coherent.h66
-rw-r--r--arch/arm/include/asm/xen/page.h4
16 files changed, 190 insertions, 45 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 10e78d00a0bb..2d46862e7bef 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -487,6 +487,16 @@ int set_memory_rw(unsigned long addr, int numpages);
487int set_memory_x(unsigned long addr, int numpages); 487int set_memory_x(unsigned long addr, int numpages);
488int set_memory_nx(unsigned long addr, int numpages); 488int set_memory_nx(unsigned long addr, int numpages);
489 489
490#ifdef CONFIG_DEBUG_RODATA
491void mark_rodata_ro(void);
492void set_kernel_text_rw(void);
493void set_kernel_text_ro(void);
494#else
495static inline void set_kernel_text_rw(void) { }
496static inline void set_kernel_text_ro(void) { }
497#endif
498
490void flush_uprobe_xol_access(struct page *page, unsigned long uaddr, 499void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
491 void *kaddr, unsigned long len); 500 void *kaddr, unsigned long len);
501
492#endif 502#endif
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index dc662fca9230..4111592f0130 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -17,6 +17,7 @@ struct dev_archdata {
17#ifdef CONFIG_ARM_DMA_USE_IOMMU 17#ifdef CONFIG_ARM_DMA_USE_IOMMU
18 struct dma_iommu_mapping *mapping; 18 struct dma_iommu_mapping *mapping;
19#endif 19#endif
20 bool dma_coherent;
20}; 21};
21 22
22struct omap_device; 23struct omap_device;
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 85738b200023..e6e3446abdf6 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -123,11 +123,18 @@ static inline unsigned long dma_max_pfn(struct device *dev)
123 123
124static inline int set_arch_dma_coherent_ops(struct device *dev) 124static inline int set_arch_dma_coherent_ops(struct device *dev)
125{ 125{
126 dev->archdata.dma_coherent = true;
126 set_dma_ops(dev, &arm_coherent_dma_ops); 127 set_dma_ops(dev, &arm_coherent_dma_ops);
127 return 0; 128 return 0;
128} 129}
129#define set_arch_dma_coherent_ops(dev) set_arch_dma_coherent_ops(dev) 130#define set_arch_dma_coherent_ops(dev) set_arch_dma_coherent_ops(dev)
130 131
132/* do not use this function in a driver */
133static inline bool is_device_dma_coherent(struct device *dev)
134{
135 return dev->archdata.dma_coherent;
136}
137
131static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 138static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
132{ 139{
133 unsigned int offset = paddr & ~PAGE_MASK; 140 unsigned int offset = paddr & ~PAGE_MASK;
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 74124b0d0d79..0415eae1df27 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -2,27 +2,24 @@
2#define _ASM_FIXMAP_H 2#define _ASM_FIXMAP_H
3 3
4#define FIXADDR_START 0xffc00000UL 4#define FIXADDR_START 0xffc00000UL
5#define FIXADDR_TOP 0xffe00000UL 5#define FIXADDR_END 0xfff00000UL
6#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) 6#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)
7 7
8#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) 8#include <asm/kmap_types.h>
9 9
10#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) 10enum fixed_addresses {
11#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) 11 FIX_KMAP_BEGIN,
12 FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
12 13
13extern void __this_fixmap_does_not_exist(void); 14 /* Support writing RO kernel text via kprobes, jump labels, etc. */
15 FIX_TEXT_POKE0,
16 FIX_TEXT_POKE1,
14 17
15static inline unsigned long fix_to_virt(const unsigned int idx) 18 __end_of_fixed_addresses
16{ 19};
17 if (idx >= FIX_KMAP_NR_PTES)
18 __this_fixmap_does_not_exist();
19 return __fix_to_virt(idx);
20}
21 20
22static inline unsigned int virt_to_fix(const unsigned long vaddr) 21void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
23{ 22
24 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 23#include <asm-generic/fixmap.h>
25 return __virt_to_fix(vaddr);
26}
27 24
28#endif 25#endif
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index a71b417b1856..af79da40af2a 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -8,6 +8,7 @@ static inline void ack_bad_irq(int irq)
8{ 8{
9 extern unsigned long irq_err_count; 9 extern unsigned long irq_err_count;
10 irq_err_count++; 10 irq_err_count++;
11 pr_crit("unexpected IRQ trap at vector %02x\n", irq);
11} 12}
12 13
13void set_irq_flags(unsigned int irq, unsigned int flags); 14void set_irq_flags(unsigned int irq, unsigned int flags);
diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h
index d428e386c88e..3446f6a1d9fa 100644
--- a/arch/arm/include/asm/mcpm.h
+++ b/arch/arm/include/asm/mcpm.h
@@ -219,6 +219,23 @@ void __mcpm_outbound_leave_critical(unsigned int cluster, int state);
219bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster); 219bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster);
220int __mcpm_cluster_state(unsigned int cluster); 220int __mcpm_cluster_state(unsigned int cluster);
221 221
222/**
223 * mcpm_sync_init - Initialize the cluster synchronization support
224 *
225 * @power_up_setup: platform specific function invoked during very
226 * early CPU/cluster bringup stage.
227 *
228 * This prepares memory used by vlocks and the MCPM state machine used
229 * across CPUs that may have their caches active or inactive. Must be
230 * called only after a successful call to mcpm_platform_register().
231 *
232 * The power_up_setup argument is a pointer to assembly code called when
233 * the MMU and caches are still disabled during boot and no stack space is
234 * available. The affinity level passed to that code corresponds to the
235 * resource that needs to be initialized (e.g. 1 for cluster level, 0 for
236 * CPU level). Proper exclusion mechanisms are already activated at that
237 * point.
238 */
222int __init mcpm_sync_init( 239int __init mcpm_sync_init(
223 void (*power_up_setup)(unsigned int affinity_level)); 240 void (*power_up_setup)(unsigned int affinity_level));
224 241
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index 209e6504922e..a89b4076cde4 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -30,14 +30,14 @@ static inline void set_my_cpu_offset(unsigned long off)
30static inline unsigned long __my_cpu_offset(void) 30static inline unsigned long __my_cpu_offset(void)
31{ 31{
32 unsigned long off; 32 unsigned long off;
33 register unsigned long *sp asm ("sp");
34 33
35 /* 34 /*
36 * Read TPIDRPRW. 35 * Read TPIDRPRW.
37 * We want to allow caching the value, so avoid using volatile and 36 * We want to allow caching the value, so avoid using volatile and
38 * instead use a fake stack read to hazard against barrier(). 37 * instead use a fake stack read to hazard against barrier().
39 */ 38 */
40 asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp)); 39 asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
40 : "Q" (*(const unsigned long *)current_stack_pointer));
41 41
42 return off; 42 return off;
43} 43}
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 78a779361682..19cfab526d13 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -157,7 +157,15 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
157static inline void 157static inline void
158pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) 158pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
159{ 159{
160 __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); 160 extern pmdval_t user_pmd_table;
161 pmdval_t prot;
162
163 if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE))
164 prot = user_pmd_table;
165 else
166 prot = _PAGE_USER_TABLE;
167
168 __pmd_populate(pmdp, page_to_phys(ptep), prot);
161} 169}
162#define pmd_pgtable(pmd) pmd_page(pmd) 170#define pmd_pgtable(pmd) pmd_page(pmd)
163 171
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
index 5cfba15cb401..5e68278e953e 100644
--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -20,12 +20,14 @@
20#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) 20#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
21#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0) 21#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
22#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0) 22#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
23#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */
23#define PMD_BIT4 (_AT(pmdval_t, 1) << 4) 24#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
24#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5) 25#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
25#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */ 26#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
26/* 27/*
27 * - section 28 * - section
28 */ 29 */
30#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
29#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) 31#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
30#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) 32#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
31#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */ 33#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index 9fd61c72a33a..f8f1cff62065 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -76,6 +76,7 @@
76#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ 76#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
77#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ 77#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
78#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ 78#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */
79#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */
79#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ 80#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */
80 81
81/* 82/*
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 3b30062975b2..d5cac545ba33 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -252,17 +252,57 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
252 set_pte_ext(ptep, pteval, ext); 252 set_pte_ext(ptep, pteval, ext);
253} 253}
254 254
255#define PTE_BIT_FUNC(fn,op) \ 255static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
256static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 256{
257 257 pte_val(pte) &= ~pgprot_val(prot);
258PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY); 258 return pte;
259PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY); 259}
260PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); 260
261PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); 261static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot)
262PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); 262{
263PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); 263 pte_val(pte) |= pgprot_val(prot);
264PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); 264 return pte;
265PTE_BIT_FUNC(mknexec, |= L_PTE_XN); 265}
266
267static inline pte_t pte_wrprotect(pte_t pte)
268{
269 return set_pte_bit(pte, __pgprot(L_PTE_RDONLY));
270}
271
272static inline pte_t pte_mkwrite(pte_t pte)
273{
274 return clear_pte_bit(pte, __pgprot(L_PTE_RDONLY));
275}
276
277static inline pte_t pte_mkclean(pte_t pte)
278{
279 return clear_pte_bit(pte, __pgprot(L_PTE_DIRTY));
280}
281
282static inline pte_t pte_mkdirty(pte_t pte)
283{
284 return set_pte_bit(pte, __pgprot(L_PTE_DIRTY));
285}
286
287static inline pte_t pte_mkold(pte_t pte)
288{
289 return clear_pte_bit(pte, __pgprot(L_PTE_YOUNG));
290}
291
292static inline pte_t pte_mkyoung(pte_t pte)
293{
294 return set_pte_bit(pte, __pgprot(L_PTE_YOUNG));
295}
296
297static inline pte_t pte_mkexec(pte_t pte)
298{
299 return clear_pte_bit(pte, __pgprot(L_PTE_XN));
300}
301
302static inline pte_t pte_mknexec(pte_t pte)
303{
304 return set_pte_bit(pte, __pgprot(L_PTE_XN));
305}
266 306
267static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 307static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
268{ 308{
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 601264d983fa..51622ba7c4a6 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -154,9 +154,8 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
154 return regs->ARM_sp; 154 return regs->ARM_sp;
155} 155}
156 156
157#define current_pt_regs(void) ({ \ 157#define current_pt_regs(void) ({ (struct pt_regs *) \
158 register unsigned long sp asm ("sp"); \ 158 ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
159 (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \
160}) 159})
161 160
162#endif /* __ASSEMBLY__ */ 161#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index ce73ab635414..d890e41f5520 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -90,14 +90,19 @@ struct thread_info {
90#define init_stack (init_thread_union.stack) 90#define init_stack (init_thread_union.stack)
91 91
92/* 92/*
93 * how to get the current stack pointer in C
94 */
95register unsigned long current_stack_pointer asm ("sp");
96
97/*
93 * how to get the thread information struct from C 98 * how to get the thread information struct from C
94 */ 99 */
95static inline struct thread_info *current_thread_info(void) __attribute_const__; 100static inline struct thread_info *current_thread_info(void) __attribute_const__;
96 101
97static inline struct thread_info *current_thread_info(void) 102static inline struct thread_info *current_thread_info(void)
98{ 103{
99 register unsigned long sp asm ("sp"); 104 return (struct thread_info *)
100 return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); 105 (current_stack_pointer & ~(THREAD_SIZE - 1));
101} 106}
102 107
103#define thread_saved_pc(tsk) \ 108#define thread_saved_pc(tsk) \
diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h
index f4ab34fd4f72..ee5f3084243c 100644
--- a/arch/arm/include/asm/vfp.h
+++ b/arch/arm/include/asm/vfp.h
@@ -22,6 +22,7 @@
22#define FPSID_NODOUBLE (1<<20) 22#define FPSID_NODOUBLE (1<<20)
23#define FPSID_ARCH_BIT (16) 23#define FPSID_ARCH_BIT (16)
24#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) 24#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT)
25#define FPSID_CPUID_ARCH_MASK (0x7F << FPSID_ARCH_BIT)
25#define FPSID_PART_BIT (8) 26#define FPSID_PART_BIT (8)
26#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT) 27#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT)
27#define FPSID_VARIANT_BIT (4) 28#define FPSID_VARIANT_BIT (4)
@@ -75,6 +76,10 @@
75/* MVFR0 bits */ 76/* MVFR0 bits */
76#define MVFR0_A_SIMD_BIT (0) 77#define MVFR0_A_SIMD_BIT (0)
77#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT) 78#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT)
79#define MVFR0_SP_BIT (4)
80#define MVFR0_SP_MASK (0xf << MVFR0_SP_BIT)
81#define MVFR0_DP_BIT (8)
82#define MVFR0_DP_MASK (0xf << MVFR0_DP_BIT)
78 83
79/* Bit patterns for decoding the packaged operation descriptors */ 84/* Bit patterns for decoding the packaged operation descriptors */
80#define VFPOPDESC_LENGTH_BIT (9) 85#define VFPOPDESC_LENGTH_BIT (9)
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index e8275ea88e88..efd562412850 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -5,6 +5,18 @@
5#include <linux/dma-attrs.h> 5#include <linux/dma-attrs.h>
6#include <linux/dma-mapping.h> 6#include <linux/dma-mapping.h>
7 7
8void __xen_dma_map_page(struct device *hwdev, struct page *page,
9 dma_addr_t dev_addr, unsigned long offset, size_t size,
10 enum dma_data_direction dir, struct dma_attrs *attrs);
11void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
12 size_t size, enum dma_data_direction dir,
13 struct dma_attrs *attrs);
14void __xen_dma_sync_single_for_cpu(struct device *hwdev,
15 dma_addr_t handle, size_t size, enum dma_data_direction dir);
16
17void __xen_dma_sync_single_for_device(struct device *hwdev,
18 dma_addr_t handle, size_t size, enum dma_data_direction dir);
19
8static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, 20static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
9 dma_addr_t *dma_handle, gfp_t flags, 21 dma_addr_t *dma_handle, gfp_t flags,
10 struct dma_attrs *attrs) 22 struct dma_attrs *attrs)
@@ -20,20 +32,56 @@ static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
20} 32}
21 33
22static inline void xen_dma_map_page(struct device *hwdev, struct page *page, 34static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
23 unsigned long offset, size_t size, enum dma_data_direction dir, 35 dma_addr_t dev_addr, unsigned long offset, size_t size,
24 struct dma_attrs *attrs) 36 enum dma_data_direction dir, struct dma_attrs *attrs)
25{ 37{
26 __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); 38 bool local = PFN_DOWN(dev_addr) == page_to_pfn(page);
39 /* Dom0 is mapped 1:1, so if pfn == mfn the page is local otherwise
40 * is a foreign page grant-mapped in dom0. If the page is local we
41 * can safely call the native dma_ops function, otherwise we call
42 * the xen specific function. */
43 if (local)
44 __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
45 else
46 __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
27} 47}
28 48
29void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, 49static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
30 size_t size, enum dma_data_direction dir, 50 size_t size, enum dma_data_direction dir,
31 struct dma_attrs *attrs); 51 struct dma_attrs *attrs)
52{
53 unsigned long pfn = PFN_DOWN(handle);
54 /* Dom0 is mapped 1:1, so calling pfn_valid on a foreign mfn will
55 * always return false. If the page is local we can safely call the
56 * native dma_ops function, otherwise we call the xen specific
57 * function. */
58 if (pfn_valid(pfn)) {
59 if (__generic_dma_ops(hwdev)->unmap_page)
60 __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
61 } else
62 __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
63}
32 64
33void xen_dma_sync_single_for_cpu(struct device *hwdev, 65static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
34 dma_addr_t handle, size_t size, enum dma_data_direction dir); 66 dma_addr_t handle, size_t size, enum dma_data_direction dir)
67{
68 unsigned long pfn = PFN_DOWN(handle);
69 if (pfn_valid(pfn)) {
70 if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
71 __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
72 } else
73 __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
74}
35 75
36void xen_dma_sync_single_for_device(struct device *hwdev, 76static inline void xen_dma_sync_single_for_device(struct device *hwdev,
37 dma_addr_t handle, size_t size, enum dma_data_direction dir); 77 dma_addr_t handle, size_t size, enum dma_data_direction dir)
78{
79 unsigned long pfn = PFN_DOWN(handle);
80 if (pfn_valid(pfn)) {
81 if (__generic_dma_ops(hwdev)->sync_single_for_device)
82 __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
83 } else
84 __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
85}
38 86
39#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */ 87#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 135c24a5ba26..68c739b3fdf4 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -107,4 +107,8 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
107#define xen_remap(cookie, size) ioremap_cache((cookie), (size)) 107#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
108#define xen_unmap(cookie) iounmap((cookie)) 108#define xen_unmap(cookie) iounmap((cookie))
109 109
110bool xen_arch_need_swiotlb(struct device *dev,
111 unsigned long pfn,
112 unsigned long mfn);
113
110#endif /* _ASM_ARM_XEN_PAGE_H */ 114#endif /* _ASM_ARM_XEN_PAGE_H */