aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArun KS <arun.linux@gmail.com>2014-05-06 21:41:22 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-05-16 13:03:18 -0400
commit90f51a09ef83703b6c2e0434e0384b61b59699d3 (patch)
tree34e36b07e6172dc74414d9a89b7f35ef0b4f8d55
parenteb631bb5bf5b042202aaaee4a8dd8f863ba2a900 (diff)
arm64: Fix machine_shutdown() definition
This patch ports most of commit 19ab428f4b79 "ARM: 7759/1: decouple CPU offlining from reboot/shutdown" by Stephen Warren from arch/arm to arch/arm64. machine_shutdown() is a hook for kexec. Add a comment saying so, since it isn't obvious from the function name. Halt, power-off, and restart have different requirements re: stopping secondary CPUs than kexec has. The former simply require the secondary CPUs to be quiesced somehow, whereas kexec requires them to be completely non-operational, so that no matter where the kexec target images are written in RAM, they won't influence operation of the secondary CPUS,which could happen if the CPUs were still executing some kind of pin loop. To this end, modify machine_halt, power_off, and restart to call smp_send_stop() directly, rather than calling machine_shutdown(). In machine_shutdown(), replace the call to smp_send_stop() with a call to disable_nonboot_cpus(). This completely disables all but one CPU, thus satisfying the kexec requirements a couple paragraphs above. Signed-off-by: Arun KS <getarunks@gmail.com> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/kernel/process.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 9f2d6020b6c2..ed37c3694cb8 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -114,29 +114,58 @@ void arch_cpu_idle_dead(void)
114} 114}
115#endif 115#endif
116 116
117/*
118 * Called by kexec, immediately prior to machine_kexec().
119 *
120 * This must completely disable all secondary CPUs; simply causing those CPUs
121 * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
122 * kexec'd kernel to use any and all RAM as it sees fit, without having to
123 * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
124 * functionality embodied in disable_nonboot_cpus() to achieve this.
125 */
117void machine_shutdown(void) 126void machine_shutdown(void)
118{ 127{
119#ifdef CONFIG_SMP 128 disable_nonboot_cpus();
120 smp_send_stop();
121#endif
122} 129}
123 130
131/*
132 * Halting simply requires that the secondary CPUs stop performing any
133 * activity (executing tasks, handling interrupts). smp_send_stop()
134 * achieves this.
135 */
124void machine_halt(void) 136void machine_halt(void)
125{ 137{
126 machine_shutdown(); 138 smp_send_stop();
127 while (1); 139 while (1);
128} 140}
129 141
142/*
143 * Power-off simply requires that the secondary CPUs stop performing any
144 * activity (executing tasks, handling interrupts). smp_send_stop()
145 * achieves this. When the system power is turned off, it will take all CPUs
146 * with it.
147 */
130void machine_power_off(void) 148void machine_power_off(void)
131{ 149{
132 machine_shutdown(); 150 smp_send_stop();
133 if (pm_power_off) 151 if (pm_power_off)
134 pm_power_off(); 152 pm_power_off();
135} 153}
136 154
155/*
156 * Restart requires that the secondary CPUs stop performing any activity
157 * while the primary CPU resets the system. Systems with a single CPU can
158 * use soft_restart() as their machine descriptor's .restart hook, since that
159 * will cause the only available CPU to reset. Systems with multiple CPUs must
160 * provide a HW restart implementation, to ensure that all CPUs reset at once.
161 * This is required so that any code running after reset on the primary CPU
162 * doesn't have to co-ordinate with other CPUs to ensure they aren't still
163 * executing pre-reset code, and using RAM that the primary CPU's code wishes
164 * to use. Implementing such co-ordination would be essentially impossible.
165 */
137void machine_restart(char *cmd) 166void machine_restart(char *cmd)
138{ 167{
139 machine_shutdown(); 168 smp_send_stop();
140 169
141 /* Disable interrupts first */ 170 /* Disable interrupts first */
142 local_irq_disable(); 171 local_irq_disable();