aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/cache-l2x0.c22
-rw-r--r--arch/arm/mm/copypage-v4mc.c9
-rw-r--r--arch/arm/mm/copypage-v6.c20
-rw-r--r--arch/arm/mm/copypage-xscale.c9
-rw-r--r--arch/arm/mm/dma-mapping.c20
-rw-r--r--arch/arm/mm/fault.c3
-rw-r--r--arch/arm/mm/flush.c14
-rw-r--r--arch/arm/mm/highmem.c21
-rw-r--r--arch/arm/mm/init.c4
-rw-r--r--arch/arm/mm/mm.h26
-rw-r--r--arch/arm/mm/mmu.c7
-rw-r--r--arch/arm/mm/vmregion.c76
-rw-r--r--arch/arm/mm/vmregion.h5
13 files changed, 161 insertions, 75 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b1e192ba8c24..a53fd2aaa2f4 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,13 +30,13 @@
30 30
31static void __iomem *l2x0_base; 31static void __iomem *l2x0_base;
32static DEFINE_RAW_SPINLOCK(l2x0_lock); 32static DEFINE_RAW_SPINLOCK(l2x0_lock);
33static uint32_t l2x0_way_mask; /* Bitmask of active ways */ 33static u32 l2x0_way_mask; /* Bitmask of active ways */
34static uint32_t l2x0_size; 34static u32 l2x0_size;
35 35
36struct l2x0_regs l2x0_saved_regs; 36struct l2x0_regs l2x0_saved_regs;
37 37
38struct l2x0_of_data { 38struct l2x0_of_data {
39 void (*setup)(const struct device_node *, __u32 *, __u32 *); 39 void (*setup)(const struct device_node *, u32 *, u32 *);
40 void (*save)(void); 40 void (*save)(void);
41 void (*resume)(void); 41 void (*resume)(void);
42}; 42};
@@ -288,7 +288,7 @@ static void l2x0_disable(void)
288 raw_spin_unlock_irqrestore(&l2x0_lock, flags); 288 raw_spin_unlock_irqrestore(&l2x0_lock, flags);
289} 289}
290 290
291static void l2x0_unlock(__u32 cache_id) 291static void l2x0_unlock(u32 cache_id)
292{ 292{
293 int lockregs; 293 int lockregs;
294 int i; 294 int i;
@@ -307,11 +307,11 @@ static void l2x0_unlock(__u32 cache_id)
307 } 307 }
308} 308}
309 309
310void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 310void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
311{ 311{
312 __u32 aux; 312 u32 aux;
313 __u32 cache_id; 313 u32 cache_id;
314 __u32 way_size = 0; 314 u32 way_size = 0;
315 int ways; 315 int ways;
316 const char *type; 316 const char *type;
317 317
@@ -388,7 +388,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
388 388
389#ifdef CONFIG_OF 389#ifdef CONFIG_OF
390static void __init l2x0_of_setup(const struct device_node *np, 390static void __init l2x0_of_setup(const struct device_node *np,
391 __u32 *aux_val, __u32 *aux_mask) 391 u32 *aux_val, u32 *aux_mask)
392{ 392{
393 u32 data[2] = { 0, 0 }; 393 u32 data[2] = { 0, 0 };
394 u32 tag = 0; 394 u32 tag = 0;
@@ -422,7 +422,7 @@ static void __init l2x0_of_setup(const struct device_node *np,
422} 422}
423 423
424static void __init pl310_of_setup(const struct device_node *np, 424static void __init pl310_of_setup(const struct device_node *np,
425 __u32 *aux_val, __u32 *aux_mask) 425 u32 *aux_val, u32 *aux_mask)
426{ 426{
427 u32 data[3] = { 0, 0, 0 }; 427 u32 data[3] = { 0, 0, 0 };
428 u32 tag[3] = { 0, 0, 0 }; 428 u32 tag[3] = { 0, 0, 0 };
@@ -548,7 +548,7 @@ static const struct of_device_id l2x0_ids[] __initconst = {
548 {} 548 {}
549}; 549};
550 550
551int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) 551int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
552{ 552{
553 struct device_node *np; 553 struct device_node *np;
554 struct l2x0_of_data *data; 554 struct l2x0_of_data *data;
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index ec8c3befb9c8..1267e64133b9 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -23,10 +23,6 @@
23 23
24#include "mm.h" 24#include "mm.h"
25 25
26/*
27 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
28 * specific hacks for copying pages efficiently.
29 */
30#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ 26#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
31 L_PTE_MT_MINICACHE) 27 L_PTE_MT_MINICACHE)
32 28
@@ -78,10 +74,9 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from,
78 74
79 raw_spin_lock(&minicache_lock); 75 raw_spin_lock(&minicache_lock);
80 76
81 set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); 77 set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
82 flush_tlb_kernel_page(0xffff8000);
83 78
84 mc_copy_user_page((void *)0xffff8000, kto); 79 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
85 80
86 raw_spin_unlock(&minicache_lock); 81 raw_spin_unlock(&minicache_lock);
87 82
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 8b03a5814d00..b9bcc9d79176 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -24,9 +24,6 @@
24#error FIX ME 24#error FIX ME
25#endif 25#endif
26 26
27#define from_address (0xffff8000)
28#define to_address (0xffffc000)
29
30static DEFINE_RAW_SPINLOCK(v6_lock); 27static DEFINE_RAW_SPINLOCK(v6_lock);
31 28
32/* 29/*
@@ -90,14 +87,11 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
90 */ 87 */
91 raw_spin_lock(&v6_lock); 88 raw_spin_lock(&v6_lock);
92 89
93 set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); 90 kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT);
94 set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); 91 kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT);
95
96 kfrom = from_address + (offset << PAGE_SHIFT);
97 kto = to_address + (offset << PAGE_SHIFT);
98 92
99 flush_tlb_kernel_page(kfrom); 93 set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL));
100 flush_tlb_kernel_page(kto); 94 set_top_pte(kto, mk_pte(to, PAGE_KERNEL));
101 95
102 copy_page((void *)kto, (void *)kfrom); 96 copy_page((void *)kto, (void *)kfrom);
103 97
@@ -111,8 +105,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
111 */ 105 */
112static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr) 106static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr)
113{ 107{
114 unsigned int offset = CACHE_COLOUR(vaddr); 108 unsigned long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
115 unsigned long to = to_address + (offset << PAGE_SHIFT);
116 109
117 /* FIXME: not highmem safe */ 110 /* FIXME: not highmem safe */
118 discard_old_kernel_data(page_address(page)); 111 discard_old_kernel_data(page_address(page));
@@ -123,8 +116,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad
123 */ 116 */
124 raw_spin_lock(&v6_lock); 117 raw_spin_lock(&v6_lock);
125 118
126 set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); 119 set_top_pte(to, mk_pte(page, PAGE_KERNEL));
127 flush_tlb_kernel_page(to);
128 clear_page((void *)to); 120 clear_page((void *)to);
129 121
130 raw_spin_unlock(&v6_lock); 122 raw_spin_unlock(&v6_lock);
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 439d106ae638..0fb85025344d 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -23,12 +23,6 @@
23 23
24#include "mm.h" 24#include "mm.h"
25 25
26/*
27 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
28 * specific hacks for copying pages efficiently.
29 */
30#define COPYPAGE_MINICACHE 0xffff8000
31
32#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ 26#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
33 L_PTE_MT_MINICACHE) 27 L_PTE_MT_MINICACHE)
34 28
@@ -100,8 +94,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
100 94
101 raw_spin_lock(&minicache_lock); 95 raw_spin_lock(&minicache_lock);
102 96
103 set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); 97 set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
104 flush_tlb_kernel_page(COPYPAGE_MINICACHE);
105 98
106 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); 99 mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
107 100
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1aa664a1999f..db23ae4aaaab 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -214,7 +214,8 @@ static int __init consistent_init(void)
214core_initcall(consistent_init); 214core_initcall(consistent_init);
215 215
216static void * 216static void *
217__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) 217__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
218 const void *caller)
218{ 219{
219 struct arm_vmregion *c; 220 struct arm_vmregion *c;
220 size_t align; 221 size_t align;
@@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
241 * Allocate a virtual address in the consistent mapping region. 242 * Allocate a virtual address in the consistent mapping region.
242 */ 243 */
243 c = arm_vmregion_alloc(&consistent_head, align, size, 244 c = arm_vmregion_alloc(&consistent_head, align, size,
244 gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); 245 gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
245 if (c) { 246 if (c) {
246 pte_t *pte; 247 pte_t *pte;
247 int idx = CONSISTENT_PTE_INDEX(c->vm_start); 248 int idx = CONSISTENT_PTE_INDEX(c->vm_start);
@@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
320 321
321#else /* !CONFIG_MMU */ 322#else /* !CONFIG_MMU */
322 323
323#define __dma_alloc_remap(page, size, gfp, prot) page_address(page) 324#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page)
324#define __dma_free_remap(addr, size) do { } while (0) 325#define __dma_free_remap(addr, size) do { } while (0)
325 326
326#endif /* CONFIG_MMU */ 327#endif /* CONFIG_MMU */
327 328
328static void * 329static void *
329__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, 330__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
330 pgprot_t prot) 331 pgprot_t prot, const void *caller)
331{ 332{
332 struct page *page; 333 struct page *page;
333 void *addr; 334 void *addr;
@@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
349 return NULL; 350 return NULL;
350 351
351 if (!arch_is_coherent()) 352 if (!arch_is_coherent())
352 addr = __dma_alloc_remap(page, size, gfp, prot); 353 addr = __dma_alloc_remap(page, size, gfp, prot, caller);
353 else 354 else
354 addr = page_address(page); 355 addr = page_address(page);
355 356
@@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
374 return memory; 375 return memory;
375 376
376 return __dma_alloc(dev, size, handle, gfp, 377 return __dma_alloc(dev, size, handle, gfp,
377 pgprot_dmacoherent(pgprot_kernel)); 378 pgprot_dmacoherent(pgprot_kernel),
379 __builtin_return_address(0));
378} 380}
379EXPORT_SYMBOL(dma_alloc_coherent); 381EXPORT_SYMBOL(dma_alloc_coherent);
380 382
@@ -386,7 +388,8 @@ void *
386dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 388dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
387{ 389{
388 return __dma_alloc(dev, size, handle, gfp, 390 return __dma_alloc(dev, size, handle, gfp,
389 pgprot_writecombine(pgprot_kernel)); 391 pgprot_writecombine(pgprot_kernel),
392 __builtin_return_address(0));
390} 393}
391EXPORT_SYMBOL(dma_alloc_writecombine); 394EXPORT_SYMBOL(dma_alloc_writecombine);
392 395
@@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask);
723 726
724static int __init dma_debug_do_init(void) 727static int __init dma_debug_do_init(void)
725{ 728{
729#ifdef CONFIG_MMU
730 arm_vmregion_create_proc("dma-mappings", &consistent_head);
731#endif
726 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 732 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
727 return 0; 733 return 0;
728} 734}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 5bdff5c3e6cb..9055b5a84ec5 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -165,7 +165,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
165 struct siginfo si; 165 struct siginfo si;
166 166
167#ifdef CONFIG_DEBUG_USER 167#ifdef CONFIG_DEBUG_USER
168 if (user_debug & UDBG_SEGV) { 168 if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
169 ((user_debug & UDBG_BUS) && (sig == SIGBUS))) {
169 printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", 170 printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
170 tsk->comm, sig, addr, fsr); 171 tsk->comm, sig, addr, fsr);
171 show_pte(tsk->mm, addr); 172 show_pte(tsk->mm, addr);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 062d61a1f87d..77458548e031 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -22,15 +22,12 @@
22 22
23#ifdef CONFIG_CPU_CACHE_VIPT 23#ifdef CONFIG_CPU_CACHE_VIPT
24 24
25#define ALIAS_FLUSH_START 0xffff4000
26
27static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) 25static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
28{ 26{
29 unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); 27 unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
30 const int zero = 0; 28 const int zero = 0;
31 29
32 set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0); 30 set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL));
33 flush_tlb_kernel_page(to);
34 31
35 asm( "mcrr p15, 0, %1, %0, c14\n" 32 asm( "mcrr p15, 0, %1, %0, c14\n"
36 " mcr p15, 0, %2, c7, c10, 4" 33 " mcr p15, 0, %2, c7, c10, 4"
@@ -41,13 +38,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
41 38
42static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) 39static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
43{ 40{
44 unsigned long colour = CACHE_COLOUR(vaddr); 41 unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
45 unsigned long offset = vaddr & (PAGE_SIZE - 1); 42 unsigned long offset = vaddr & (PAGE_SIZE - 1);
46 unsigned long to; 43 unsigned long to;
47 44
48 set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); 45 set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL));
49 to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset; 46 to = va + offset;
50 flush_tlb_kernel_page(to);
51 flush_icache_range(to, to + len); 47 flush_icache_range(to, to + len);
52} 48}
53 49
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 5a21505d7550..21b9e1bf9b77 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -69,15 +69,14 @@ void *kmap_atomic(struct page *page)
69 * With debugging enabled, kunmap_atomic forces that entry to 0. 69 * With debugging enabled, kunmap_atomic forces that entry to 0.
70 * Make sure it was indeed properly unmapped. 70 * Make sure it was indeed properly unmapped.
71 */ 71 */
72 BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); 72 BUG_ON(!pte_none(get_top_pte(vaddr)));
73#endif 73#endif
74 set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
75 /* 74 /*
76 * When debugging is off, kunmap_atomic leaves the previous mapping 75 * When debugging is off, kunmap_atomic leaves the previous mapping
77 * in place, so this TLB flush ensures the TLB is updated with the 76 * in place, so the contained TLB flush ensures the TLB is updated
78 * new mapping. 77 * with the new mapping.
79 */ 78 */
80 local_flush_tlb_kernel_page(vaddr); 79 set_top_pte(vaddr, mk_pte(page, kmap_prot));
81 80
82 return (void *)vaddr; 81 return (void *)vaddr;
83} 82}
@@ -96,8 +95,7 @@ void __kunmap_atomic(void *kvaddr)
96 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); 95 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
97#ifdef CONFIG_DEBUG_HIGHMEM 96#ifdef CONFIG_DEBUG_HIGHMEM
98 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); 97 BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
99 set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); 98 set_top_pte(vaddr, __pte(0));
100 local_flush_tlb_kernel_page(vaddr);
101#else 99#else
102 (void) idx; /* to kill a warning */ 100 (void) idx; /* to kill a warning */
103#endif 101#endif
@@ -121,10 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
121 idx = type + KM_TYPE_NR * smp_processor_id(); 119 idx = type + KM_TYPE_NR * smp_processor_id();
122 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 120 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
123#ifdef CONFIG_DEBUG_HIGHMEM 121#ifdef CONFIG_DEBUG_HIGHMEM
124 BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); 122 BUG_ON(!pte_none(get_top_pte(vaddr)));
125#endif 123#endif
126 set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0); 124 set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
127 local_flush_tlb_kernel_page(vaddr);
128 125
129 return (void *)vaddr; 126 return (void *)vaddr;
130} 127}
@@ -132,11 +129,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
132struct page *kmap_atomic_to_page(const void *ptr) 129struct page *kmap_atomic_to_page(const void *ptr)
133{ 130{
134 unsigned long vaddr = (unsigned long)ptr; 131 unsigned long vaddr = (unsigned long)ptr;
135 pte_t *pte;
136 132
137 if (vaddr < FIXADDR_START) 133 if (vaddr < FIXADDR_START)
138 return virt_to_page(ptr); 134 return virt_to_page(ptr);
139 135
140 pte = TOP_PTE(vaddr); 136 return pte_page(get_top_pte(vaddr));
141 return pte_page(*pte);
142} 137}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 245a55a0a5bb..595079fa9d1d 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -658,7 +658,9 @@ void __init mem_init(void)
658#ifdef CONFIG_HIGHMEM 658#ifdef CONFIG_HIGHMEM
659 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" 659 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
660#endif 660#endif
661#ifdef CONFIG_MODULES
661 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" 662 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
663#endif
662 " .text : 0x%p" " - 0x%p" " (%4d kB)\n" 664 " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
663 " .init : 0x%p" " - 0x%p" " (%4d kB)\n" 665 " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
664 " .data : 0x%p" " - 0x%p" " (%4d kB)\n" 666 " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
@@ -677,7 +679,9 @@ void __init mem_init(void)
677 MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) * 679 MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
678 (PAGE_SIZE)), 680 (PAGE_SIZE)),
679#endif 681#endif
682#ifdef CONFIG_MODULES
680 MLM(MODULES_VADDR, MODULES_END), 683 MLM(MODULES_VADDR, MODULES_END),
684#endif
681 685
682 MLK_ROUNDUP(_text, _etext), 686 MLK_ROUNDUP(_text, _etext),
683 MLK_ROUNDUP(__init_begin, __init_end), 687 MLK_ROUNDUP(__init_begin, __init_end),
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 70f6d3ea4834..27f4a619b35d 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -3,7 +3,31 @@
3/* the upper-most page table pointer */ 3/* the upper-most page table pointer */
4extern pmd_t *top_pmd; 4extern pmd_t *top_pmd;
5 5
6#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) 6/*
7 * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
8 * specific hacks for copying pages efficiently, while 0xffff4000
9 * is reserved for VIPT aliasing flushing by generic code.
10 *
11 * Note that we don't allow VIPT aliasing caches with SMP.
12 */
13#define COPYPAGE_MINICACHE 0xffff8000
14#define COPYPAGE_V6_FROM 0xffff8000
15#define COPYPAGE_V6_TO 0xffffc000
16/* PFN alias flushing, for VIPT caches */
17#define FLUSH_ALIAS_START 0xffff4000
18
19static inline void set_top_pte(unsigned long va, pte_t pte)
20{
21 pte_t *ptep = pte_offset_kernel(top_pmd, va);
22 set_pte_ext(ptep, pte, 0);
23 local_flush_tlb_kernel_page(va);
24}
25
26static inline pte_t get_top_pte(unsigned long va)
27{
28 pte_t *ptep = pte_offset_kernel(top_pmd, va);
29 return *ptep;
30}
7 31
8static inline pmd_t *pmd_off_k(unsigned long virt) 32static inline pmd_t *pmd_off_k(unsigned long virt)
9{ 33{
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index cd439c1dd506..b86f8933ff91 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -999,11 +999,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
999{ 999{
1000 struct map_desc map; 1000 struct map_desc map;
1001 unsigned long addr; 1001 unsigned long addr;
1002 void *vectors;
1002 1003
1003 /* 1004 /*
1004 * Allocate the vector page early. 1005 * Allocate the vector page early.
1005 */ 1006 */
1006 vectors_page = early_alloc(PAGE_SIZE); 1007 vectors = early_alloc(PAGE_SIZE);
1008
1009 early_trap_init(vectors);
1007 1010
1008 for (addr = VMALLOC_START; addr; addr += PMD_SIZE) 1011 for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
1009 pmd_clear(pmd_off_k(addr)); 1012 pmd_clear(pmd_off_k(addr));
@@ -1043,7 +1046,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
1043 * location (0xffff0000). If we aren't using high-vectors, also 1046 * location (0xffff0000). If we aren't using high-vectors, also
1044 * create a mapping at the low-vectors virtual address. 1047 * create a mapping at the low-vectors virtual address.
1045 */ 1048 */
1046 map.pfn = __phys_to_pfn(virt_to_phys(vectors_page)); 1049 map.pfn = __phys_to_pfn(virt_to_phys(vectors));
1047 map.virtual = 0xffff0000; 1050 map.virtual = 0xffff0000;
1048 map.length = PAGE_SIZE; 1051 map.length = PAGE_SIZE;
1049 map.type = MT_HIGH_VECTORS; 1052 map.type = MT_HIGH_VECTORS;
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 036fdbfdd62f..a631016e1f8f 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -1,5 +1,8 @@
1#include <linux/fs.h>
1#include <linux/spinlock.h> 2#include <linux/spinlock.h>
2#include <linux/list.h> 3#include <linux/list.h>
4#include <linux/proc_fs.h>
5#include <linux/seq_file.h>
3#include <linux/slab.h> 6#include <linux/slab.h>
4 7
5#include "vmregion.h" 8#include "vmregion.h"
@@ -36,7 +39,7 @@
36 39
37struct arm_vmregion * 40struct arm_vmregion *
38arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, 41arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
39 size_t size, gfp_t gfp) 42 size_t size, gfp_t gfp, const void *caller)
40{ 43{
41 unsigned long start = head->vm_start, addr = head->vm_end; 44 unsigned long start = head->vm_start, addr = head->vm_end;
42 unsigned long flags; 45 unsigned long flags;
@@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
52 if (!new) 55 if (!new)
53 goto out; 56 goto out;
54 57
58 new->caller = caller;
59
55 spin_lock_irqsave(&head->vm_lock, flags); 60 spin_lock_irqsave(&head->vm_lock, flags);
56 61
57 addr = rounddown(addr - size, align); 62 addr = rounddown(addr - size, align);
@@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
129 134
130 kfree(c); 135 kfree(c);
131} 136}
137
138#ifdef CONFIG_PROC_FS
139static int arm_vmregion_show(struct seq_file *m, void *p)
140{
141 struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list);
142
143 seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end,
144 c->vm_end - c->vm_start);
145 if (c->caller)
146 seq_printf(m, " %pS", (void *)c->caller);
147 seq_putc(m, '\n');
148 return 0;
149}
150
151static void *arm_vmregion_start(struct seq_file *m, loff_t *pos)
152{
153 struct arm_vmregion_head *h = m->private;
154 spin_lock_irq(&h->vm_lock);
155 return seq_list_start(&h->vm_list, *pos);
156}
157
158static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos)
159{
160 struct arm_vmregion_head *h = m->private;
161 return seq_list_next(p, &h->vm_list, pos);
162}
163
164static void arm_vmregion_stop(struct seq_file *m, void *p)
165{
166 struct arm_vmregion_head *h = m->private;
167 spin_unlock_irq(&h->vm_lock);
168}
169
170static const struct seq_operations arm_vmregion_ops = {
171 .start = arm_vmregion_start,
172 .stop = arm_vmregion_stop,
173 .next = arm_vmregion_next,
174 .show = arm_vmregion_show,
175};
176
177static int arm_vmregion_open(struct inode *inode, struct file *file)
178{
179 struct arm_vmregion_head *h = PDE(inode)->data;
180 int ret = seq_open(file, &arm_vmregion_ops);
181 if (!ret) {
182 struct seq_file *m = file->private_data;
183 m->private = h;
184 }
185 return ret;
186}
187
188static const struct file_operations arm_vmregion_fops = {
189 .open = arm_vmregion_open,
190 .read = seq_read,
191 .llseek = seq_lseek,
192 .release = seq_release,
193};
194
195int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
196{
197 proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h);
198 return 0;
199}
200#else
201int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
202{
203 return 0;
204}
205#endif
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 15e9f044db9f..162be662c088 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -19,11 +19,14 @@ struct arm_vmregion {
19 unsigned long vm_end; 19 unsigned long vm_end;
20 struct page *vm_pages; 20 struct page *vm_pages;
21 int vm_active; 21 int vm_active;
22 const void *caller;
22}; 23};
23 24
24struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t); 25struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *);
25struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); 26struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
26struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); 27struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
27void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); 28void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
28 29
30int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *);
31
29#endif 32#endif