aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S106
-rw-r--r--arch/arm/kernel/entry-v7m.S2
-rw-r--r--arch/arm/kernel/fiq.c23
-rw-r--r--arch/arm/kernel/head-common.S1
-rw-r--r--arch/arm/kernel/head-nommu.S2
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/hw_breakpoint.c4
-rw-r--r--arch/arm/kernel/hyp-stub.S4
-rw-r--r--arch/arm/kernel/machine_kexec.c20
-rw-r--r--arch/arm/kernel/perf_event.c10
-rw-r--r--arch/arm/kernel/perf_event_cpu.c6
-rw-r--r--arch/arm/kernel/process.c49
-rw-r--r--arch/arm/kernel/psci_smp.c3
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/signal.c56
-rw-r--r--arch/arm/kernel/signal.h12
-rw-r--r--arch/arm/kernel/smp.c28
-rw-r--r--arch/arm/kernel/smp_tlb.c17
-rw-r--r--arch/arm/kernel/smp_twd.c6
-rw-r--r--arch/arm/kernel/traps.c46
-rw-r--r--arch/arm/kernel/vmlinux.lds.S17
21 files changed, 266 insertions, 151 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a39cfc2a1f90..9cbe70c8b0ef 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -357,7 +357,8 @@ ENDPROC(__pabt_svc)
357 .endm 357 .endm
358 358
359 .macro kuser_cmpxchg_check 359 .macro kuser_cmpxchg_check
360#if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) 360#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
361 !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
361#ifndef CONFIG_MMU 362#ifndef CONFIG_MMU
362#warning "NPTL on non MMU needs fixing" 363#warning "NPTL on non MMU needs fixing"
363#else 364#else
@@ -742,6 +743,18 @@ ENDPROC(__switch_to)
742#endif 743#endif
743 .endm 744 .endm
744 745
746 .macro kuser_pad, sym, size
747 .if (. - \sym) & 3
748 .rept 4 - (. - \sym) & 3
749 .byte 0
750 .endr
751 .endif
752 .rept (\size - (. - \sym)) / 4
753 .word 0xe7fddef1
754 .endr
755 .endm
756
757#ifdef CONFIG_KUSER_HELPERS
745 .align 5 758 .align 5
746 .globl __kuser_helper_start 759 .globl __kuser_helper_start
747__kuser_helper_start: 760__kuser_helper_start:
@@ -832,18 +845,13 @@ kuser_cmpxchg64_fixup:
832#error "incoherent kernel configuration" 845#error "incoherent kernel configuration"
833#endif 846#endif
834 847
835 /* pad to next slot */ 848 kuser_pad __kuser_cmpxchg64, 64
836 .rept (16 - (. - __kuser_cmpxchg64)/4)
837 .word 0
838 .endr
839
840 .align 5
841 849
842__kuser_memory_barrier: @ 0xffff0fa0 850__kuser_memory_barrier: @ 0xffff0fa0
843 smp_dmb arm 851 smp_dmb arm
844 usr_ret lr 852 usr_ret lr
845 853
846 .align 5 854 kuser_pad __kuser_memory_barrier, 32
847 855
848__kuser_cmpxchg: @ 0xffff0fc0 856__kuser_cmpxchg: @ 0xffff0fc0
849 857
@@ -916,13 +924,14 @@ kuser_cmpxchg32_fixup:
916 924
917#endif 925#endif
918 926
919 .align 5 927 kuser_pad __kuser_cmpxchg, 32
920 928
921__kuser_get_tls: @ 0xffff0fe0 929__kuser_get_tls: @ 0xffff0fe0
922 ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init 930 ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init
923 usr_ret lr 931 usr_ret lr
924 mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code 932 mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code
925 .rep 4 933 kuser_pad __kuser_get_tls, 16
934 .rep 3
926 .word 0 @ 0xffff0ff0 software TLS value, then 935 .word 0 @ 0xffff0ff0 software TLS value, then
927 .endr @ pad up to __kuser_helper_version 936 .endr @ pad up to __kuser_helper_version
928 937
@@ -932,14 +941,16 @@ __kuser_helper_version: @ 0xffff0ffc
932 .globl __kuser_helper_end 941 .globl __kuser_helper_end
933__kuser_helper_end: 942__kuser_helper_end:
934 943
944#endif
945
935 THUMB( .thumb ) 946 THUMB( .thumb )
936 947
937/* 948/*
938 * Vector stubs. 949 * Vector stubs.
939 * 950 *
940 * This code is copied to 0xffff0200 so we can use branches in the 951 * This code is copied to 0xffff1000 so we can use branches in the
941 * vectors, rather than ldr's. Note that this code must not 952 * vectors, rather than ldr's. Note that this code must not exceed
942 * exceed 0x300 bytes. 953 * a page size.
943 * 954 *
944 * Common stub entry macro: 955 * Common stub entry macro:
945 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 956 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -986,8 +997,17 @@ ENDPROC(vector_\name)
9861: 9971:
987 .endm 998 .endm
988 999
989 .globl __stubs_start 1000 .section .stubs, "ax", %progbits
990__stubs_start: 1001__stubs_start:
1002 @ This must be the first word
1003 .word vector_swi
1004
1005vector_rst:
1006 ARM( swi SYS_ERROR0 )
1007 THUMB( svc #0 )
1008 THUMB( nop )
1009 b vector_und
1010
991/* 1011/*
992 * Interrupt dispatcher 1012 * Interrupt dispatcher
993 */ 1013 */
@@ -1082,6 +1102,16 @@ __stubs_start:
1082 .align 5 1102 .align 5
1083 1103
1084/*============================================================================= 1104/*=============================================================================
1105 * Address exception handler
1106 *-----------------------------------------------------------------------------
1107 * These aren't too critical.
1108 * (they're not supposed to happen, and won't happen in 32-bit data mode).
1109 */
1110
1111vector_addrexcptn:
1112 b vector_addrexcptn
1113
1114/*=============================================================================
1085 * Undefined FIQs 1115 * Undefined FIQs
1086 *----------------------------------------------------------------------------- 1116 *-----------------------------------------------------------------------------
1087 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC 1117 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
@@ -1094,45 +1124,19 @@ __stubs_start:
1094vector_fiq: 1124vector_fiq:
1095 subs pc, lr, #4 1125 subs pc, lr, #4
1096 1126
1097/*============================================================================= 1127 .globl vector_fiq_offset
1098 * Address exception handler 1128 .equ vector_fiq_offset, vector_fiq
1099 *-----------------------------------------------------------------------------
1100 * These aren't too critical.
1101 * (they're not supposed to happen, and won't happen in 32-bit data mode).
1102 */
1103
1104vector_addrexcptn:
1105 b vector_addrexcptn
1106
1107/*
1108 * We group all the following data together to optimise
1109 * for CPUs with separate I & D caches.
1110 */
1111 .align 5
1112
1113.LCvswi:
1114 .word vector_swi
1115
1116 .globl __stubs_end
1117__stubs_end:
1118
1119 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
1120 1129
1121 .globl __vectors_start 1130 .section .vectors, "ax", %progbits
1122__vectors_start: 1131__vectors_start:
1123 ARM( swi SYS_ERROR0 ) 1132 W(b) vector_rst
1124 THUMB( svc #0 ) 1133 W(b) vector_und
1125 THUMB( nop ) 1134 W(ldr) pc, __vectors_start + 0x1000
1126 W(b) vector_und + stubs_offset 1135 W(b) vector_pabt
1127 W(ldr) pc, .LCvswi + stubs_offset 1136 W(b) vector_dabt
1128 W(b) vector_pabt + stubs_offset 1137 W(b) vector_addrexcptn
1129 W(b) vector_dabt + stubs_offset 1138 W(b) vector_irq
1130 W(b) vector_addrexcptn + stubs_offset 1139 W(b) vector_fiq
1131 W(b) vector_irq + stubs_offset
1132 W(b) vector_fiq + stubs_offset
1133
1134 .globl __vectors_end
1135__vectors_end:
1136 1140
1137 .data 1141 .data
1138 1142
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index e00621f1403f..52b26432c9a9 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -49,7 +49,7 @@ __irq_entry:
49 mov r1, sp 49 mov r1, sp
50 stmdb sp!, {lr} 50 stmdb sp!, {lr}
51 @ routine called with r0 = irq number, r1 = struct pt_regs * 51 @ routine called with r0 = irq number, r1 = struct pt_regs *
52 bl nvic_do_IRQ 52 bl nvic_handle_irq
53 53
54 pop {lr} 54 pop {lr}
55 @ 55 @
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 2adda11f712f..fc7920288a3d 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -47,6 +47,11 @@
47#include <asm/irq.h> 47#include <asm/irq.h>
48#include <asm/traps.h> 48#include <asm/traps.h>
49 49
50#define FIQ_OFFSET ({ \
51 extern void *vector_fiq_offset; \
52 (unsigned)&vector_fiq_offset; \
53 })
54
50static unsigned long no_fiq_insn; 55static unsigned long no_fiq_insn;
51 56
52/* Default reacquire function 57/* Default reacquire function
@@ -79,14 +84,13 @@ int show_fiq_list(struct seq_file *p, int prec)
79 84
80void set_fiq_handler(void *start, unsigned int length) 85void set_fiq_handler(void *start, unsigned int length)
81{ 86{
82#if defined(CONFIG_CPU_USE_DOMAINS) 87 void *base = vectors_page;
83 memcpy((void *)0xffff001c, start, length); 88 unsigned offset = FIQ_OFFSET;
84#else 89
85 memcpy(vectors_page + 0x1c, start, length); 90 memcpy(base + offset, start, length);
86#endif 91 if (!cache_is_vipt_nonaliasing())
87 flush_icache_range(0xffff001c, 0xffff001c + length); 92 flush_icache_range(base + offset, offset + length);
88 if (!vectors_high()) 93 flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
89 flush_icache_range(0x1c, 0x1c + length);
90} 94}
91 95
92int claim_fiq(struct fiq_handler *f) 96int claim_fiq(struct fiq_handler *f)
@@ -144,6 +148,7 @@ EXPORT_SYMBOL(disable_fiq);
144 148
145void __init init_FIQ(int start) 149void __init init_FIQ(int start)
146{ 150{
147 no_fiq_insn = *(unsigned long *)0xffff001c; 151 unsigned offset = FIQ_OFFSET;
152 no_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
148 fiq_start = start; 153 fiq_start = start;
149} 154}
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 76ab5ca50610..47cd974e57ea 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -149,7 +149,6 @@ ENDPROC(lookup_processor_type)
149 * r5 = proc_info pointer in physical address space 149 * r5 = proc_info pointer in physical address space
150 * r9 = cpuid (preserved) 150 * r9 = cpuid (preserved)
151 */ 151 */
152 __CPUINIT
153__lookup_processor_type: 152__lookup_processor_type:
154 adr r3, __lookup_processor_type_data 153 adr r3, __lookup_processor_type_data
155 ldmia r3, {r4 - r6} 154 ldmia r3, {r4 - r6}
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 75f14cc3e073..14235ba64a90 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -87,7 +87,7 @@ ENTRY(stext)
87ENDPROC(stext) 87ENDPROC(stext)
88 88
89#ifdef CONFIG_SMP 89#ifdef CONFIG_SMP
90 __CPUINIT 90 .text
91ENTRY(secondary_startup) 91ENTRY(secondary_startup)
92 /* 92 /*
93 * Common entry point for secondary CPUs. 93 * Common entry point for secondary CPUs.
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 45e8935cae4e..2c7cc1e03473 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -343,7 +343,7 @@ __turn_mmu_on_loc:
343 .long __turn_mmu_on_end 343 .long __turn_mmu_on_end
344 344
345#if defined(CONFIG_SMP) 345#if defined(CONFIG_SMP)
346 __CPUINIT 346 .text
347ENTRY(secondary_startup) 347ENTRY(secondary_startup)
348 /* 348 /*
349 * Common entry point for secondary CPUs. 349 * Common entry point for secondary CPUs.
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 1fd749ee4a1b..7b95de601357 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -1020,7 +1020,7 @@ out_mdbgen:
1020 cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); 1020 cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
1021} 1021}
1022 1022
1023static int __cpuinit dbg_reset_notify(struct notifier_block *self, 1023static int dbg_reset_notify(struct notifier_block *self,
1024 unsigned long action, void *cpu) 1024 unsigned long action, void *cpu)
1025{ 1025{
1026 if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE) 1026 if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
@@ -1029,7 +1029,7 @@ static int __cpuinit dbg_reset_notify(struct notifier_block *self,
1029 return NOTIFY_OK; 1029 return NOTIFY_OK;
1030} 1030}
1031 1031
1032static struct notifier_block __cpuinitdata dbg_reset_nb = { 1032static struct notifier_block dbg_reset_nb = {
1033 .notifier_call = dbg_reset_notify, 1033 .notifier_call = dbg_reset_notify,
1034}; 1034};
1035 1035
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 4910232c4833..797b1a6a4906 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -56,8 +56,8 @@ ENTRY(__boot_cpu_mode)
56 ldr \reg3, [\reg2] 56 ldr \reg3, [\reg2]
57 ldr \reg1, [\reg2, \reg3] 57 ldr \reg1, [\reg2, \reg3]
58 cmp \mode, \reg1 @ matches primary CPU boot mode? 58 cmp \mode, \reg1 @ matches primary CPU boot mode?
59 orrne r7, r7, #BOOT_CPU_MODE_MISMATCH 59 orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH
60 strne r7, [r5, r6] @ record what happened and give up 60 strne \reg1, [\reg2, \reg3] @ record what happened and give up
61 .endm 61 .endm
62 62
63#else /* ZIMAGE */ 63#else /* ZIMAGE */
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 4fb074c446bf..d7c82df69243 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -15,6 +15,7 @@
15#include <asm/mmu_context.h> 15#include <asm/mmu_context.h>
16#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
17#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18#include <asm/smp_plat.h>
18#include <asm/system_misc.h> 19#include <asm/system_misc.h>
19 20
20extern const unsigned char relocate_new_kernel[]; 21extern const unsigned char relocate_new_kernel[];
@@ -39,6 +40,14 @@ int machine_kexec_prepare(struct kimage *image)
39 int i, err; 40 int i, err;
40 41
41 /* 42 /*
43 * Validate that if the current HW supports SMP, then the SW supports
44 * and implements CPU hotplug for the current HW. If not, we won't be
45 * able to kexec reliably, so fail the prepare operation.
46 */
47 if (num_possible_cpus() > 1 && !platform_can_cpu_hotplug())
48 return -EINVAL;
49
50 /*
42 * No segment at default ATAGs address. try to locate 51 * No segment at default ATAGs address. try to locate
43 * a dtb using magic. 52 * a dtb using magic.
44 */ 53 */
@@ -134,10 +143,13 @@ void machine_kexec(struct kimage *image)
134 unsigned long reboot_code_buffer_phys; 143 unsigned long reboot_code_buffer_phys;
135 void *reboot_code_buffer; 144 void *reboot_code_buffer;
136 145
137 if (num_online_cpus() > 1) { 146 /*
138 pr_err("kexec: error: multiple CPUs still online\n"); 147 * This can only happen if machine_shutdown() failed to disable some
139 return; 148 * CPU, and that can only happen if the checks in
140 } 149 * machine_kexec_prepare() were not correct. If this fails, we can't
150 * reliably kexec anyway, so BUG_ON is appropriate.
151 */
152 BUG_ON(num_online_cpus() > 1);
141 153
142 page_list = image->head & PAGE_MASK; 154 page_list = image->head & PAGE_MASK;
143 155
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d9f5cd4e533f..e186ee1e63f6 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -53,7 +53,12 @@ armpmu_map_cache_event(const unsigned (*cache_map)
53static int 53static int
54armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) 54armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
55{ 55{
56 int mapping = (*event_map)[config]; 56 int mapping;
57
58 if (config >= PERF_COUNT_HW_MAX)
59 return -EINVAL;
60
61 mapping = (*event_map)[config];
57 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; 62 return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
58} 63}
59 64
@@ -253,6 +258,9 @@ validate_event(struct pmu_hw_events *hw_events,
253 struct arm_pmu *armpmu = to_arm_pmu(event->pmu); 258 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
254 struct pmu *leader_pmu = event->group_leader->pmu; 259 struct pmu *leader_pmu = event->group_leader->pmu;
255 260
261 if (is_software_event(event))
262 return 1;
263
256 if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) 264 if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
257 return 1; 265 return 1;
258 266
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 1f2740e3dbc0..aebe0e99c153 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -157,8 +157,8 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
157 * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading 157 * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
158 * junk values out of them. 158 * junk values out of them.
159 */ 159 */
160static int __cpuinit cpu_pmu_notify(struct notifier_block *b, 160static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
161 unsigned long action, void *hcpu) 161 void *hcpu)
162{ 162{
163 if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) 163 if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
164 return NOTIFY_DONE; 164 return NOTIFY_DONE;
@@ -171,7 +171,7 @@ static int __cpuinit cpu_pmu_notify(struct notifier_block *b,
171 return NOTIFY_OK; 171 return NOTIFY_OK;
172} 172}
173 173
174static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = { 174static struct notifier_block cpu_pmu_hotplug_notifier = {
175 .notifier_call = cpu_pmu_notify, 175 .notifier_call = cpu_pmu_notify,
176}; 176};
177 177
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d3ca4f6915af..94f6b05f9e24 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -197,6 +197,7 @@ void machine_shutdown(void)
197 */ 197 */
198void machine_halt(void) 198void machine_halt(void)
199{ 199{
200 local_irq_disable();
200 smp_send_stop(); 201 smp_send_stop();
201 202
202 local_irq_disable(); 203 local_irq_disable();
@@ -211,6 +212,7 @@ void machine_halt(void)
211 */ 212 */
212void machine_power_off(void) 213void machine_power_off(void)
213{ 214{
215 local_irq_disable();
214 smp_send_stop(); 216 smp_send_stop();
215 217
216 if (pm_power_off) 218 if (pm_power_off)
@@ -230,6 +232,7 @@ void machine_power_off(void)
230 */ 232 */
231void machine_restart(char *cmd) 233void machine_restart(char *cmd)
232{ 234{
235 local_irq_disable();
233 smp_send_stop(); 236 smp_send_stop();
234 237
235 arm_pm_restart(reboot_mode, cmd); 238 arm_pm_restart(reboot_mode, cmd);
@@ -426,10 +429,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
426} 429}
427 430
428#ifdef CONFIG_MMU 431#ifdef CONFIG_MMU
432#ifdef CONFIG_KUSER_HELPERS
429/* 433/*
430 * The vectors page is always readable from user space for the 434 * The vectors page is always readable from user space for the
431 * atomic helpers and the signal restart code. Insert it into the 435 * atomic helpers. Insert it into the gate_vma so that it is visible
432 * gate_vma so that it is visible through ptrace and /proc/<pid>/mem. 436 * through ptrace and /proc/<pid>/mem.
433 */ 437 */
434static struct vm_area_struct gate_vma = { 438static struct vm_area_struct gate_vma = {
435 .vm_start = 0xffff0000, 439 .vm_start = 0xffff0000,
@@ -458,9 +462,48 @@ int in_gate_area_no_mm(unsigned long addr)
458{ 462{
459 return in_gate_area(NULL, addr); 463 return in_gate_area(NULL, addr);
460} 464}
465#define is_gate_vma(vma) ((vma) == &gate_vma)
466#else
467#define is_gate_vma(vma) 0
468#endif
461 469
462const char *arch_vma_name(struct vm_area_struct *vma) 470const char *arch_vma_name(struct vm_area_struct *vma)
463{ 471{
464 return (vma == &gate_vma) ? "[vectors]" : NULL; 472 return is_gate_vma(vma) ? "[vectors]" :
473 (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
474 "[sigpage]" : NULL;
475}
476
477static struct page *signal_page;
478extern struct page *get_signal_page(void);
479
480int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
481{
482 struct mm_struct *mm = current->mm;
483 unsigned long addr;
484 int ret;
485
486 if (!signal_page)
487 signal_page = get_signal_page();
488 if (!signal_page)
489 return -ENOMEM;
490
491 down_write(&mm->mmap_sem);
492 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
493 if (IS_ERR_VALUE(addr)) {
494 ret = addr;
495 goto up_fail;
496 }
497
498 ret = install_special_mapping(mm, addr, PAGE_SIZE,
499 VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
500 &signal_page);
501
502 if (ret == 0)
503 mm->context.sigpage = addr;
504
505 up_fail:
506 up_write(&mm->mmap_sem);
507 return ret;
465} 508}
466#endif 509#endif
diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
index 219f1d73572a..70ded3fb42d9 100644
--- a/arch/arm/kernel/psci_smp.c
+++ b/arch/arm/kernel/psci_smp.c
@@ -46,8 +46,7 @@
46 46
47extern void secondary_startup(void); 47extern void secondary_startup(void);
48 48
49static int __cpuinit psci_boot_secondary(unsigned int cpu, 49static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
50 struct task_struct *idle)
51{ 50{
52 if (psci_ops.cpu_on) 51 if (psci_ops.cpu_on)
53 return psci_ops.cpu_on(cpu_logical_map(cpu), 52 return psci_ops.cpu_on(cpu_logical_map(cpu),
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 63af9a7ae512..afc2489ee13b 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -836,6 +836,8 @@ static int __init meminfo_cmp(const void *_a, const void *_b)
836void __init hyp_mode_check(void) 836void __init hyp_mode_check(void)
837{ 837{
838#ifdef CONFIG_ARM_VIRT_EXT 838#ifdef CONFIG_ARM_VIRT_EXT
839 sync_boot_mode();
840
839 if (is_hyp_mode_available()) { 841 if (is_hyp_mode_available()) {
840 pr_info("CPU: All CPU(s) started in HYP mode.\n"); 842 pr_info("CPU: All CPU(s) started in HYP mode.\n");
841 pr_info("CPU: Virtualization extensions available.\n"); 843 pr_info("CPU: Virtualization extensions available.\n");
@@ -971,6 +973,7 @@ static const char *hwcap_str[] = {
971 "vfpv4", 973 "vfpv4",
972 "idiva", 974 "idiva",
973 "idivt", 975 "idivt",
976 "vfpd32",
974 "lpae", 977 "lpae",
975 NULL 978 NULL
976}; 979};
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 1c16c35c271a..ab3304225272 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -8,6 +8,7 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/random.h>
11#include <linux/signal.h> 12#include <linux/signal.h>
12#include <linux/personality.h> 13#include <linux/personality.h>
13#include <linux/uaccess.h> 14#include <linux/uaccess.h>
@@ -15,12 +16,11 @@
15 16
16#include <asm/elf.h> 17#include <asm/elf.h>
17#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
19#include <asm/traps.h>
18#include <asm/ucontext.h> 20#include <asm/ucontext.h>
19#include <asm/unistd.h> 21#include <asm/unistd.h>
20#include <asm/vfp.h> 22#include <asm/vfp.h>
21 23
22#include "signal.h"
23
24/* 24/*
25 * For ARM syscalls, we encode the syscall number into the instruction. 25 * For ARM syscalls, we encode the syscall number into the instruction.
26 */ 26 */
@@ -40,11 +40,13 @@
40#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) 40#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
41#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) 41#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
42 42
43const unsigned long sigreturn_codes[7] = { 43static const unsigned long sigreturn_codes[7] = {
44 MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, 44 MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
45 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, 45 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
46}; 46};
47 47
48static unsigned long signal_return_offset;
49
48#ifdef CONFIG_CRUNCH 50#ifdef CONFIG_CRUNCH
49static int preserve_crunch_context(struct crunch_sigframe __user *frame) 51static int preserve_crunch_context(struct crunch_sigframe __user *frame)
50{ 52{
@@ -400,14 +402,20 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
400 __put_user(sigreturn_codes[idx+1], rc+1)) 402 __put_user(sigreturn_codes[idx+1], rc+1))
401 return 1; 403 return 1;
402 404
403 if ((cpsr & MODE32_BIT) && !IS_ENABLED(CONFIG_ARM_MPU)) { 405#ifdef CONFIG_MMU
406 if (cpsr & MODE32_BIT) {
407 struct mm_struct *mm = current->mm;
408
404 /* 409 /*
405 * 32-bit code can use the new high-page 410 * 32-bit code can use the signal return page
406 * signal return code support except when the MPU has 411 * except when the MPU has protected the vectors
407 * protected the vectors page from PL0 412 * page from PL0
408 */ 413 */
409 retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; 414 retcode = mm->context.sigpage + signal_return_offset +
410 } else { 415 (idx << 2) + thumb;
416 } else
417#endif
418 {
411 /* 419 /*
412 * Ensure that the instruction cache sees 420 * Ensure that the instruction cache sees
413 * the return code written onto the stack. 421 * the return code written onto the stack.
@@ -608,3 +616,33 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
608 } while (thread_flags & _TIF_WORK_MASK); 616 } while (thread_flags & _TIF_WORK_MASK);
609 return 0; 617 return 0;
610} 618}
619
620struct page *get_signal_page(void)
621{
622 unsigned long ptr;
623 unsigned offset;
624 struct page *page;
625 void *addr;
626
627 page = alloc_pages(GFP_KERNEL, 0);
628
629 if (!page)
630 return NULL;
631
632 addr = page_address(page);
633
634 /* Give the signal return code some randomness */
635 offset = 0x200 + (get_random_int() & 0x7fc);
636 signal_return_offset = offset;
637
638 /*
639 * Copy signal return handlers into the vector page, and
640 * set sigreturn to be a pointer to these.
641 */
642 memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
643
644 ptr = (unsigned long)addr + offset;
645 flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
646
647 return page;
648}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
deleted file mode 100644
index 5ff067b7c752..000000000000
--- a/arch/arm/kernel/signal.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * linux/arch/arm/kernel/signal.h
3 *
4 * Copyright (C) 2005-2009 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
11
12extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index c5fb5469054b..2dc19349eb19 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -58,7 +58,7 @@ struct secondary_data secondary_data;
58 * control for which core is the next to come out of the secondary 58 * control for which core is the next to come out of the secondary
59 * boot "holding pen" 59 * boot "holding pen"
60 */ 60 */
61volatile int __cpuinitdata pen_release = -1; 61volatile int pen_release = -1;
62 62
63enum ipi_msg_type { 63enum ipi_msg_type {
64 IPI_WAKEUP, 64 IPI_WAKEUP,
@@ -86,7 +86,7 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
86 return pgdir >> ARCH_PGD_SHIFT; 86 return pgdir >> ARCH_PGD_SHIFT;
87} 87}
88 88
89int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) 89int __cpu_up(unsigned int cpu, struct task_struct *idle)
90{ 90{
91 int ret; 91 int ret;
92 92
@@ -138,13 +138,23 @@ void __init smp_init_cpus(void)
138 smp_ops.smp_init_cpus(); 138 smp_ops.smp_init_cpus();
139} 139}
140 140
141int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 141int boot_secondary(unsigned int cpu, struct task_struct *idle)
142{ 142{
143 if (smp_ops.smp_boot_secondary) 143 if (smp_ops.smp_boot_secondary)
144 return smp_ops.smp_boot_secondary(cpu, idle); 144 return smp_ops.smp_boot_secondary(cpu, idle);
145 return -ENOSYS; 145 return -ENOSYS;
146} 146}
147 147
148int platform_can_cpu_hotplug(void)
149{
150#ifdef CONFIG_HOTPLUG_CPU
151 if (smp_ops.cpu_kill)
152 return 1;
153#endif
154
155 return 0;
156}
157
148#ifdef CONFIG_HOTPLUG_CPU 158#ifdef CONFIG_HOTPLUG_CPU
149static void percpu_timer_stop(void); 159static void percpu_timer_stop(void);
150 160
@@ -170,7 +180,7 @@ static int platform_cpu_disable(unsigned int cpu)
170/* 180/*
171 * __cpu_disable runs on the processor to be shutdown. 181 * __cpu_disable runs on the processor to be shutdown.
172 */ 182 */
173int __cpuinit __cpu_disable(void) 183int __cpu_disable(void)
174{ 184{
175 unsigned int cpu = smp_processor_id(); 185 unsigned int cpu = smp_processor_id();
176 int ret; 186 int ret;
@@ -216,7 +226,7 @@ static DECLARE_COMPLETION(cpu_died);
216 * called on the thread which is asking for a CPU to be shutdown - 226 * called on the thread which is asking for a CPU to be shutdown -
217 * waits until shutdown has completed, or it is timed out. 227 * waits until shutdown has completed, or it is timed out.
218 */ 228 */
219void __cpuinit __cpu_die(unsigned int cpu) 229void __cpu_die(unsigned int cpu)
220{ 230{
221 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { 231 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
222 pr_err("CPU%u: cpu didn't die\n", cpu); 232 pr_err("CPU%u: cpu didn't die\n", cpu);
@@ -306,7 +316,7 @@ void __ref cpu_die(void)
306 * Called by both boot and secondaries to move global data into 316 * Called by both boot and secondaries to move global data into
307 * per-processor storage. 317 * per-processor storage.
308 */ 318 */
309static void __cpuinit smp_store_cpu_info(unsigned int cpuid) 319static void smp_store_cpu_info(unsigned int cpuid)
310{ 320{
311 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); 321 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
312 322
@@ -322,7 +332,7 @@ static void percpu_timer_setup(void);
322 * This is the secondary CPU boot entry. We're using this CPUs 332 * This is the secondary CPU boot entry. We're using this CPUs
323 * idle thread stack, but a set of temporary page tables. 333 * idle thread stack, but a set of temporary page tables.
324 */ 334 */
325asmlinkage void __cpuinit secondary_start_kernel(void) 335asmlinkage void secondary_start_kernel(void)
326{ 336{
327 struct mm_struct *mm = &init_mm; 337 struct mm_struct *mm = &init_mm;
328 unsigned int cpu; 338 unsigned int cpu;
@@ -521,7 +531,7 @@ static void broadcast_timer_set_mode(enum clock_event_mode mode,
521{ 531{
522} 532}
523 533
524static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) 534static void broadcast_timer_setup(struct clock_event_device *evt)
525{ 535{
526 evt->name = "dummy_timer"; 536 evt->name = "dummy_timer";
527 evt->features = CLOCK_EVT_FEAT_ONESHOT | 537 evt->features = CLOCK_EVT_FEAT_ONESHOT |
@@ -550,7 +560,7 @@ int local_timer_register(struct local_timer_ops *ops)
550} 560}
551#endif 561#endif
552 562
553static void __cpuinit percpu_timer_setup(void) 563static void percpu_timer_setup(void)
554{ 564{
555 unsigned int cpu = smp_processor_id(); 565 unsigned int cpu = smp_processor_id();
556 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); 566 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
index a98b62dca2fa..c2edfff573c2 100644
--- a/arch/arm/kernel/smp_tlb.c
+++ b/arch/arm/kernel/smp_tlb.c
@@ -70,23 +70,6 @@ static inline void ipi_flush_bp_all(void *ignored)
70 local_flush_bp_all(); 70 local_flush_bp_all();
71} 71}
72 72
73#ifdef CONFIG_ARM_ERRATA_798181
74static int erratum_a15_798181(void)
75{
76 unsigned int midr = read_cpuid_id();
77
78 /* Cortex-A15 r0p0..r3p2 affected */
79 if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
80 return 0;
81 return 1;
82}
83#else
84static int erratum_a15_798181(void)
85{
86 return 0;
87}
88#endif
89
90static void ipi_flush_tlb_a15_erratum(void *arg) 73static void ipi_flush_tlb_a15_erratum(void *arg)
91{ 74{
92 dmb(); 75 dmb();
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index f6fd1d4398c6..25956204ef23 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -187,7 +187,7 @@ core_initcall(twd_cpufreq_init);
187 187
188#endif 188#endif
189 189
190static void __cpuinit twd_calibrate_rate(void) 190static void twd_calibrate_rate(void)
191{ 191{
192 unsigned long count; 192 unsigned long count;
193 u64 waitjiffies; 193 u64 waitjiffies;
@@ -265,7 +265,7 @@ static void twd_get_clock(struct device_node *np)
265/* 265/*
266 * Setup the local clock events for a CPU. 266 * Setup the local clock events for a CPU.
267 */ 267 */
268static int __cpuinit twd_timer_setup(struct clock_event_device *clk) 268static int twd_timer_setup(struct clock_event_device *clk)
269{ 269{
270 struct clock_event_device **this_cpu_clk; 270 struct clock_event_device **this_cpu_clk;
271 int cpu = smp_processor_id(); 271 int cpu = smp_processor_id();
@@ -308,7 +308,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
308 return 0; 308 return 0;
309} 309}
310 310
311static struct local_timer_ops twd_lt_ops __cpuinitdata = { 311static struct local_timer_ops twd_lt_ops = {
312 .setup = twd_timer_setup, 312 .setup = twd_timer_setup,
313 .stop = twd_timer_stop, 313 .stop = twd_timer_stop,
314}; 314};
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index cab094c234ee..ab517fcce21b 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -35,8 +35,6 @@
35#include <asm/tls.h> 35#include <asm/tls.h>
36#include <asm/system_misc.h> 36#include <asm/system_misc.h>
37 37
38#include "signal.h"
39
40static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
41 39
42void *vectors_page; 40void *vectors_page;
@@ -800,15 +798,26 @@ void __init trap_init(void)
800 return; 798 return;
801} 799}
802 800
803static void __init kuser_get_tls_init(unsigned long vectors) 801#ifdef CONFIG_KUSER_HELPERS
802static void __init kuser_init(void *vectors)
804{ 803{
804 extern char __kuser_helper_start[], __kuser_helper_end[];
805 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
806
807 memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
808
805 /* 809 /*
806 * vectors + 0xfe0 = __kuser_get_tls 810 * vectors + 0xfe0 = __kuser_get_tls
807 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 811 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
808 */ 812 */
809 if (tls_emu || has_tls_reg) 813 if (tls_emu || has_tls_reg)
810 memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); 814 memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
811} 815}
816#else
817static void __init kuser_init(void *vectors)
818{
819}
820#endif
812 821
813void __init early_trap_init(void *vectors_base) 822void __init early_trap_init(void *vectors_base)
814{ 823{
@@ -816,33 +825,30 @@ void __init early_trap_init(void *vectors_base)
816 unsigned long vectors = (unsigned long)vectors_base; 825 unsigned long vectors = (unsigned long)vectors_base;
817 extern char __stubs_start[], __stubs_end[]; 826 extern char __stubs_start[], __stubs_end[];
818 extern char __vectors_start[], __vectors_end[]; 827 extern char __vectors_start[], __vectors_end[];
819 extern char __kuser_helper_start[], __kuser_helper_end[]; 828 unsigned i;
820 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
821 829
822 vectors_page = vectors_base; 830 vectors_page = vectors_base;
823 831
824 /* 832 /*
833 * Poison the vectors page with an undefined instruction. This
834 * instruction is chosen to be undefined for both ARM and Thumb
835 * ISAs. The Thumb version is an undefined instruction with a
836 * branch back to the undefined instruction.
837 */
838 for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
839 ((u32 *)vectors_base)[i] = 0xe7fddef1;
840
841 /*
825 * Copy the vectors, stubs and kuser helpers (in entry-armv.S) 842 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
826 * into the vector page, mapped at 0xffff0000, and ensure these 843 * into the vector page, mapped at 0xffff0000, and ensure these
827 * are visible to the instruction stream. 844 * are visible to the instruction stream.
828 */ 845 */
829 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); 846 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
830 memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); 847 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
831 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
832 848
833 /* 849 kuser_init(vectors_base);
834 * Do processor specific fixups for the kuser helpers
835 */
836 kuser_get_tls_init(vectors);
837
838 /*
839 * Copy signal return handlers into the vector page, and
840 * set sigreturn to be a pointer to these.
841 */
842 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
843 sigreturn_codes, sizeof(sigreturn_codes));
844 850
845 flush_icache_range(vectors, vectors + PAGE_SIZE); 851 flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
846 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 852 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
847#else /* ifndef CONFIG_CPU_V7M */ 853#else /* ifndef CONFIG_CPU_V7M */
848 /* 854 /*
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index fa25e4e425f6..7bcee5c9b604 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -148,6 +148,23 @@ SECTIONS
148 . = ALIGN(PAGE_SIZE); 148 . = ALIGN(PAGE_SIZE);
149 __init_begin = .; 149 __init_begin = .;
150#endif 150#endif
151 /*
152 * The vectors and stubs are relocatable code, and the
153 * only thing that matters is their relative offsets
154 */
155 __vectors_start = .;
156 .vectors 0 : AT(__vectors_start) {
157 *(.vectors)
158 }
159 . = __vectors_start + SIZEOF(.vectors);
160 __vectors_end = .;
161
162 __stubs_start = .;
163 .stubs 0x1000 : AT(__stubs_start) {
164 *(.stubs)
165 }
166 . = __stubs_start + SIZEOF(.stubs);
167 __stubs_end = .;
151 168
152 INIT_TEXT_SECTION(8) 169 INIT_TEXT_SECTION(8)
153 .exit.text : { 170 .exit.text : {