diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 12 | ||||
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos5250.dtsi | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/cacheflush.h | 4 | ||||
-rw-r--r-- | arch/arm/kernel/machine_kexec.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 43 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 13 | ||||
-rw-r--r-- | arch/arm/mm/cache-v7.S | 8 | ||||
-rw-r--r-- | arch/arm/mm/flush.c | 33 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 8 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 4 |
12 files changed, 106 insertions, 32 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 49d993cee512..2651b1da1c56 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1189,6 +1189,16 @@ config PL310_ERRATA_588369 | |||
1189 | is not correctly implemented in PL310 as clean lines are not | 1189 | is not correctly implemented in PL310 as clean lines are not |
1190 | invalidated as a result of these operations. | 1190 | invalidated as a result of these operations. |
1191 | 1191 | ||
1192 | config ARM_ERRATA_643719 | ||
1193 | bool "ARM errata: LoUIS bit field in CLIDR register is incorrect" | ||
1194 | depends on CPU_V7 && SMP | ||
1195 | help | ||
1196 | This option enables the workaround for the 643719 Cortex-A9 (prior to | ||
1197 | r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR | ||
1198 | register returns zero when it should return one. The workaround | ||
1199 | corrects this value, ensuring cache maintenance operations which use | ||
1200 | it behave as intended and avoiding data corruption. | ||
1201 | |||
1192 | config ARM_ERRATA_720789 | 1202 | config ARM_ERRATA_720789 |
1193 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" | 1203 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" |
1194 | depends on CPU_V7 | 1204 | depends on CPU_V7 |
@@ -2006,7 +2016,7 @@ config XIP_PHYS_ADDR | |||
2006 | 2016 | ||
2007 | config KEXEC | 2017 | config KEXEC |
2008 | bool "Kexec system call (EXPERIMENTAL)" | 2018 | bool "Kexec system call (EXPERIMENTAL)" |
2009 | depends on (!SMP || HOTPLUG_CPU) | 2019 | depends on (!SMP || PM_SLEEP_SMP) |
2010 | help | 2020 | help |
2011 | kexec is a system call that implements the ability to shutdown your | 2021 | kexec is a system call that implements the ability to shutdown your |
2012 | current kernel, and to start another kernel. It is like a reboot | 2022 | current kernel, and to start another kernel. It is like a reboot |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 79e9bdbfc491..120b83bfde20 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -116,7 +116,8 @@ targets := vmlinux vmlinux.lds \ | |||
116 | 116 | ||
117 | # Make sure files are removed during clean | 117 | # Make sure files are removed during clean |
118 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ | 118 | extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ |
119 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) | 119 | lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \ |
120 | hyp-stub.S | ||
120 | 121 | ||
121 | ifeq ($(CONFIG_FUNCTION_TRACER),y) | 122 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
122 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 123 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index d1650fb34c0a..ded558bb0f3b 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi | |||
@@ -763,7 +763,7 @@ | |||
763 | }; | 763 | }; |
764 | }; | 764 | }; |
765 | 765 | ||
766 | pinctrl@03680000 { | 766 | pinctrl@03860000 { |
767 | gpz: gpz { | 767 | gpz: gpz { |
768 | gpio-controller; | 768 | gpio-controller; |
769 | #gpio-cells = <2>; | 769 | #gpio-cells = <2>; |
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0673524238a6..fc9fb3d526e2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
@@ -161,9 +161,9 @@ | |||
161 | interrupts = <0 50 0>; | 161 | interrupts = <0 50 0>; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | pinctrl_3: pinctrl@03680000 { | 164 | pinctrl_3: pinctrl@03860000 { |
165 | compatible = "samsung,exynos5250-pinctrl"; | 165 | compatible = "samsung,exynos5250-pinctrl"; |
166 | reg = <0x0368000 0x1000>; | 166 | reg = <0x03860000 0x1000>; |
167 | interrupts = <0 47 0>; | 167 | interrupts = <0 47 0>; |
168 | }; | 168 | }; |
169 | 169 | ||
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index bff71388e72a..17d0ae8672fa 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -320,9 +320,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
320 | } | 320 | } |
321 | 321 | ||
322 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE | 322 | #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE |
323 | static inline void flush_kernel_dcache_page(struct page *page) | 323 | extern void flush_kernel_dcache_page(struct page *); |
324 | { | ||
325 | } | ||
326 | 324 | ||
327 | #define flush_dcache_mmap_lock(mapping) \ | 325 | #define flush_dcache_mmap_lock(mapping) \ |
328 | spin_lock_irq(&(mapping)->tree_lock) | 326 | spin_lock_irq(&(mapping)->tree_lock) |
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8ef8c9337809..4fb074c446bf 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
@@ -134,6 +134,10 @@ void machine_kexec(struct kimage *image) | |||
134 | unsigned long reboot_code_buffer_phys; | 134 | unsigned long reboot_code_buffer_phys; |
135 | void *reboot_code_buffer; | 135 | void *reboot_code_buffer; |
136 | 136 | ||
137 | if (num_online_cpus() > 1) { | ||
138 | pr_err("kexec: error: multiple CPUs still online\n"); | ||
139 | return; | ||
140 | } | ||
137 | 141 | ||
138 | page_list = image->head & PAGE_MASK; | 142 | page_list = image->head & PAGE_MASK; |
139 | 143 | ||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 282de4826abb..6e8931ccf13e 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -184,30 +184,61 @@ int __init reboot_setup(char *str) | |||
184 | 184 | ||
185 | __setup("reboot=", reboot_setup); | 185 | __setup("reboot=", reboot_setup); |
186 | 186 | ||
187 | /* | ||
188 | * Called by kexec, immediately prior to machine_kexec(). | ||
189 | * | ||
190 | * This must completely disable all secondary CPUs; simply causing those CPUs | ||
191 | * to execute e.g. a RAM-based pin loop is not sufficient. This allows the | ||
192 | * kexec'd kernel to use any and all RAM as it sees fit, without having to | ||
193 | * avoid any code or data used by any SW CPU pin loop. The CPU hotplug | ||
194 | * functionality embodied in disable_nonboot_cpus() to achieve this. | ||
195 | */ | ||
187 | void machine_shutdown(void) | 196 | void machine_shutdown(void) |
188 | { | 197 | { |
189 | #ifdef CONFIG_SMP | 198 | disable_nonboot_cpus(); |
190 | smp_send_stop(); | ||
191 | #endif | ||
192 | } | 199 | } |
193 | 200 | ||
201 | /* | ||
202 | * Halting simply requires that the secondary CPUs stop performing any | ||
203 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
204 | * achieves this. | ||
205 | */ | ||
194 | void machine_halt(void) | 206 | void machine_halt(void) |
195 | { | 207 | { |
196 | machine_shutdown(); | 208 | smp_send_stop(); |
209 | |||
197 | local_irq_disable(); | 210 | local_irq_disable(); |
198 | while (1); | 211 | while (1); |
199 | } | 212 | } |
200 | 213 | ||
214 | /* | ||
215 | * Power-off simply requires that the secondary CPUs stop performing any | ||
216 | * activity (executing tasks, handling interrupts). smp_send_stop() | ||
217 | * achieves this. When the system power is turned off, it will take all CPUs | ||
218 | * with it. | ||
219 | */ | ||
201 | void machine_power_off(void) | 220 | void machine_power_off(void) |
202 | { | 221 | { |
203 | machine_shutdown(); | 222 | smp_send_stop(); |
223 | |||
204 | if (pm_power_off) | 224 | if (pm_power_off) |
205 | pm_power_off(); | 225 | pm_power_off(); |
206 | } | 226 | } |
207 | 227 | ||
228 | /* | ||
229 | * Restart requires that the secondary CPUs stop performing any activity | ||
230 | * while the primary CPU resets the system. Systems with a single CPU can | ||
231 | * use soft_restart() as their machine descriptor's .restart hook, since that | ||
232 | * will cause the only available CPU to reset. Systems with multiple CPUs must | ||
233 | * provide a HW restart implementation, to ensure that all CPUs reset at once. | ||
234 | * This is required so that any code running after reset on the primary CPU | ||
235 | * doesn't have to co-ordinate with other CPUs to ensure they aren't still | ||
236 | * executing pre-reset code, and using RAM that the primary CPU's code wishes | ||
237 | * to use. Implementing such co-ordination would be essentially impossible. | ||
238 | */ | ||
208 | void machine_restart(char *cmd) | 239 | void machine_restart(char *cmd) |
209 | { | 240 | { |
210 | machine_shutdown(); | 241 | smp_send_stop(); |
211 | 242 | ||
212 | arm_pm_restart(reboot_mode, cmd); | 243 | arm_pm_restart(reboot_mode, cmd); |
213 | 244 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 550d63cef68e..5919eb451bb9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -651,17 +651,6 @@ void smp_send_reschedule(int cpu) | |||
651 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); | 651 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); |
652 | } | 652 | } |
653 | 653 | ||
654 | #ifdef CONFIG_HOTPLUG_CPU | ||
655 | static void smp_kill_cpus(cpumask_t *mask) | ||
656 | { | ||
657 | unsigned int cpu; | ||
658 | for_each_cpu(cpu, mask) | ||
659 | platform_cpu_kill(cpu); | ||
660 | } | ||
661 | #else | ||
662 | static void smp_kill_cpus(cpumask_t *mask) { } | ||
663 | #endif | ||
664 | |||
665 | void smp_send_stop(void) | 654 | void smp_send_stop(void) |
666 | { | 655 | { |
667 | unsigned long timeout; | 656 | unsigned long timeout; |
@@ -679,8 +668,6 @@ void smp_send_stop(void) | |||
679 | 668 | ||
680 | if (num_online_cpus() > 1) | 669 | if (num_online_cpus() > 1) |
681 | pr_warning("SMP: failed to stop secondary CPUs\n"); | 670 | pr_warning("SMP: failed to stop secondary CPUs\n"); |
682 | |||
683 | smp_kill_cpus(&mask); | ||
684 | } | 671 | } |
685 | 672 | ||
686 | /* | 673 | /* |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 15451ee4acc8..515b00064da8 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -92,6 +92,14 @@ ENTRY(v7_flush_dcache_louis) | |||
92 | mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr | 92 | mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr |
93 | ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr | 93 | ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr |
94 | ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr | 94 | ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr |
95 | #ifdef CONFIG_ARM_ERRATA_643719 | ||
96 | ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register | ||
97 | ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do | ||
98 | ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p? | ||
99 | biceq r2, r2, #0x0000000f @ clear minor revision number | ||
100 | teqeq r2, r1 @ test for errata affected core and if so... | ||
101 | orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne') | ||
102 | #endif | ||
95 | ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 | 103 | ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 |
96 | ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 | 104 | ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 |
97 | moveq pc, lr @ return if level == 0 | 105 | moveq pc, lr @ return if level == 0 |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 0d473cce501c..32aa5861119f 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -301,6 +301,39 @@ void flush_dcache_page(struct page *page) | |||
301 | EXPORT_SYMBOL(flush_dcache_page); | 301 | EXPORT_SYMBOL(flush_dcache_page); |
302 | 302 | ||
303 | /* | 303 | /* |
304 | * Ensure cache coherency for the kernel mapping of this page. We can | ||
305 | * assume that the page is pinned via kmap. | ||
306 | * | ||
307 | * If the page only exists in the page cache and there are no user | ||
308 | * space mappings, this is a no-op since the page was already marked | ||
309 | * dirty at creation. Otherwise, we need to flush the dirty kernel | ||
310 | * cache lines directly. | ||
311 | */ | ||
312 | void flush_kernel_dcache_page(struct page *page) | ||
313 | { | ||
314 | if (cache_is_vivt() || cache_is_vipt_aliasing()) { | ||
315 | struct address_space *mapping; | ||
316 | |||
317 | mapping = page_mapping(page); | ||
318 | |||
319 | if (!mapping || mapping_mapped(mapping)) { | ||
320 | void *addr; | ||
321 | |||
322 | addr = page_address(page); | ||
323 | /* | ||
324 | * kmap_atomic() doesn't set the page virtual | ||
325 | * address for highmem pages, and | ||
326 | * kunmap_atomic() takes care of cache | ||
327 | * flushing already. | ||
328 | */ | ||
329 | if (!IS_ENABLED(CONFIG_HIGHMEM) || addr) | ||
330 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | EXPORT_SYMBOL(flush_kernel_dcache_page); | ||
335 | |||
336 | /* | ||
304 | * Flush an anonymous page so that users of get_user_pages() | 337 | * Flush an anonymous page so that users of get_user_pages() |
305 | * can safely access the data. The expected sequence is: | 338 | * can safely access the data. The expected sequence is: |
306 | * | 339 | * |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e0d8565671a6..4d409e6a552d 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -616,10 +616,12 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, | |||
616 | } while (pte++, addr += PAGE_SIZE, addr != end); | 616 | } while (pte++, addr += PAGE_SIZE, addr != end); |
617 | } | 617 | } |
618 | 618 | ||
619 | static void __init map_init_section(pmd_t *pmd, unsigned long addr, | 619 | static void __init __map_init_section(pmd_t *pmd, unsigned long addr, |
620 | unsigned long end, phys_addr_t phys, | 620 | unsigned long end, phys_addr_t phys, |
621 | const struct mem_type *type) | 621 | const struct mem_type *type) |
622 | { | 622 | { |
623 | pmd_t *p = pmd; | ||
624 | |||
623 | #ifndef CONFIG_ARM_LPAE | 625 | #ifndef CONFIG_ARM_LPAE |
624 | /* | 626 | /* |
625 | * In classic MMU format, puds and pmds are folded in to | 627 | * In classic MMU format, puds and pmds are folded in to |
@@ -638,7 +640,7 @@ static void __init map_init_section(pmd_t *pmd, unsigned long addr, | |||
638 | phys += SECTION_SIZE; | 640 | phys += SECTION_SIZE; |
639 | } while (pmd++, addr += SECTION_SIZE, addr != end); | 641 | } while (pmd++, addr += SECTION_SIZE, addr != end); |
640 | 642 | ||
641 | flush_pmd_entry(pmd); | 643 | flush_pmd_entry(p); |
642 | } | 644 | } |
643 | 645 | ||
644 | static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | 646 | static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, |
@@ -661,7 +663,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, | |||
661 | */ | 663 | */ |
662 | if (type->prot_sect && | 664 | if (type->prot_sect && |
663 | ((addr | next | phys) & ~SECTION_MASK) == 0) { | 665 | ((addr | next | phys) & ~SECTION_MASK) == 0) { |
664 | map_init_section(pmd, addr, next, phys, type); | 666 | __map_init_section(pmd, addr, next, phys, type); |
665 | } else { | 667 | } else { |
666 | alloc_init_pte(pmd, addr, next, | 668 | alloc_init_pte(pmd, addr, next, |
667 | __phys_to_pfn(phys), type); | 669 | __phys_to_pfn(phys), type); |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 2c73a7301ff7..4c8c9c10a388 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -409,8 +409,8 @@ __v7_ca9mp_proc_info: | |||
409 | */ | 409 | */ |
410 | .type __v7_pj4b_proc_info, #object | 410 | .type __v7_pj4b_proc_info, #object |
411 | __v7_pj4b_proc_info: | 411 | __v7_pj4b_proc_info: |
412 | .long 0x562f5840 | 412 | .long 0x560f5800 |
413 | .long 0xfffffff0 | 413 | .long 0xff0fff00 |
414 | __v7_proc __v7_pj4b_setup | 414 | __v7_proc __v7_pj4b_setup |
415 | .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info | 415 | .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info |
416 | 416 | ||