aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 17:25:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 17:25:52 -0500
commitdeb2a1d29bf0168ff2575e714e5c1f156be663fb (patch)
tree7fc7940c20322dbb6667ba9d5070f5c2d45d4a48 /arch/arm64/include
parentbcc9f96681a1e272b38f16e324d4510823f85730 (diff)
parentc2c93e5b7f3f42277ec25ff3746096abc0c0d0f7 (diff)
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pyll ARM64 patches from Catalin Marinas: - Build fix with DMA_CMA enabled - Introduction of PTE_WRITE to distinguish between writable but clean and truly read-only pages - FIQs enabling/disabling clean-up (they aren't used on arm64) - CPU resume fix for the per-cpu offset restoring - Code comment typos * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: mm: Introduce PTE_WRITE arm64: mm: Remove PTE_BIT_FUNC macro arm64: FIQs are unused arm64: mm: fix the function name in comment of cpu_do_switch_mm arm64: fix build error if DMA_CMA is enabled arm64: kernel: fix per-cpu offset restore on resume arm64: mm: fix the function name in comment of __flush_dcache_area arm64: mm: use ubfm for dcache_line_size
Diffstat (limited to 'arch/arm64/include')
-rw-r--r--arch/arm64/include/asm/dma-contiguous.h1
-rw-r--r--arch/arm64/include/asm/pgtable.h93
2 files changed, 63 insertions, 31 deletions
diff --git a/arch/arm64/include/asm/dma-contiguous.h b/arch/arm64/include/asm/dma-contiguous.h
index d6aacb61ff4a..14c4c0ca7f2a 100644
--- a/arch/arm64/include/asm/dma-contiguous.h
+++ b/arch/arm64/include/asm/dma-contiguous.h
@@ -18,7 +18,6 @@
18#ifdef CONFIG_DMA_CMA 18#ifdef CONFIG_DMA_CMA
19 19
20#include <linux/types.h> 20#include <linux/types.h>
21#include <asm-generic/dma-contiguous.h>
22 21
23static inline void 22static inline void
24dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { } 23dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7f2b60affbb4..b524dcd17243 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -28,7 +28,7 @@
28#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */ 28#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
29#define PTE_DIRTY (_AT(pteval_t, 1) << 55) 29#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
30#define PTE_SPECIAL (_AT(pteval_t, 1) << 56) 30#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
31 /* bit 57 for PMD_SECT_SPLITTING */ 31#define PTE_WRITE (_AT(pteval_t, 1) << 57)
32#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */ 32#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
33 33
34/* 34/*
@@ -67,15 +67,15 @@ extern pgprot_t pgprot_default;
67 67
68#define _MOD_PROT(p, b) __pgprot_modify(p, 0, b) 68#define _MOD_PROT(p, b) __pgprot_modify(p, 0, b)
69 69
70#define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) 70#define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_PXN | PTE_UXN)
71#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 71#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
72#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) 72#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
73#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 73#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
74#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) 74#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
75#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 75#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
76#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) 76#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
77#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) 77#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
78#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) 78#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY | PTE_WRITE)
79 79
80#define PAGE_HYP _MOD_PROT(pgprot_default, PTE_HYP) 80#define PAGE_HYP _MOD_PROT(pgprot_default, PTE_HYP)
81#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) 81#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
@@ -83,13 +83,13 @@ extern pgprot_t pgprot_default;
83#define PAGE_S2 __pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) 83#define PAGE_S2 __pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
84#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN) 84#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
85 85
86#define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) 86#define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
87#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) 87#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
88#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) 88#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
89#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 89#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
90#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) 90#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
91#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) 91#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
92#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) 92#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
93 93
94#endif /* __ASSEMBLY__ */ 94#endif /* __ASSEMBLY__ */
95 95
@@ -140,22 +140,53 @@ extern struct page *empty_zero_page;
140#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) 140#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
141#define pte_young(pte) (pte_val(pte) & PTE_AF) 141#define pte_young(pte) (pte_val(pte) & PTE_AF)
142#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) 142#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL)
143#define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) 143#define pte_write(pte) (pte_val(pte) & PTE_WRITE)
144#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) 144#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
145 145
146#define pte_valid_user(pte) \ 146#define pte_valid_user(pte) \
147 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) 147 ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
148 148
149#define PTE_BIT_FUNC(fn,op) \ 149static inline pte_t pte_wrprotect(pte_t pte)
150static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 150{
151 pte_val(pte) &= ~PTE_WRITE;
152 return pte;
153}
154
155static inline pte_t pte_mkwrite(pte_t pte)
156{
157 pte_val(pte) |= PTE_WRITE;
158 return pte;
159}
160
161static inline pte_t pte_mkclean(pte_t pte)
162{
163 pte_val(pte) &= ~PTE_DIRTY;
164 return pte;
165}
166
167static inline pte_t pte_mkdirty(pte_t pte)
168{
169 pte_val(pte) |= PTE_DIRTY;
170 return pte;
171}
151 172
152PTE_BIT_FUNC(wrprotect, |= PTE_RDONLY); 173static inline pte_t pte_mkold(pte_t pte)
153PTE_BIT_FUNC(mkwrite, &= ~PTE_RDONLY); 174{
154PTE_BIT_FUNC(mkclean, &= ~PTE_DIRTY); 175 pte_val(pte) &= ~PTE_AF;
155PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY); 176 return pte;
156PTE_BIT_FUNC(mkold, &= ~PTE_AF); 177}
157PTE_BIT_FUNC(mkyoung, |= PTE_AF); 178
158PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL); 179static inline pte_t pte_mkyoung(pte_t pte)
180{
181 pte_val(pte) |= PTE_AF;
182 return pte;
183}
184
185static inline pte_t pte_mkspecial(pte_t pte)
186{
187 pte_val(pte) |= PTE_SPECIAL;
188 return pte;
189}
159 190
160static inline void set_pte(pte_t *ptep, pte_t pte) 191static inline void set_pte(pte_t *ptep, pte_t pte)
161{ 192{
@@ -170,8 +201,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
170 if (pte_valid_user(pte)) { 201 if (pte_valid_user(pte)) {
171 if (pte_exec(pte)) 202 if (pte_exec(pte))
172 __sync_icache_dcache(pte, addr); 203 __sync_icache_dcache(pte, addr);
173 if (!pte_dirty(pte)) 204 if (pte_dirty(pte) && pte_write(pte))
174 pte = pte_wrprotect(pte); 205 pte_val(pte) &= ~PTE_RDONLY;
206 else
207 pte_val(pte) |= PTE_RDONLY;
175 } 208 }
176 209
177 set_pte(ptep, pte); 210 set_pte(ptep, pte);
@@ -345,7 +378,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
345static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 378static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
346{ 379{
347 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | 380 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
348 PTE_PROT_NONE | PTE_VALID; 381 PTE_PROT_NONE | PTE_VALID | PTE_WRITE;
349 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 382 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
350 return pte; 383 return pte;
351} 384}