Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 377221
b: refs/heads/master
c: 19ab428
h: refs/heads/master
i:
  377219: 38bbc45
v: v3
  • Loading branch information
Stephen Warren authored and Russell King committed Jun 17, 2013
1 parent cd6208f commit 861b4ce
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 69f91ff8c93c778cb65b71d9b2d95ff62956354f
refs/heads/master: 19ab428f4b7988ef3ac727c680efc193ef53ce14
2 changes: 1 addition & 1 deletion trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2016,7 +2016,7 @@ config XIP_PHYS_ADDR

config KEXEC
bool "Kexec system call (EXPERIMENTAL)"
depends on (!SMP || HOTPLUG_CPU)
depends on (!SMP || PM_SLEEP_SMP)
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
Expand Down
4 changes: 4 additions & 0 deletions trunk/arch/arm/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ void machine_kexec(struct kimage *image)
unsigned long reboot_code_buffer_phys;
void *reboot_code_buffer;

if (num_online_cpus() > 1) {
pr_err("kexec: error: multiple CPUs still online\n");
return;
}

page_list = image->head & PAGE_MASK;

Expand Down
43 changes: 37 additions & 6 deletions trunk/arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,30 +184,61 @@ int __init reboot_setup(char *str)

__setup("reboot=", reboot_setup);

/*
* Called by kexec, immediately prior to machine_kexec().
*
* This must completely disable all secondary CPUs; simply causing those CPUs
* to execute e.g. a RAM-based pin loop is not sufficient. This allows the
* kexec'd kernel to use any and all RAM as it sees fit, without having to
* avoid any code or data used by any SW CPU pin loop. The CPU hotplug
* functionality embodied in disable_nonboot_cpus() to achieve this.
*/
void machine_shutdown(void)
{
#ifdef CONFIG_SMP
smp_send_stop();
#endif
disable_nonboot_cpus();
}

/*
* Halting simply requires that the secondary CPUs stop performing any
* activity (executing tasks, handling interrupts). smp_send_stop()
* achieves this.
*/
void machine_halt(void)
{
machine_shutdown();
smp_send_stop();

local_irq_disable();
while (1);
}

/*
* Power-off simply requires that the secondary CPUs stop performing any
* activity (executing tasks, handling interrupts). smp_send_stop()
* achieves this. When the system power is turned off, it will take all CPUs
* with it.
*/
void machine_power_off(void)
{
machine_shutdown();
smp_send_stop();

if (pm_power_off)
pm_power_off();
}

/*
* Restart requires that the secondary CPUs stop performing any activity
* while the primary CPU resets the system. Systems with a single CPU can
* use soft_restart() as their machine descriptor's .restart hook, since that
* will cause the only available CPU to reset. Systems with multiple CPUs must
* provide a HW restart implementation, to ensure that all CPUs reset at once.
* This is required so that any code running after reset on the primary CPU
* doesn't have to co-ordinate with other CPUs to ensure they aren't still
* executing pre-reset code, and using RAM that the primary CPU's code wishes
* to use. Implementing such co-ordination would be essentially impossible.
*/
void machine_restart(char *cmd)
{
machine_shutdown();
smp_send_stop();

arm_pm_restart(reboot_mode, cmd);

Expand Down
13 changes: 0 additions & 13 deletions trunk/arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,17 +651,6 @@ void smp_send_reschedule(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}

#ifdef CONFIG_HOTPLUG_CPU
static void smp_kill_cpus(cpumask_t *mask)
{
unsigned int cpu;
for_each_cpu(cpu, mask)
platform_cpu_kill(cpu);
}
#else
static void smp_kill_cpus(cpumask_t *mask) { }
#endif

void smp_send_stop(void)
{
unsigned long timeout;
Expand All @@ -679,8 +668,6 @@ void smp_send_stop(void)

if (num_online_cpus() > 1)
pr_warning("SMP: failed to stop secondary CPUs\n");

smp_kill_cpus(&mask);
}

/*
Expand Down

0 comments on commit 861b4ce

Please sign in to comment.