aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--arch/arm64/include/asm/dma-contiguous.h1
-rw-r--r--arch/arm64/include/asm/pgtable.h93
-rw-r--r--arch/arm64/kernel/process.c6
-rw-r--r--arch/arm64/kernel/smp.c2
-rw-r--r--arch/arm64/kernel/suspend.c8
-rw-r--r--arch/arm64/mm/cache.S2
-rw-r--r--arch/arm64/mm/proc-macros.S3
-rw-r--r--arch/arm64/mm/proc.S2
8 files changed, 74 insertions, 43 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}
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 248a15db37f2..1c0a9be2ffa8 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -85,11 +85,6 @@ EXPORT_SYMBOL_GPL(pm_power_off);
85void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); 85void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
86EXPORT_SYMBOL_GPL(arm_pm_restart); 86EXPORT_SYMBOL_GPL(arm_pm_restart);
87 87
88void arch_cpu_idle_prepare(void)
89{
90 local_fiq_enable();
91}
92
93/* 88/*
94 * This is our default idle handler. 89 * This is our default idle handler.
95 */ 90 */
@@ -138,7 +133,6 @@ void machine_restart(char *cmd)
138 133
139 /* Disable interrupts first */ 134 /* Disable interrupts first */
140 local_irq_disable(); 135 local_irq_disable();
141 local_fiq_disable();
142 136
143 /* Now call the architecture specific reboot code. */ 137 /* Now call the architecture specific reboot code. */
144 if (arm_pm_restart) 138 if (arm_pm_restart)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1b7617ab499b..7cfb92a4ab66 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -161,7 +161,6 @@ asmlinkage void secondary_start_kernel(void)
161 complete(&cpu_running); 161 complete(&cpu_running);
162 162
163 local_irq_enable(); 163 local_irq_enable();
164 local_fiq_enable();
165 local_async_enable(); 164 local_async_enable();
166 165
167 /* 166 /*
@@ -495,7 +494,6 @@ static void ipi_cpu_stop(unsigned int cpu)
495 494
496 set_cpu_online(cpu, false); 495 set_cpu_online(cpu, false);
497 496
498 local_fiq_disable();
499 local_irq_disable(); 497 local_irq_disable();
500 498
501 while (1) 499 while (1)
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 430344e2c989..1fa9ce4afd8f 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -1,3 +1,4 @@
1#include <linux/percpu.h>
1#include <linux/slab.h> 2#include <linux/slab.h>
2#include <asm/cacheflush.h> 3#include <asm/cacheflush.h>
3#include <asm/cpu_ops.h> 4#include <asm/cpu_ops.h>
@@ -89,6 +90,13 @@ int cpu_suspend(unsigned long arg)
89 if (ret == 0) { 90 if (ret == 0) {
90 cpu_switch_mm(mm->pgd, mm); 91 cpu_switch_mm(mm->pgd, mm);
91 flush_tlb_all(); 92 flush_tlb_all();
93
94 /*
95 * Restore per-cpu offset before any kernel
96 * subsystem relying on it has a chance to run.
97 */
98 set_my_cpu_offset(per_cpu_offset(cpu));
99
92 /* 100 /*
93 * Restore HW breakpoint registers to sane values 101 * Restore HW breakpoint registers to sane values
94 * before debug exceptions are possibly reenabled 102 * before debug exceptions are possibly reenabled
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 48a386094fa3..1ea9f26d1b70 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -146,7 +146,7 @@ ENDPROC(flush_icache_range)
146ENDPROC(__flush_cache_user_range) 146ENDPROC(__flush_cache_user_range)
147 147
148/* 148/*
149 * __flush_kern_dcache_page(kaddr) 149 * __flush_dcache_area(kaddr, size)
150 * 150 *
151 * Ensure that the data held in the page kaddr is written back to the 151 * Ensure that the data held in the page kaddr is written back to the
152 * page in question. 152 * page in question.
diff --git a/arch/arm64/mm/proc-macros.S b/arch/arm64/mm/proc-macros.S
index 8957b822010b..005d29e2977d 100644
--- a/arch/arm64/mm/proc-macros.S
+++ b/arch/arm64/mm/proc-macros.S
@@ -38,8 +38,7 @@
38 */ 38 */
39 .macro dcache_line_size, reg, tmp 39 .macro dcache_line_size, reg, tmp
40 mrs \tmp, ctr_el0 // read CTR 40 mrs \tmp, ctr_el0 // read CTR
41 lsr \tmp, \tmp, #16 41 ubfm \tmp, \tmp, #16, #19 // cache line size encoding
42 and \tmp, \tmp, #0xf // cache line size encoding
43 mov \reg, #4 // bytes per word 42 mov \reg, #4 // bytes per word
44 lsl \reg, \reg, \tmp // actual cache line size 43 lsl \reg, \reg, \tmp // actual cache line size
45 .endm 44 .endm
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index bed1f1de1caf..1333e6f9a8e5 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -150,7 +150,7 @@ ENDPROC(cpu_do_resume)
150#endif 150#endif
151 151
152/* 152/*
153 * cpu_switch_mm(pgd_phys, tsk) 153 * cpu_do_switch_mm(pgd_phys, tsk)
154 * 154 *
155 * Set the translation table base pointer to be pgd_phys. 155 * Set the translation table base pointer to be pgd_phys.
156 * 156 *