diff options
Diffstat (limited to 'arch/arm/kernel/machine_kexec.c')
| -rw-r--r-- | arch/arm/kernel/machine_kexec.c | 20 | 
1 files changed, 16 insertions, 4 deletions
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 @@  #include <asm/mmu_context.h>  #include <asm/cacheflush.h>  #include <asm/mach-types.h> +#include <asm/smp_plat.h>  #include <asm/system_misc.h>  extern const unsigned char relocate_new_kernel[]; @@ -39,6 +40,14 @@ int machine_kexec_prepare(struct kimage *image)  	int i, err;  	/* +	 * Validate that if the current HW supports SMP, then the SW supports +	 * and implements CPU hotplug for the current HW. If not, we won't be +	 * able to kexec reliably, so fail the prepare operation. +	 */ +	if (num_possible_cpus() > 1 && !platform_can_cpu_hotplug()) +		return -EINVAL; + +	/*  	 * No segment at default ATAGs address. try to locate  	 * a dtb using magic.  	 */ @@ -134,10 +143,13 @@ 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; -	} +	/* +	 * This can only happen if machine_shutdown() failed to disable some +	 * CPU, and that can only happen if the checks in +	 * machine_kexec_prepare() were not correct. If this fails, we can't +	 * reliably kexec anyway, so BUG_ON is appropriate. +	 */ +	BUG_ON(num_online_cpus() > 1);  	page_list = image->head & PAGE_MASK;  | 
