aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/include/asm/Kbuild1
-rw-r--r--arch/alpha/include/asm/sections.h7
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/include/asm/pgtable-2level.h2
-rw-r--r--arch/arm/include/asm/pgtable-3level.h15
-rw-r--r--arch/arm/include/asm/pgtable.h6
-rw-r--r--arch/arm/include/asm/tlb.h38
-rw-r--r--arch/arm/kernel/hibernate.c3
-rw-r--r--arch/arm/mm/dma-mapping.c210
-rw-r--r--arch/arm/mm/flush.c15
-rw-r--r--arch/arm/mm/init.c2
-rw-r--r--arch/arm64/Kconfig5
-rw-r--r--arch/arm64/include/asm/pgtable.h21
-rw-r--r--arch/arm64/include/asm/tlb.h20
-rw-r--r--arch/arm64/mm/dma-mapping.c164
-rw-r--r--arch/arm64/mm/flush.c16
-rw-r--r--arch/cris/include/asm/Kbuild1
-rw-r--r--arch/cris/include/asm/sections.h7
-rw-r--r--arch/frv/include/asm/processor.h16
-rw-r--r--arch/frv/kernel/irq-mb93091.c8
-rw-r--r--arch/frv/kernel/irq-mb93093.c1
-rw-r--r--arch/frv/kernel/irq-mb93493.c4
-rw-r--r--arch/frv/kernel/setup.c2
-rw-r--r--arch/frv/kernel/time.c1
-rw-r--r--arch/m32r/include/asm/Kbuild1
-rw-r--r--arch/m32r/include/asm/sections.h7
-rw-r--r--arch/m32r/kernel/time.c1
-rw-r--r--arch/m68k/kernel/sys_m68k.c21
-rw-r--r--arch/mips/include/asm/suspend.h7
-rw-r--r--arch/mips/power/cpu.c2
-rw-r--r--arch/mn10300/include/asm/Kbuild1
-rw-r--r--arch/mn10300/include/asm/sections.h1
-rw-r--r--arch/powerpc/include/asm/pgtable.h57
-rw-r--r--arch/powerpc/include/asm/pte-common.h5
-rw-r--r--arch/powerpc/kernel/suspend.c4
-rw-r--r--arch/s390/kernel/suspend.c6
-rw-r--r--arch/score/include/asm/Kbuild1
-rw-r--r--arch/score/include/asm/sections.h6
-rw-r--r--arch/sh/include/asm/sections.h1
-rw-r--r--arch/sparc/power/hibernate.c4
-rw-r--r--arch/unicore32/include/mach/pm.h3
-rw-r--r--arch/unicore32/kernel/hibernate.c1
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/include/asm/pgtable_types.h14
-rw-r--r--arch/x86/power/hibernate_32.c4
-rw-r--r--arch/x86/power/hibernate_64.c4
46 files changed, 401 insertions, 322 deletions
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index a52cbf178c3a..25b49725df07 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -8,4 +8,5 @@ generic-y += irq_work.h
8generic-y += mcs_spinlock.h 8generic-y += mcs_spinlock.h
9generic-y += preempt.h 9generic-y += preempt.h
10generic-y += scatterlist.h 10generic-y += scatterlist.h
11generic-y += sections.h
11generic-y += trace_clock.h 12generic-y += trace_clock.h
diff --git a/arch/alpha/include/asm/sections.h b/arch/alpha/include/asm/sections.h
deleted file mode 100644
index 43b40edd6e44..000000000000
--- a/arch/alpha/include/asm/sections.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _ALPHA_SECTIONS_H
2#define _ALPHA_SECTIONS_H
3
4/* nothing to see, move along */
5#include <asm-generic/sections.h>
6
7#endif
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d9d32de9628c..18f392f8b744 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -14,6 +14,7 @@ config ARM
14 select CLONE_BACKWARDS 14 select CLONE_BACKWARDS
15 select CPU_PM if (SUSPEND || CPU_IDLE) 15 select CPU_PM if (SUSPEND || CPU_IDLE)
16 select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS 16 select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
17 select GENERIC_ALLOCATOR
17 select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) 18 select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
18 select GENERIC_CLOCKEVENTS_BROADCAST if SMP 19 select GENERIC_CLOCKEVENTS_BROADCAST if SMP
19 select GENERIC_IDLE_POLL_SETUP 20 select GENERIC_IDLE_POLL_SETUP
@@ -61,6 +62,7 @@ config ARM
61 select HAVE_PERF_EVENTS 62 select HAVE_PERF_EVENTS
62 select HAVE_PERF_REGS 63 select HAVE_PERF_REGS
63 select HAVE_PERF_USER_STACK_DUMP 64 select HAVE_PERF_USER_STACK_DUMP
65 select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE)
64 select HAVE_REGS_AND_STACK_ACCESS_API 66 select HAVE_REGS_AND_STACK_ACCESS_API
65 select HAVE_SYSCALL_TRACEPOINTS 67 select HAVE_SYSCALL_TRACEPOINTS
66 select HAVE_UID16 68 select HAVE_UID16
@@ -1659,6 +1661,10 @@ config ARCH_SELECT_MEMORY_MODEL
1659config HAVE_ARCH_PFN_VALID 1661config HAVE_ARCH_PFN_VALID
1660 def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM 1662 def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
1661 1663
1664config HAVE_GENERIC_RCU_GUP
1665 def_bool y
1666 depends on ARM_LPAE
1667
1662config HIGHMEM 1668config HIGHMEM
1663 bool "High Memory Support" 1669 bool "High Memory Support"
1664 depends on MMU 1670 depends on MMU
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 219ac88a9542..f0279411847d 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -182,6 +182,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
182#define pmd_addr_end(addr,end) (end) 182#define pmd_addr_end(addr,end) (end)
183 183
184#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 184#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
185#define pte_special(pte) (0)
186static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
185 187
186/* 188/*
187 * We don't have huge page support for short descriptors, for the moment 189 * We don't have huge page support for short descriptors, for the moment
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 06e0bc0f8b00..a31ecdad4b59 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -213,10 +213,19 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
213#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val))) 213#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))
214 214
215#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF)) 215#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))
216#define pte_special(pte) (pte_isset((pte), L_PTE_SPECIAL))
217static inline pte_t pte_mkspecial(pte_t pte)
218{
219 pte_val(pte) |= L_PTE_SPECIAL;
220 return pte;
221}
222#define __HAVE_ARCH_PTE_SPECIAL
216 223
217#define __HAVE_ARCH_PMD_WRITE 224#define __HAVE_ARCH_PMD_WRITE
218#define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY)) 225#define pmd_write(pmd) (pmd_isclear((pmd), L_PMD_SECT_RDONLY))
219#define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY)) 226#define pmd_dirty(pmd) (pmd_isset((pmd), L_PMD_SECT_DIRTY))
227#define pud_page(pud) pmd_page(__pmd(pud_val(pud)))
228#define pud_write(pud) pmd_write(__pmd(pud_val(pud)))
220 229
221#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd)) 230#define pmd_hugewillfault(pmd) (!pmd_young(pmd) || !pmd_write(pmd))
222#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd)) 231#define pmd_thp_or_huge(pmd) (pmd_huge(pmd) || pmd_trans_huge(pmd))
@@ -224,6 +233,12 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
224#ifdef CONFIG_TRANSPARENT_HUGEPAGE 233#ifdef CONFIG_TRANSPARENT_HUGEPAGE
225#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd)) 234#define pmd_trans_huge(pmd) (pmd_val(pmd) && !pmd_table(pmd))
226#define pmd_trans_splitting(pmd) (pmd_isset((pmd), L_PMD_SECT_SPLITTING)) 235#define pmd_trans_splitting(pmd) (pmd_isset((pmd), L_PMD_SECT_SPLITTING))
236
237#ifdef CONFIG_HAVE_RCU_TABLE_FREE
238#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
239void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
240 pmd_t *pmdp);
241#endif
227#endif 242#endif
228 243
229#define PMD_BIT_FUNC(fn,op) \ 244#define PMD_BIT_FUNC(fn,op) \
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 01baef07cd0c..90aa4583b308 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -226,7 +226,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
226#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY)) 226#define pte_dirty(pte) (pte_isset((pte), L_PTE_DIRTY))
227#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG)) 227#define pte_young(pte) (pte_isset((pte), L_PTE_YOUNG))
228#define pte_exec(pte) (pte_isclear((pte), L_PTE_XN)) 228#define pte_exec(pte) (pte_isclear((pte), L_PTE_XN))
229#define pte_special(pte) (0)
230 229
231#define pte_valid_user(pte) \ 230#define pte_valid_user(pte) \
232 (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte)) 231 (pte_valid(pte) && pte_isset((pte), L_PTE_USER) && pte_young(pte))
@@ -245,7 +244,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
245 unsigned long ext = 0; 244 unsigned long ext = 0;
246 245
247 if (addr < TASK_SIZE && pte_valid_user(pteval)) { 246 if (addr < TASK_SIZE && pte_valid_user(pteval)) {
248 __sync_icache_dcache(pteval); 247 if (!pte_special(pteval))
248 __sync_icache_dcache(pteval);
249 ext |= PTE_EXT_NG; 249 ext |= PTE_EXT_NG;
250 } 250 }
251 251
@@ -264,8 +264,6 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
264PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); 264PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN);
265PTE_BIT_FUNC(mknexec, |= L_PTE_XN); 265PTE_BIT_FUNC(mknexec, |= L_PTE_XN);
266 266
267static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
268
269static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 267static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
270{ 268{
271 const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | 269 const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index f1a0dace3efe..3cadb726ec88 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -35,12 +35,39 @@
35 35
36#define MMU_GATHER_BUNDLE 8 36#define MMU_GATHER_BUNDLE 8
37 37
38#ifdef CONFIG_HAVE_RCU_TABLE_FREE
39static inline void __tlb_remove_table(void *_table)
40{
41 free_page_and_swap_cache((struct page *)_table);
42}
43
44struct mmu_table_batch {
45 struct rcu_head rcu;
46 unsigned int nr;
47 void *tables[0];
48};
49
50#define MAX_TABLE_BATCH \
51 ((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
52
53extern void tlb_table_flush(struct mmu_gather *tlb);
54extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
55
56#define tlb_remove_entry(tlb, entry) tlb_remove_table(tlb, entry)
57#else
58#define tlb_remove_entry(tlb, entry) tlb_remove_page(tlb, entry)
59#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
60
38/* 61/*
39 * TLB handling. This allows us to remove pages from the page 62 * TLB handling. This allows us to remove pages from the page
40 * tables, and efficiently handle the TLB issues. 63 * tables, and efficiently handle the TLB issues.
41 */ 64 */
42struct mmu_gather { 65struct mmu_gather {
43 struct mm_struct *mm; 66 struct mm_struct *mm;
67#ifdef CONFIG_HAVE_RCU_TABLE_FREE
68 struct mmu_table_batch *batch;
69 unsigned int need_flush;
70#endif
44 unsigned int fullmm; 71 unsigned int fullmm;
45 struct vm_area_struct *vma; 72 struct vm_area_struct *vma;
46 unsigned long start, end; 73 unsigned long start, end;
@@ -101,6 +128,9 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
101static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) 128static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
102{ 129{
103 tlb_flush(tlb); 130 tlb_flush(tlb);
131#ifdef CONFIG_HAVE_RCU_TABLE_FREE
132 tlb_table_flush(tlb);
133#endif
104} 134}
105 135
106static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) 136static inline void tlb_flush_mmu_free(struct mmu_gather *tlb)
@@ -129,6 +159,10 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
129 tlb->pages = tlb->local; 159 tlb->pages = tlb->local;
130 tlb->nr = 0; 160 tlb->nr = 0;
131 __tlb_alloc_page(tlb); 161 __tlb_alloc_page(tlb);
162
163#ifdef CONFIG_HAVE_RCU_TABLE_FREE
164 tlb->batch = NULL;
165#endif
132} 166}
133 167
134static inline void 168static inline void
@@ -205,7 +239,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
205 tlb_add_flush(tlb, addr + SZ_1M); 239 tlb_add_flush(tlb, addr + SZ_1M);
206#endif 240#endif
207 241
208 tlb_remove_page(tlb, pte); 242 tlb_remove_entry(tlb, pte);
209} 243}
210 244
211static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, 245static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
@@ -213,7 +247,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
213{ 247{
214#ifdef CONFIG_ARM_LPAE 248#ifdef CONFIG_ARM_LPAE
215 tlb_add_flush(tlb, addr); 249 tlb_add_flush(tlb, addr);
216 tlb_remove_page(tlb, virt_to_page(pmdp)); 250 tlb_remove_entry(tlb, virt_to_page(pmdp));
217#endif 251#endif
218} 252}
219 253
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
index bb8b79648643..c4cc50e58c13 100644
--- a/arch/arm/kernel/hibernate.c
+++ b/arch/arm/kernel/hibernate.c
@@ -21,8 +21,7 @@
21#include <asm/idmap.h> 21#include <asm/idmap.h>
22#include <asm/suspend.h> 22#include <asm/suspend.h>
23#include <asm/memory.h> 23#include <asm/memory.h>
24 24#include <asm/sections.h>
25extern const void __nosave_begin, __nosave_end;
26 25
27int pfn_is_nosave(unsigned long pfn) 26int pfn_is_nosave(unsigned long pfn)
28{ 27{
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7a996aaa061e..c245d903927f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -12,6 +12,7 @@
12#include <linux/bootmem.h> 12#include <linux/bootmem.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/genalloc.h>
15#include <linux/gfp.h> 16#include <linux/gfp.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/list.h> 18#include <linux/list.h>
@@ -298,57 +299,29 @@ static void *
298__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, 299__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
299 const void *caller) 300 const void *caller)
300{ 301{
301 struct vm_struct *area;
302 unsigned long addr;
303
304 /* 302 /*
305 * DMA allocation can be mapped to user space, so lets 303 * DMA allocation can be mapped to user space, so lets
306 * set VM_USERMAP flags too. 304 * set VM_USERMAP flags too.
307 */ 305 */
308 area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, 306 return dma_common_contiguous_remap(page, size,
309 caller); 307 VM_ARM_DMA_CONSISTENT | VM_USERMAP,
310 if (!area) 308 prot, caller);
311 return NULL;
312 addr = (unsigned long)area->addr;
313 area->phys_addr = __pfn_to_phys(page_to_pfn(page));
314
315 if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) {
316 vunmap((void *)addr);
317 return NULL;
318 }
319 return (void *)addr;
320} 309}
321 310
322static void __dma_free_remap(void *cpu_addr, size_t size) 311static void __dma_free_remap(void *cpu_addr, size_t size)
323{ 312{
324 unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP; 313 dma_common_free_remap(cpu_addr, size,
325 struct vm_struct *area = find_vm_area(cpu_addr); 314 VM_ARM_DMA_CONSISTENT | VM_USERMAP);
326 if (!area || (area->flags & flags) != flags) {
327 WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
328 return;
329 }
330 unmap_kernel_range((unsigned long)cpu_addr, size);
331 vunmap(cpu_addr);
332} 315}
333 316
334#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K 317#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
318static struct gen_pool *atomic_pool;
335 319
336struct dma_pool { 320static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
337 size_t size;
338 spinlock_t lock;
339 unsigned long *bitmap;
340 unsigned long nr_pages;
341 void *vaddr;
342 struct page **pages;
343};
344
345static struct dma_pool atomic_pool = {
346 .size = DEFAULT_DMA_COHERENT_POOL_SIZE,
347};
348 321
349static int __init early_coherent_pool(char *p) 322static int __init early_coherent_pool(char *p)
350{ 323{
351 atomic_pool.size = memparse(p, &p); 324 atomic_pool_size = memparse(p, &p);
352 return 0; 325 return 0;
353} 326}
354early_param("coherent_pool", early_coherent_pool); 327early_param("coherent_pool", early_coherent_pool);
@@ -358,14 +331,14 @@ void __init init_dma_coherent_pool_size(unsigned long size)
358 /* 331 /*
359 * Catch any attempt to set the pool size too late. 332 * Catch any attempt to set the pool size too late.
360 */ 333 */
361 BUG_ON(atomic_pool.vaddr); 334 BUG_ON(atomic_pool);
362 335
363 /* 336 /*
364 * Set architecture specific coherent pool size only if 337 * Set architecture specific coherent pool size only if
365 * it has not been changed by kernel command line parameter. 338 * it has not been changed by kernel command line parameter.
366 */ 339 */
367 if (atomic_pool.size == DEFAULT_DMA_COHERENT_POOL_SIZE) 340 if (atomic_pool_size == DEFAULT_DMA_COHERENT_POOL_SIZE)
368 atomic_pool.size = size; 341 atomic_pool_size = size;
369} 342}
370 343
371/* 344/*
@@ -373,52 +346,44 @@ void __init init_dma_coherent_pool_size(unsigned long size)
373 */ 346 */
374static int __init atomic_pool_init(void) 347static int __init atomic_pool_init(void)
375{ 348{
376 struct dma_pool *pool = &atomic_pool;
377 pgprot_t prot = pgprot_dmacoherent(PAGE_KERNEL); 349 pgprot_t prot = pgprot_dmacoherent(PAGE_KERNEL);
378 gfp_t gfp = GFP_KERNEL | GFP_DMA; 350 gfp_t gfp = GFP_KERNEL | GFP_DMA;
379 unsigned long nr_pages = pool->size >> PAGE_SHIFT;
380 unsigned long *bitmap;
381 struct page *page; 351 struct page *page;
382 struct page **pages;
383 void *ptr; 352 void *ptr;
384 int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long);
385 353
386 bitmap = kzalloc(bitmap_size, GFP_KERNEL); 354 atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
387 if (!bitmap) 355 if (!atomic_pool)
388 goto no_bitmap; 356 goto out;
389
390 pages = kzalloc(nr_pages * sizeof(struct page *), GFP_KERNEL);
391 if (!pages)
392 goto no_pages;
393 357
394 if (dev_get_cma_area(NULL)) 358 if (dev_get_cma_area(NULL))
395 ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page, 359 ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
396 atomic_pool_init); 360 &page, atomic_pool_init);
397 else 361 else
398 ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page, 362 ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
399 atomic_pool_init); 363 &page, atomic_pool_init);
400 if (ptr) { 364 if (ptr) {
401 int i; 365 int ret;
402 366
403 for (i = 0; i < nr_pages; i++) 367 ret = gen_pool_add_virt(atomic_pool, (unsigned long)ptr,
404 pages[i] = page + i; 368 page_to_phys(page),
405 369 atomic_pool_size, -1);
406 spin_lock_init(&pool->lock); 370 if (ret)
407 pool->vaddr = ptr; 371 goto destroy_genpool;
408 pool->pages = pages; 372
409 pool->bitmap = bitmap; 373 gen_pool_set_algo(atomic_pool,
410 pool->nr_pages = nr_pages; 374 gen_pool_first_fit_order_align,
411 pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", 375 (void *)PAGE_SHIFT);
412 (unsigned)pool->size / 1024); 376 pr_info("DMA: preallocated %zd KiB pool for atomic coherent allocations\n",
377 atomic_pool_size / 1024);
413 return 0; 378 return 0;
414 } 379 }
415 380
416 kfree(pages); 381destroy_genpool:
417no_pages: 382 gen_pool_destroy(atomic_pool);
418 kfree(bitmap); 383 atomic_pool = NULL;
419no_bitmap: 384out:
420 pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", 385 pr_err("DMA: failed to allocate %zx KiB pool for atomic coherent allocation\n",
421 (unsigned)pool->size / 1024); 386 atomic_pool_size / 1024);
422 return -ENOMEM; 387 return -ENOMEM;
423} 388}
424/* 389/*
@@ -522,76 +487,36 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
522 487
523static void *__alloc_from_pool(size_t size, struct page **ret_page) 488static void *__alloc_from_pool(size_t size, struct page **ret_page)
524{ 489{
525 struct dma_pool *pool = &atomic_pool; 490 unsigned long val;
526 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
527 unsigned int pageno;
528 unsigned long flags;
529 void *ptr = NULL; 491 void *ptr = NULL;
530 unsigned long align_mask;
531 492
532 if (!pool->vaddr) { 493 if (!atomic_pool) {
533 WARN(1, "coherent pool not initialised!\n"); 494 WARN(1, "coherent pool not initialised!\n");
534 return NULL; 495 return NULL;
535 } 496 }
536 497
537 /* 498 val = gen_pool_alloc(atomic_pool, size);
538 * Align the region allocation - allocations from pool are rather 499 if (val) {
539 * small, so align them to their order in pages, minimum is a page 500 phys_addr_t phys = gen_pool_virt_to_phys(atomic_pool, val);
540 * size. This helps reduce fragmentation of the DMA space. 501
541 */ 502 *ret_page = phys_to_page(phys);
542 align_mask = (1 << get_order(size)) - 1; 503 ptr = (void *)val;
543
544 spin_lock_irqsave(&pool->lock, flags);
545 pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages,
546 0, count, align_mask);
547 if (pageno < pool->nr_pages) {
548 bitmap_set(pool->bitmap, pageno, count);
549 ptr = pool->vaddr + PAGE_SIZE * pageno;
550 *ret_page = pool->pages[pageno];
551 } else {
552 pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n"
553 "Please increase it with coherent_pool= kernel parameter!\n",
554 (unsigned)pool->size / 1024);
555 } 504 }
556 spin_unlock_irqrestore(&pool->lock, flags);
557 505
558 return ptr; 506 return ptr;
559} 507}
560 508
561static bool __in_atomic_pool(void *start, size_t size) 509static bool __in_atomic_pool(void *start, size_t size)
562{ 510{
563 struct dma_pool *pool = &atomic_pool; 511 return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
564 void *end = start + size;
565 void *pool_start = pool->vaddr;
566 void *pool_end = pool->vaddr + pool->size;
567
568 if (start < pool_start || start >= pool_end)
569 return false;
570
571 if (end <= pool_end)
572 return true;
573
574 WARN(1, "Wrong coherent size(%p-%p) from atomic pool(%p-%p)\n",
575 start, end - 1, pool_start, pool_end - 1);
576
577 return false;
578} 512}
579 513
580static int __free_from_pool(void *start, size_t size) 514static int __free_from_pool(void *start, size_t size)
581{ 515{
582 struct dma_pool *pool = &atomic_pool;
583 unsigned long pageno, count;
584 unsigned long flags;
585
586 if (!__in_atomic_pool(start, size)) 516 if (!__in_atomic_pool(start, size))
587 return 0; 517 return 0;
588 518
589 pageno = (start - pool->vaddr) >> PAGE_SHIFT; 519 gen_pool_free(atomic_pool, (unsigned long)start, size);
590 count = size >> PAGE_SHIFT;
591
592 spin_lock_irqsave(&pool->lock, flags);
593 bitmap_clear(pool->bitmap, pageno, count);
594 spin_unlock_irqrestore(&pool->lock, flags);
595 520
596 return 1; 521 return 1;
597} 522}
@@ -1271,29 +1196,8 @@ static void *
1271__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, 1196__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
1272 const void *caller) 1197 const void *caller)
1273{ 1198{
1274 unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 1199 return dma_common_pages_remap(pages, size,
1275 struct vm_struct *area; 1200 VM_ARM_DMA_CONSISTENT | VM_USERMAP, prot, caller);
1276 unsigned long p;
1277
1278 area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
1279 caller);
1280 if (!area)
1281 return NULL;
1282
1283 area->pages = pages;
1284 area->nr_pages = nr_pages;
1285 p = (unsigned long)area->addr;
1286
1287 for (i = 0; i < nr_pages; i++) {
1288 phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i]));
1289 if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot))
1290 goto err;
1291 p += PAGE_SIZE;
1292 }
1293 return area->addr;
1294err:
1295 unmap_kernel_range((unsigned long)area->addr, size);
1296 vunmap(area->addr);
1297 return NULL; 1201 return NULL;
1298} 1202}
1299 1203
@@ -1355,11 +1259,13 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si
1355 1259
1356static struct page **__atomic_get_pages(void *addr) 1260static struct page **__atomic_get_pages(void *addr)
1357{ 1261{
1358 struct dma_pool *pool = &atomic_pool; 1262 struct page *page;
1359 struct page **pages = pool->pages; 1263 phys_addr_t phys;
1360 int offs = (addr - pool->vaddr) >> PAGE_SHIFT; 1264
1265 phys = gen_pool_virt_to_phys(atomic_pool, (unsigned long)addr);
1266 page = phys_to_page(phys);
1361 1267
1362 return pages + offs; 1268 return (struct page **)page;
1363} 1269}
1364 1270
1365static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) 1271static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
@@ -1501,8 +1407,8 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
1501 } 1407 }
1502 1408
1503 if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) { 1409 if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {
1504 unmap_kernel_range((unsigned long)cpu_addr, size); 1410 dma_common_free_remap(cpu_addr, size,
1505 vunmap(cpu_addr); 1411 VM_ARM_DMA_CONSISTENT | VM_USERMAP);
1506 } 1412 }
1507 1413
1508 __iommu_remove_mapping(dev, handle, size); 1414 __iommu_remove_mapping(dev, handle, size);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 43d54f5b26b9..265b836b3bd1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -400,3 +400,18 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l
400 */ 400 */
401 __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); 401 __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
402} 402}
403
404#ifdef CONFIG_TRANSPARENT_HUGEPAGE
405#ifdef CONFIG_HAVE_RCU_TABLE_FREE
406void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
407 pmd_t *pmdp)
408{
409 pmd_t pmd = pmd_mksplitting(*pmdp);
410 VM_BUG_ON(address & ~PMD_MASK);
411 set_pmd_at(vma->vm_mm, address, pmdp, pmd);
412
413 /* dummy IPI to serialise against fast_gup */
414 kick_all_cpus_sync();
415}
416#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
417#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 9221645dd192..92bba32d9230 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -322,7 +322,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
322 * reserve memory for DMA contigouos allocations, 322 * reserve memory for DMA contigouos allocations,
323 * must come from DMA area inside low memory 323 * must come from DMA area inside low memory
324 */ 324 */
325 dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit)); 325 dma_contiguous_reserve(arm_dma_limit);
326 326
327 arm_memblock_steal_permitted = false; 327 arm_memblock_steal_permitted = false;
328 memblock_dump_all(); 328 memblock_dump_all();
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3f0e854d0ff4..c49ca4c738bb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -18,6 +18,7 @@ config ARM64
18 select COMMON_CLK 18 select COMMON_CLK
19 select CPU_PM if (SUSPEND || CPU_IDLE) 19 select CPU_PM if (SUSPEND || CPU_IDLE)
20 select DCACHE_WORD_ACCESS 20 select DCACHE_WORD_ACCESS
21 select GENERIC_ALLOCATOR
21 select GENERIC_CLOCKEVENTS 22 select GENERIC_CLOCKEVENTS
22 select GENERIC_CLOCKEVENTS_BROADCAST if SMP 23 select GENERIC_CLOCKEVENTS_BROADCAST if SMP
23 select GENERIC_CPU_AUTOPROBE 24 select GENERIC_CPU_AUTOPROBE
@@ -56,6 +57,7 @@ config ARM64
56 select HAVE_PERF_EVENTS 57 select HAVE_PERF_EVENTS
57 select HAVE_PERF_REGS 58 select HAVE_PERF_REGS
58 select HAVE_PERF_USER_STACK_DUMP 59 select HAVE_PERF_USER_STACK_DUMP
60 select HAVE_RCU_TABLE_FREE
59 select HAVE_SYSCALL_TRACEPOINTS 61 select HAVE_SYSCALL_TRACEPOINTS
60 select IRQ_DOMAIN 62 select IRQ_DOMAIN
61 select MODULES_USE_ELF_RELA 63 select MODULES_USE_ELF_RELA
@@ -109,6 +111,9 @@ config GENERIC_CALIBRATE_DELAY
109config ZONE_DMA 111config ZONE_DMA
110 def_bool y 112 def_bool y
111 113
114config HAVE_GENERIC_RCU_GUP
115 def_bool y
116
112config ARCH_DMA_ADDR_T_64BIT 117config ARCH_DMA_ADDR_T_64BIT
113 def_bool y 118 def_bool y
114 119
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 77dbe1e6398d..cefd3e825612 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -244,6 +244,16 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
244 244
245#define __HAVE_ARCH_PTE_SPECIAL 245#define __HAVE_ARCH_PTE_SPECIAL
246 246
247static inline pte_t pud_pte(pud_t pud)
248{
249 return __pte(pud_val(pud));
250}
251
252static inline pmd_t pud_pmd(pud_t pud)
253{
254 return __pmd(pud_val(pud));
255}
256
247static inline pte_t pmd_pte(pmd_t pmd) 257static inline pte_t pmd_pte(pmd_t pmd)
248{ 258{
249 return __pte(pmd_val(pmd)); 259 return __pte(pmd_val(pmd));
@@ -261,7 +271,13 @@ static inline pmd_t pte_pmd(pte_t pte)
261#ifdef CONFIG_TRANSPARENT_HUGEPAGE 271#ifdef CONFIG_TRANSPARENT_HUGEPAGE
262#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) 272#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
263#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd)) 273#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
264#endif 274#ifdef CONFIG_HAVE_RCU_TABLE_FREE
275#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
276struct vm_area_struct;
277void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
278 pmd_t *pmdp);
279#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
280#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
265 281
266#define pmd_young(pmd) pte_young(pmd_pte(pmd)) 282#define pmd_young(pmd) pte_young(pmd_pte(pmd))
267#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) 283#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
@@ -282,6 +298,7 @@ static inline pmd_t pte_pmd(pte_t pte)
282#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) 298#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
283 299
284#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) 300#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
301#define pud_write(pud) pte_write(pud_pte(pud))
285#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT) 302#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
286 303
287#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd)) 304#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
@@ -383,6 +400,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
383 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); 400 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
384} 401}
385 402
403#define pud_page(pud) pmd_page(pud_pmd(pud))
404
386#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */ 405#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */
387 406
388#if CONFIG_ARM64_PGTABLE_LEVELS > 3 407#if CONFIG_ARM64_PGTABLE_LEVELS > 3
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 62731ef9749a..a82c0c5c8b52 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -23,6 +23,20 @@
23 23
24#include <asm-generic/tlb.h> 24#include <asm-generic/tlb.h>
25 25
26#include <linux/pagemap.h>
27#include <linux/swap.h>
28
29#ifdef CONFIG_HAVE_RCU_TABLE_FREE
30
31#define tlb_remove_entry(tlb, entry) tlb_remove_table(tlb, entry)
32static inline void __tlb_remove_table(void *_table)
33{
34 free_page_and_swap_cache((struct page *)_table);
35}
36#else
37#define tlb_remove_entry(tlb, entry) tlb_remove_page(tlb, entry)
38#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
39
26/* 40/*
27 * There's three ways the TLB shootdown code is used: 41 * There's three ways the TLB shootdown code is used:
28 * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region(). 42 * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region().
@@ -88,7 +102,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
88{ 102{
89 pgtable_page_dtor(pte); 103 pgtable_page_dtor(pte);
90 tlb_add_flush(tlb, addr); 104 tlb_add_flush(tlb, addr);
91 tlb_remove_page(tlb, pte); 105 tlb_remove_entry(tlb, pte);
92} 106}
93 107
94#if CONFIG_ARM64_PGTABLE_LEVELS > 2 108#if CONFIG_ARM64_PGTABLE_LEVELS > 2
@@ -96,7 +110,7 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
96 unsigned long addr) 110 unsigned long addr)
97{ 111{
98 tlb_add_flush(tlb, addr); 112 tlb_add_flush(tlb, addr);
99 tlb_remove_page(tlb, virt_to_page(pmdp)); 113 tlb_remove_entry(tlb, virt_to_page(pmdp));
100} 114}
101#endif 115#endif
102 116
@@ -105,7 +119,7 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
105 unsigned long addr) 119 unsigned long addr)
106{ 120{
107 tlb_add_flush(tlb, addr); 121 tlb_add_flush(tlb, addr);
108 tlb_remove_page(tlb, virt_to_page(pudp)); 122 tlb_remove_entry(tlb, virt_to_page(pudp));
109} 123}
110#endif 124#endif
111 125
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 2c71077cacfd..d92094203913 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -20,6 +20,7 @@
20#include <linux/gfp.h> 20#include <linux/gfp.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/genalloc.h>
23#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
24#include <linux/dma-contiguous.h> 25#include <linux/dma-contiguous.h>
25#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
@@ -38,6 +39,54 @@ static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
38 return prot; 39 return prot;
39} 40}
40 41
42static struct gen_pool *atomic_pool;
43
44#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
45static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
46
47static int __init early_coherent_pool(char *p)
48{
49 atomic_pool_size = memparse(p, &p);
50 return 0;
51}
52early_param("coherent_pool", early_coherent_pool);
53
54static void *__alloc_from_pool(size_t size, struct page **ret_page)
55{
56 unsigned long val;
57 void *ptr = NULL;
58
59 if (!atomic_pool) {
60 WARN(1, "coherent pool not initialised!\n");
61 return NULL;
62 }
63
64 val = gen_pool_alloc(atomic_pool, size);
65 if (val) {
66 phys_addr_t phys = gen_pool_virt_to_phys(atomic_pool, val);
67
68 *ret_page = phys_to_page(phys);
69 ptr = (void *)val;
70 }
71
72 return ptr;
73}
74
75static bool __in_atomic_pool(void *start, size_t size)
76{
77 return addr_in_gen_pool(atomic_pool, (unsigned long)start, size);
78}
79
80static int __free_from_pool(void *start, size_t size)
81{
82 if (!__in_atomic_pool(start, size))
83 return 0;
84
85 gen_pool_free(atomic_pool, (unsigned long)start, size);
86
87 return 1;
88}
89
41static void *__dma_alloc_coherent(struct device *dev, size_t size, 90static void *__dma_alloc_coherent(struct device *dev, size_t size,
42 dma_addr_t *dma_handle, gfp_t flags, 91 dma_addr_t *dma_handle, gfp_t flags,
43 struct dma_attrs *attrs) 92 struct dma_attrs *attrs)
@@ -50,7 +99,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
50 if (IS_ENABLED(CONFIG_ZONE_DMA) && 99 if (IS_ENABLED(CONFIG_ZONE_DMA) &&
51 dev->coherent_dma_mask <= DMA_BIT_MASK(32)) 100 dev->coherent_dma_mask <= DMA_BIT_MASK(32))
52 flags |= GFP_DMA; 101 flags |= GFP_DMA;
53 if (IS_ENABLED(CONFIG_DMA_CMA)) { 102 if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) {
54 struct page *page; 103 struct page *page;
55 104
56 size = PAGE_ALIGN(size); 105 size = PAGE_ALIGN(size);
@@ -70,50 +119,54 @@ static void __dma_free_coherent(struct device *dev, size_t size,
70 void *vaddr, dma_addr_t dma_handle, 119 void *vaddr, dma_addr_t dma_handle,
71 struct dma_attrs *attrs) 120 struct dma_attrs *attrs)
72{ 121{
122 bool freed;
123 phys_addr_t paddr = dma_to_phys(dev, dma_handle);
124
73 if (dev == NULL) { 125 if (dev == NULL) {
74 WARN_ONCE(1, "Use an actual device structure for DMA allocation\n"); 126 WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
75 return; 127 return;
76 } 128 }
77 129
78 if (IS_ENABLED(CONFIG_DMA_CMA)) { 130 freed = dma_release_from_contiguous(dev,
79 phys_addr_t paddr = dma_to_phys(dev, dma_handle);
80
81 dma_release_from_contiguous(dev,
82 phys_to_page(paddr), 131 phys_to_page(paddr),
83 size >> PAGE_SHIFT); 132 size >> PAGE_SHIFT);
84 } else { 133 if (!freed)
85 swiotlb_free_coherent(dev, size, vaddr, dma_handle); 134 swiotlb_free_coherent(dev, size, vaddr, dma_handle);
86 }
87} 135}
88 136
89static void *__dma_alloc_noncoherent(struct device *dev, size_t size, 137static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
90 dma_addr_t *dma_handle, gfp_t flags, 138 dma_addr_t *dma_handle, gfp_t flags,
91 struct dma_attrs *attrs) 139 struct dma_attrs *attrs)
92{ 140{
93 struct page *page, **map; 141 struct page *page;
94 void *ptr, *coherent_ptr; 142 void *ptr, *coherent_ptr;
95 int order, i;
96 143
97 size = PAGE_ALIGN(size); 144 size = PAGE_ALIGN(size);
98 order = get_order(size); 145
146 if (!(flags & __GFP_WAIT)) {
147 struct page *page = NULL;
148 void *addr = __alloc_from_pool(size, &page);
149
150 if (addr)
151 *dma_handle = phys_to_dma(dev, page_to_phys(page));
152
153 return addr;
154
155 }
99 156
100 ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs); 157 ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
101 if (!ptr) 158 if (!ptr)
102 goto no_mem; 159 goto no_mem;
103 map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA);
104 if (!map)
105 goto no_map;
106 160
107 /* remove any dirty cache lines on the kernel alias */ 161 /* remove any dirty cache lines on the kernel alias */
108 __dma_flush_range(ptr, ptr + size); 162 __dma_flush_range(ptr, ptr + size);
109 163
110 /* create a coherent mapping */ 164 /* create a coherent mapping */
111 page = virt_to_page(ptr); 165 page = virt_to_page(ptr);
112 for (i = 0; i < (size >> PAGE_SHIFT); i++) 166 coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
113 map[i] = page + i; 167 __get_dma_pgprot(attrs,
114 coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP, 168 __pgprot(PROT_NORMAL_NC), false),
115 __get_dma_pgprot(attrs, __pgprot(PROT_NORMAL_NC), false)); 169 NULL);
116 kfree(map);
117 if (!coherent_ptr) 170 if (!coherent_ptr)
118 goto no_map; 171 goto no_map;
119 172
@@ -132,6 +185,8 @@ static void __dma_free_noncoherent(struct device *dev, size_t size,
132{ 185{
133 void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle)); 186 void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
134 187
188 if (__free_from_pool(vaddr, size))
189 return;
135 vunmap(vaddr); 190 vunmap(vaddr);
136 __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs); 191 __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
137} 192}
@@ -307,6 +362,67 @@ EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
307 362
308extern int swiotlb_late_init_with_default_size(size_t default_size); 363extern int swiotlb_late_init_with_default_size(size_t default_size);
309 364
365static int __init atomic_pool_init(void)
366{
367 pgprot_t prot = __pgprot(PROT_NORMAL_NC);
368 unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
369 struct page *page;
370 void *addr;
371 unsigned int pool_size_order = get_order(atomic_pool_size);
372
373 if (dev_get_cma_area(NULL))
374 page = dma_alloc_from_contiguous(NULL, nr_pages,
375 pool_size_order);
376 else
377 page = alloc_pages(GFP_DMA, pool_size_order);
378
379 if (page) {
380 int ret;
381 void *page_addr = page_address(page);
382
383 memset(page_addr, 0, atomic_pool_size);
384 __dma_flush_range(page_addr, page_addr + atomic_pool_size);
385
386 atomic_pool = gen_pool_create(PAGE_SHIFT, -1);
387 if (!atomic_pool)
388 goto free_page;
389
390 addr = dma_common_contiguous_remap(page, atomic_pool_size,
391 VM_USERMAP, prot, atomic_pool_init);
392
393 if (!addr)
394 goto destroy_genpool;
395
396 ret = gen_pool_add_virt(atomic_pool, (unsigned long)addr,
397 page_to_phys(page),
398 atomic_pool_size, -1);
399 if (ret)
400 goto remove_mapping;
401
402 gen_pool_set_algo(atomic_pool,
403 gen_pool_first_fit_order_align,
404 (void *)PAGE_SHIFT);
405
406 pr_info("DMA: preallocated %zu KiB pool for atomic allocations\n",
407 atomic_pool_size / 1024);
408 return 0;
409 }
410 goto out;
411
412remove_mapping:
413 dma_common_free_remap(addr, atomic_pool_size, VM_USERMAP);
414destroy_genpool:
415 gen_pool_destroy(atomic_pool);
416 atomic_pool = NULL;
417free_page:
418 if (!dma_release_from_contiguous(NULL, page, nr_pages))
419 __free_pages(page, pool_size_order);
420out:
421 pr_err("DMA: failed to allocate %zu KiB pool for atomic coherent allocation\n",
422 atomic_pool_size / 1024);
423 return -ENOMEM;
424}
425
310static int __init swiotlb_late_init(void) 426static int __init swiotlb_late_init(void)
311{ 427{
312 size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); 428 size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
@@ -315,7 +431,17 @@ static int __init swiotlb_late_init(void)
315 431
316 return swiotlb_late_init_with_default_size(swiotlb_size); 432 return swiotlb_late_init_with_default_size(swiotlb_size);
317} 433}
318arch_initcall(swiotlb_late_init); 434
435static int __init arm64_dma_init(void)
436{
437 int ret = 0;
438
439 ret |= swiotlb_late_init();
440 ret |= atomic_pool_init();
441
442 return ret;
443}
444arch_initcall(arm64_dma_init);
319 445
320#define PREALLOC_DMA_DEBUG_ENTRIES 4096 446#define PREALLOC_DMA_DEBUG_ENTRIES 4096
321 447
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index 0d64089d28b5..b6f14e8d2121 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -104,3 +104,19 @@ EXPORT_SYMBOL(flush_dcache_page);
104 */ 104 */
105EXPORT_SYMBOL(flush_cache_all); 105EXPORT_SYMBOL(flush_cache_all);
106EXPORT_SYMBOL(flush_icache_range); 106EXPORT_SYMBOL(flush_icache_range);
107
108#ifdef CONFIG_TRANSPARENT_HUGEPAGE
109#ifdef CONFIG_HAVE_RCU_TABLE_FREE
110void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
111 pmd_t *pmdp)
112{
113 pmd_t pmd = pmd_mksplitting(*pmdp);
114
115 VM_BUG_ON(address & ~PMD_MASK);
116 set_pmd_at(vma->vm_mm, address, pmdp, pmd);
117
118 /* dummy IPI to serialise against fast_gup */
119 kick_all_cpus_sync();
120}
121#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
122#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 802b94c4ca86..2ca489eaadd3 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -15,6 +15,7 @@ generic-y += mcs_spinlock.h
15generic-y += module.h 15generic-y += module.h
16generic-y += preempt.h 16generic-y += preempt.h
17generic-y += scatterlist.h 17generic-y += scatterlist.h
18generic-y += sections.h
18generic-y += trace_clock.h 19generic-y += trace_clock.h
19generic-y += vga.h 20generic-y += vga.h
20generic-y += xor.h 21generic-y += xor.h
diff --git a/arch/cris/include/asm/sections.h b/arch/cris/include/asm/sections.h
deleted file mode 100644
index 2c998ce8967b..000000000000
--- a/arch/cris/include/asm/sections.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _CRIS_SECTIONS_H
2#define _CRIS_SECTIONS_H
3
4/* nothing to see, move along */
5#include <asm-generic/sections.h>
6
7#endif
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
index 6554e78893f2..ae8d423e79d9 100644
--- a/arch/frv/include/asm/processor.h
+++ b/arch/frv/include/asm/processor.h
@@ -35,22 +35,6 @@
35struct task_struct; 35struct task_struct;
36 36
37/* 37/*
38 * CPU type and hardware bug flags. Kept separately for each CPU.
39 */
40struct cpuinfo_frv {
41#ifdef CONFIG_MMU
42 unsigned long *pgd_quick;
43 unsigned long *pte_quick;
44 unsigned long pgtable_cache_sz;
45#endif
46} __cacheline_aligned;
47
48extern struct cpuinfo_frv __nongprelbss boot_cpu_data;
49
50#define cpu_data (&boot_cpu_data)
51#define current_cpu_data boot_cpu_data
52
53/*
54 * Bus types 38 * Bus types
55 */ 39 */
56#define EISA_bus 0 40#define EISA_bus 0
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 2cc327a1ca44..091b2839be90 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -107,25 +107,25 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask)
107static struct irqaction fpga_irq[4] = { 107static struct irqaction fpga_irq[4] = {
108 [0] = { 108 [0] = {
109 .handler = fpga_interrupt, 109 .handler = fpga_interrupt,
110 .flags = IRQF_DISABLED | IRQF_SHARED, 110 .flags = IRQF_SHARED,
111 .name = "fpga.0", 111 .name = "fpga.0",
112 .dev_id = (void *) 0x0028UL, 112 .dev_id = (void *) 0x0028UL,
113 }, 113 },
114 [1] = { 114 [1] = {
115 .handler = fpga_interrupt, 115 .handler = fpga_interrupt,
116 .flags = IRQF_DISABLED | IRQF_SHARED, 116 .flags = IRQF_SHARED,
117 .name = "fpga.1", 117 .name = "fpga.1",
118 .dev_id = (void *) 0x0050UL, 118 .dev_id = (void *) 0x0050UL,
119 }, 119 },
120 [2] = { 120 [2] = {
121 .handler = fpga_interrupt, 121 .handler = fpga_interrupt,
122 .flags = IRQF_DISABLED | IRQF_SHARED, 122 .flags = IRQF_SHARED,
123 .name = "fpga.2", 123 .name = "fpga.2",
124 .dev_id = (void *) 0x1c00UL, 124 .dev_id = (void *) 0x1c00UL,
125 }, 125 },
126 [3] = { 126 [3] = {
127 .handler = fpga_interrupt, 127 .handler = fpga_interrupt,
128 .flags = IRQF_DISABLED | IRQF_SHARED, 128 .flags = IRQF_SHARED,
129 .name = "fpga.3", 129 .name = "fpga.3",
130 .dev_id = (void *) 0x6386UL, 130 .dev_id = (void *) 0x6386UL,
131 } 131 }
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index 95e4eb4f1f38..1f3015cf80f5 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -105,7 +105,6 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask)
105static struct irqaction fpga_irq[1] = { 105static struct irqaction fpga_irq[1] = {
106 [0] = { 106 [0] = {
107 .handler = fpga_interrupt, 107 .handler = fpga_interrupt,
108 .flags = IRQF_DISABLED,
109 .name = "fpga.0", 108 .name = "fpga.0",
110 .dev_id = (void *) 0x0700UL, 109 .dev_id = (void *) 0x0700UL,
111 } 110 }
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index ba648da0932d..8ca5aa4ff595 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -118,13 +118,13 @@ static irqreturn_t mb93493_interrupt(int irq, void *_piqsr)
118static struct irqaction mb93493_irq[2] = { 118static struct irqaction mb93493_irq[2] = {
119 [0] = { 119 [0] = {
120 .handler = mb93493_interrupt, 120 .handler = mb93493_interrupt,
121 .flags = IRQF_DISABLED | IRQF_SHARED, 121 .flags = IRQF_SHARED,
122 .name = "mb93493.0", 122 .name = "mb93493.0",
123 .dev_id = (void *) __addr_MB93493_IQSR(0), 123 .dev_id = (void *) __addr_MB93493_IQSR(0),
124 }, 124 },
125 [1] = { 125 [1] = {
126 .handler = mb93493_interrupt, 126 .handler = mb93493_interrupt,
127 .flags = IRQF_DISABLED | IRQF_SHARED, 127 .flags = IRQF_SHARED,
128 .name = "mb93493.1", 128 .name = "mb93493.1",
129 .dev_id = (void *) __addr_MB93493_IQSR(1), 129 .dev_id = (void *) __addr_MB93493_IQSR(1),
130 } 130 }
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 9f3a7a62d787..9f4a9a607dbe 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -104,8 +104,6 @@ unsigned long __nongprelbss dma_coherent_mem_end;
104unsigned long __initdata __sdram_old_base; 104unsigned long __initdata __sdram_old_base;
105unsigned long __initdata num_mappedpages; 105unsigned long __initdata num_mappedpages;
106 106
107struct cpuinfo_frv __nongprelbss boot_cpu_data;
108
109char __initdata command_line[COMMAND_LINE_SIZE]; 107char __initdata command_line[COMMAND_LINE_SIZE];
110char __initdata redboot_command_line[COMMAND_LINE_SIZE]; 108char __initdata redboot_command_line[COMMAND_LINE_SIZE];
111 109
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index b457de496b70..332e00bf9d06 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -44,7 +44,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy);
44 44
45static struct irqaction timer_irq = { 45static struct irqaction timer_irq = {
46 .handler = timer_interrupt, 46 .handler = timer_interrupt,
47 .flags = IRQF_DISABLED,
48 .name = "timer", 47 .name = "timer",
49}; 48};
50 49
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index e02448b0648b..3796801d6e0c 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -8,4 +8,5 @@ generic-y += mcs_spinlock.h
8generic-y += module.h 8generic-y += module.h
9generic-y += preempt.h 9generic-y += preempt.h
10generic-y += scatterlist.h 10generic-y += scatterlist.h
11generic-y += sections.h
11generic-y += trace_clock.h 12generic-y += trace_clock.h
diff --git a/arch/m32r/include/asm/sections.h b/arch/m32r/include/asm/sections.h
deleted file mode 100644
index 5e5d21c4908a..000000000000
--- a/arch/m32r/include/asm/sections.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _M32R_SECTIONS_H
2#define _M32R_SECTIONS_H
3
4/* nothing to see, move along */
5#include <asm-generic/sections.h>
6
7#endif /* _M32R_SECTIONS_H */
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 1a15f81ea1bd..093f2761aa51 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -134,7 +134,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
134 134
135static struct irqaction irq0 = { 135static struct irqaction irq0 = {
136 .handler = timer_interrupt, 136 .handler = timer_interrupt,
137 .flags = IRQF_DISABLED,
138 .name = "MFT2", 137 .name = "MFT2",
139}; 138};
140 139
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 3a480b3df0d6..9aa01adb407f 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -376,7 +376,6 @@ cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
376asmlinkage int 376asmlinkage int
377sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) 377sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
378{ 378{
379 struct vm_area_struct *vma;
380 int ret = -EINVAL; 379 int ret = -EINVAL;
381 380
382 if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || 381 if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
@@ -389,17 +388,21 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
389 if (!capable(CAP_SYS_ADMIN)) 388 if (!capable(CAP_SYS_ADMIN))
390 goto out; 389 goto out;
391 } else { 390 } else {
391 struct vm_area_struct *vma;
392
393 /* Check for overflow. */
394 if (addr + len < addr)
395 goto out;
396
392 /* 397 /*
393 * Verify that the specified address region actually belongs 398 * Verify that the specified address region actually belongs
394 * to this process. 399 * to this process.
395 */ 400 */
396 vma = find_vma (current->mm, addr);
397 ret = -EINVAL; 401 ret = -EINVAL;
398 /* Check for overflow. */ 402 down_read(&current->mm->mmap_sem);
399 if (addr + len < addr) 403 vma = find_vma(current->mm, addr);
400 goto out; 404 if (!vma || addr < vma->vm_start || addr + len > vma->vm_end)
401 if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) 405 goto out_unlock;
402 goto out;
403 } 406 }
404 407
405 if (CPU_IS_020_OR_030) { 408 if (CPU_IS_020_OR_030) {
@@ -429,7 +432,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
429 __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); 432 __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
430 } 433 }
431 ret = 0; 434 ret = 0;
432 goto out; 435 goto out_unlock;
433 } else { 436 } else {
434 /* 437 /*
435 * 040 or 060: don't blindly trust 'scope', someone could 438 * 040 or 060: don't blindly trust 'scope', someone could
@@ -446,6 +449,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
446 ret = cache_flush_060 (addr, scope, cache, len); 449 ret = cache_flush_060 (addr, scope, cache, len);
447 } 450 }
448 } 451 }
452out_unlock:
453 up_read(&current->mm->mmap_sem);
449out: 454out:
450 return ret; 455 return ret;
451} 456}
diff --git a/arch/mips/include/asm/suspend.h b/arch/mips/include/asm/suspend.h
deleted file mode 100644
index 3adac3b53d19..000000000000
--- a/arch/mips/include/asm/suspend.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __ASM_SUSPEND_H
2#define __ASM_SUSPEND_H
3
4/* References to section boundaries */
5extern const void __nosave_begin, __nosave_end;
6
7#endif /* __ASM_SUSPEND_H */
diff --git a/arch/mips/power/cpu.c b/arch/mips/power/cpu.c
index 521e5963df05..2129e67723ff 100644
--- a/arch/mips/power/cpu.c
+++ b/arch/mips/power/cpu.c
@@ -7,7 +7,7 @@
7 * Author: Hu Hongbing <huhb@lemote.com> 7 * Author: Hu Hongbing <huhb@lemote.com>
8 * Wu Zhangjin <wuzhangjin@gmail.com> 8 * Wu Zhangjin <wuzhangjin@gmail.com>
9 */ 9 */
10#include <asm/suspend.h> 10#include <asm/sections.h>
11#include <asm/fpu.h> 11#include <asm/fpu.h>
12#include <asm/dsp.h> 12#include <asm/dsp.h>
13 13
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index 77eb1a68d13b..54a062cb9f2c 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -8,4 +8,5 @@ generic-y += irq_work.h
8generic-y += mcs_spinlock.h 8generic-y += mcs_spinlock.h
9generic-y += preempt.h 9generic-y += preempt.h
10generic-y += scatterlist.h 10generic-y += scatterlist.h
11generic-y += sections.h
11generic-y += trace_clock.h 12generic-y += trace_clock.h
diff --git a/arch/mn10300/include/asm/sections.h b/arch/mn10300/include/asm/sections.h
deleted file mode 100644
index 2b8c5160388f..000000000000
--- a/arch/mn10300/include/asm/sections.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/sections.h>
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index d98c1ecc3266..f60d4ea8b50c 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -38,10 +38,9 @@ static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK)
38static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); } 38static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
39 39
40#ifdef CONFIG_NUMA_BALANCING 40#ifdef CONFIG_NUMA_BALANCING
41
42static inline int pte_present(pte_t pte) 41static inline int pte_present(pte_t pte)
43{ 42{
44 return pte_val(pte) & (_PAGE_PRESENT | _PAGE_NUMA); 43 return pte_val(pte) & _PAGE_NUMA_MASK;
45} 44}
46 45
47#define pte_present_nonuma pte_present_nonuma 46#define pte_present_nonuma pte_present_nonuma
@@ -50,37 +49,6 @@ static inline int pte_present_nonuma(pte_t pte)
50 return pte_val(pte) & (_PAGE_PRESENT); 49 return pte_val(pte) & (_PAGE_PRESENT);
51} 50}
52 51
53#define pte_numa pte_numa
54static inline int pte_numa(pte_t pte)
55{
56 return (pte_val(pte) &
57 (_PAGE_NUMA|_PAGE_PRESENT)) == _PAGE_NUMA;
58}
59
60#define pte_mknonnuma pte_mknonnuma
61static inline pte_t pte_mknonnuma(pte_t pte)
62{
63 pte_val(pte) &= ~_PAGE_NUMA;
64 pte_val(pte) |= _PAGE_PRESENT | _PAGE_ACCESSED;
65 return pte;
66}
67
68#define pte_mknuma pte_mknuma
69static inline pte_t pte_mknuma(pte_t pte)
70{
71 /*
72 * We should not set _PAGE_NUMA on non present ptes. Also clear the
73 * present bit so that hash_page will return 1 and we collect this
74 * as numa fault.
75 */
76 if (pte_present(pte)) {
77 pte_val(pte) |= _PAGE_NUMA;
78 pte_val(pte) &= ~_PAGE_PRESENT;
79 } else
80 VM_BUG_ON(1);
81 return pte;
82}
83
84#define ptep_set_numa ptep_set_numa 52#define ptep_set_numa ptep_set_numa
85static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr, 53static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr,
86 pte_t *ptep) 54 pte_t *ptep)
@@ -92,12 +60,6 @@ static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr,
92 return; 60 return;
93} 61}
94 62
95#define pmd_numa pmd_numa
96static inline int pmd_numa(pmd_t pmd)
97{
98 return pte_numa(pmd_pte(pmd));
99}
100
101#define pmdp_set_numa pmdp_set_numa 63#define pmdp_set_numa pmdp_set_numa
102static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr, 64static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr,
103 pmd_t *pmdp) 65 pmd_t *pmdp)
@@ -109,16 +71,21 @@ static inline void pmdp_set_numa(struct mm_struct *mm, unsigned long addr,
109 return; 71 return;
110} 72}
111 73
112#define pmd_mknonnuma pmd_mknonnuma 74/*
113static inline pmd_t pmd_mknonnuma(pmd_t pmd) 75 * Generic NUMA pte helpers expect pteval_t and pmdval_t types to exist
76 * which was inherited from x86. For the purposes of powerpc pte_basic_t and
77 * pmd_t are equivalent
78 */
79#define pteval_t pte_basic_t
80#define pmdval_t pmd_t
81static inline pteval_t ptenuma_flags(pte_t pte)
114{ 82{
115 return pte_pmd(pte_mknonnuma(pmd_pte(pmd))); 83 return pte_val(pte) & _PAGE_NUMA_MASK;
116} 84}
117 85
118#define pmd_mknuma pmd_mknuma 86static inline pmdval_t pmdnuma_flags(pmd_t pmd)
119static inline pmd_t pmd_mknuma(pmd_t pmd)
120{ 87{
121 return pte_pmd(pte_mknuma(pmd_pte(pmd))); 88 return pmd_val(pmd) & _PAGE_NUMA_MASK;
122} 89}
123 90
124# else 91# else
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index 8d1569c29042..e040c3595129 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -98,6 +98,11 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
98 _PAGE_USER | _PAGE_ACCESSED | \ 98 _PAGE_USER | _PAGE_ACCESSED | \
99 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC) 99 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
100 100
101#ifdef CONFIG_NUMA_BALANCING
102/* Mask of bits that distinguish present and numa ptes */
103#define _PAGE_NUMA_MASK (_PAGE_NUMA|_PAGE_PRESENT)
104#endif
105
101/* 106/*
102 * We define 2 sets of base prot bits, one for basic pages (ie, 107 * We define 2 sets of base prot bits, one for basic pages (ie,
103 * cacheable kernel and user pages) and one for non cacheable 108 * cacheable kernel and user pages) and one for non cacheable
diff --git a/arch/powerpc/kernel/suspend.c b/arch/powerpc/kernel/suspend.c
index 0167d53da30c..a531154cc0f3 100644
--- a/arch/powerpc/kernel/suspend.c
+++ b/arch/powerpc/kernel/suspend.c
@@ -9,9 +9,7 @@
9 9
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <asm/page.h> 11#include <asm/page.h>
12 12#include <asm/sections.h>
13/* References to section boundaries */
14extern const void __nosave_begin, __nosave_end;
15 13
16/* 14/*
17 * pfn_is_nosave - check if given pfn is in the 'nosave' section 15 * pfn_is_nosave - check if given pfn is in the 'nosave' section
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c
index a7a7537ce1e7..1c4c5accd220 100644
--- a/arch/s390/kernel/suspend.c
+++ b/arch/s390/kernel/suspend.c
@@ -13,14 +13,10 @@
13#include <asm/ipl.h> 13#include <asm/ipl.h>
14#include <asm/cio.h> 14#include <asm/cio.h>
15#include <asm/pci.h> 15#include <asm/pci.h>
16#include <asm/sections.h>
16#include "entry.h" 17#include "entry.h"
17 18
18/* 19/*
19 * References to section boundaries
20 */
21extern const void __nosave_begin, __nosave_end;
22
23/*
24 * The restore of the saved pages in an hibernation image will set 20 * The restore of the saved pages in an hibernation image will set
25 * the change and referenced bits in the storage key for each page. 21 * the change and referenced bits in the storage key for each page.
26 * Overindication of the referenced bits after an hibernation cycle 22 * Overindication of the referenced bits after an hibernation cycle
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index 3fe5681744f1..46461c19f284 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -10,6 +10,7 @@ generic-y += irq_work.h
10generic-y += mcs_spinlock.h 10generic-y += mcs_spinlock.h
11generic-y += preempt.h 11generic-y += preempt.h
12generic-y += scatterlist.h 12generic-y += scatterlist.h
13generic-y += sections.h
13generic-y += trace_clock.h 14generic-y += trace_clock.h
14generic-y += xor.h 15generic-y += xor.h
15generic-y += serial.h 16generic-y += serial.h
diff --git a/arch/score/include/asm/sections.h b/arch/score/include/asm/sections.h
deleted file mode 100644
index 9441d23af005..000000000000
--- a/arch/score/include/asm/sections.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _ASM_SCORE_SECTIONS_H
2#define _ASM_SCORE_SECTIONS_H
3
4#include <asm-generic/sections.h>
5
6#endif /* _ASM_SCORE_SECTIONS_H */
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
index 1b6199740e98..7a99e6af6372 100644
--- a/arch/sh/include/asm/sections.h
+++ b/arch/sh/include/asm/sections.h
@@ -3,7 +3,6 @@
3 3
4#include <asm-generic/sections.h> 4#include <asm-generic/sections.h>
5 5
6extern long __nosave_begin, __nosave_end;
7extern long __machvec_start, __machvec_end; 6extern long __machvec_start, __machvec_end;
8extern char __uncached_start, __uncached_end; 7extern char __uncached_start, __uncached_end;
9extern char __start_eh_frame[], __stop_eh_frame[]; 8extern char __start_eh_frame[], __stop_eh_frame[];
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c
index 42b0b8ce699a..17bd2e167e07 100644
--- a/arch/sparc/power/hibernate.c
+++ b/arch/sparc/power/hibernate.c
@@ -9,11 +9,9 @@
9#include <asm/hibernate.h> 9#include <asm/hibernate.h>
10#include <asm/visasm.h> 10#include <asm/visasm.h>
11#include <asm/page.h> 11#include <asm/page.h>
12#include <asm/sections.h>
12#include <asm/tlb.h> 13#include <asm/tlb.h>
13 14
14/* References to section boundaries */
15extern const void __nosave_begin, __nosave_end;
16
17struct saved_context saved_context; 15struct saved_context saved_context;
18 16
19/* 17/*
diff --git a/arch/unicore32/include/mach/pm.h b/arch/unicore32/include/mach/pm.h
index 4dcd34ae194c..77b522694e74 100644
--- a/arch/unicore32/include/mach/pm.h
+++ b/arch/unicore32/include/mach/pm.h
@@ -36,8 +36,5 @@ extern int puv3_pm_enter(suspend_state_t state);
36/* Defined in hibernate_asm.S */ 36/* Defined in hibernate_asm.S */
37extern int restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist); 37extern int restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist);
38 38
39/* References to section boundaries */
40extern const void __nosave_begin, __nosave_end;
41
42extern struct pbe *restore_pblist; 39extern struct pbe *restore_pblist;
43#endif 40#endif
diff --git a/arch/unicore32/kernel/hibernate.c b/arch/unicore32/kernel/hibernate.c
index d75ef8b6cb56..9969ec374abb 100644
--- a/arch/unicore32/kernel/hibernate.c
+++ b/arch/unicore32/kernel/hibernate.c
@@ -18,6 +18,7 @@
18#include <asm/page.h> 18#include <asm/page.h>
19#include <asm/pgtable.h> 19#include <asm/pgtable.h>
20#include <asm/pgalloc.h> 20#include <asm/pgalloc.h>
21#include <asm/sections.h>
21#include <asm/suspend.h> 22#include <asm/suspend.h>
22 23
23#include "mach/pm.h" 24#include "mach/pm.h"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e4b1f431c7ed..3eb8a41509b3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -30,7 +30,6 @@ config X86
30 select HAVE_UNSTABLE_SCHED_CLOCK 30 select HAVE_UNSTABLE_SCHED_CLOCK
31 select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 31 select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
32 select ARCH_SUPPORTS_INT128 if X86_64 32 select ARCH_SUPPORTS_INT128 if X86_64
33 select ARCH_WANTS_PROT_NUMA_PROT_NONE
34 select HAVE_IDE 33 select HAVE_IDE
35 select HAVE_OPROFILE 34 select HAVE_OPROFILE
36 select HAVE_PCSPKR_PLATFORM 35 select HAVE_PCSPKR_PLATFORM
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index f216963760e5..0f9724c9c510 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -325,6 +325,20 @@ static inline pteval_t pte_flags(pte_t pte)
325 return native_pte_val(pte) & PTE_FLAGS_MASK; 325 return native_pte_val(pte) & PTE_FLAGS_MASK;
326} 326}
327 327
328#ifdef CONFIG_NUMA_BALANCING
329/* Set of bits that distinguishes present, prot_none and numa ptes */
330#define _PAGE_NUMA_MASK (_PAGE_NUMA|_PAGE_PROTNONE|_PAGE_PRESENT)
331static inline pteval_t ptenuma_flags(pte_t pte)
332{
333 return pte_flags(pte) & _PAGE_NUMA_MASK;
334}
335
336static inline pmdval_t pmdnuma_flags(pmd_t pmd)
337{
338 return pmd_flags(pmd) & _PAGE_NUMA_MASK;
339}
340#endif /* CONFIG_NUMA_BALANCING */
341
328#define pgprot_val(x) ((x).pgprot) 342#define pgprot_val(x) ((x).pgprot)
329#define __pgprot(x) ((pgprot_t) { (x) } ) 343#define __pgprot(x) ((pgprot_t) { (x) } )
330 344
diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c
index 7d28c885d238..291226b952a9 100644
--- a/arch/x86/power/hibernate_32.c
+++ b/arch/x86/power/hibernate_32.c
@@ -13,13 +13,11 @@
13#include <asm/page.h> 13#include <asm/page.h>
14#include <asm/pgtable.h> 14#include <asm/pgtable.h>
15#include <asm/mmzone.h> 15#include <asm/mmzone.h>
16#include <asm/sections.h>
16 17
17/* Defined in hibernate_asm_32.S */ 18/* Defined in hibernate_asm_32.S */
18extern int restore_image(void); 19extern int restore_image(void);
19 20
20/* References to section boundaries */
21extern const void __nosave_begin, __nosave_end;
22
23/* Pointer to the temporary resume page tables */ 21/* Pointer to the temporary resume page tables */
24pgd_t *resume_pg_dir; 22pgd_t *resume_pg_dir;
25 23
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 35e2bb6c0f37..009947d419a6 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -17,11 +17,9 @@
17#include <asm/page.h> 17#include <asm/page.h>
18#include <asm/pgtable.h> 18#include <asm/pgtable.h>
19#include <asm/mtrr.h> 19#include <asm/mtrr.h>
20#include <asm/sections.h>
20#include <asm/suspend.h> 21#include <asm/suspend.h>
21 22
22/* References to section boundaries */
23extern __visible const void __nosave_begin, __nosave_end;
24
25/* Defined in hibernate_asm_64.S */ 23/* Defined in hibernate_asm_64.S */
26extern asmlinkage __visible int restore_image(void); 24extern asmlinkage __visible int restore_image(void);
27 25