aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:26:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:26:14 -0400
commit0cf744bc7ae8e0072159a901f6e1a159bbc30ffa (patch)
treefc8222a3a5af4f42226070c3f76462cfcf0b4e50 /arch/arm/include
parentb528392669415dc1e53a047215e5ad6c2de879fc (diff)
parent7f8998c7aef3ac9c5f3f2943e083dfa6302e90d0 (diff)
Merge branch 'akpm' (fixes from Andrew Morton)
Merge patch-bomb from Andrew Morton: - part of OCFS2 (review is laggy again) - procfs - slab - all of MM - zram, zbud - various other random things: arch, filesystems. * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (164 commits) nosave: consolidate __nosave_{begin,end} in <asm/sections.h> include/linux/screen_info.h: remove unused ORIG_* macros kernel/sys.c: compat sysinfo syscall: fix undefined behavior kernel/sys.c: whitespace fixes acct: eliminate compile warning kernel/async.c: switch to pr_foo() include/linux/blkdev.h: use NULL instead of zero include/linux/kernel.h: deduplicate code implementing clamp* macros include/linux/kernel.h: rewrite min3, max3 and clamp using min and max alpha: use Kbuild logic to include <asm-generic/sections.h> frv: remove deprecated IRQF_DISABLED frv: remove unused cpuinfo_frv and friends to fix future build error zbud: avoid accessing last unused freelist zsmalloc: simplify init_zspage free obj linking mm/zsmalloc.c: correct comment for fullness group computation zram: use notify_free to account all free notifications zram: report maximum used memory zram: zram memory size limitation zsmalloc: change return value unit of zs_get_total_size_bytes zsmalloc: move pages_allocated to zs_pool ...
Diffstat (limited to 'arch/arm/include')
-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
4 files changed, 55 insertions, 6 deletions
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