Re: PS3: Strange issue with kexec and FreeBSD loader
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2013-02-22 22:45:12
On Sat, 2013-02-23 at 00:41 +0100, Phileas Fogg wrote:
Benjamin Herrenschmidt wrote:quoted
On Fri, 2013-02-22 at 21:49 +0100, Phileas Fogg wrote:quoted
i wanted to let you know that i tested your advice. And let me say, it's was a damn good advice :) I can boot FreeBSD loader on Linux 3.8 now, no SHA256 checksum failures. And no panics with FreeBSD LiveCD anymore too. I just inserted hard_irq_disable() after each local_irq_disable() in arch/powerpc/kernel/machine_kexec_64.cAwesome ! :-) Care to send a patch with a Signed-off-by: ?No problem, but as i said it was your idea how to fix the issue with kexec. Anyways here is the patch which i tested on my PS3 console with Linux 3.8. After applying this patch i can boot any Linux kernel starting with 2.6, FreeBSD loader, FreeBSD LiveCD and my own tiny ELF kernels too. Even OpenBSD bootloader starts now too :) And i don't see any failed SHA256 checksums in the purgatory code.
Thanks, but I still need the Signed-off-by: line before i can apply it :-) (legal...) Cheers, Ben.
quoted hunk ↗ jump to hunk
regards From c17cdf38dfe180b4a571827bb547aaf9b678cf29 Mon Sep 17 00:00:00 2001 From: Phileas Fogg <redacted> Date: Sat, 23 Feb 2013 00:32:19 +0100 Subject: [PATCH] kexec: disable hard IRQ before kexec Disable hard IRQ before kexec a new kernel image. Not doing it can result in corrupted data in the memory segments reserved for the new kernel. --- arch/powerpc/kernel/machine_kexec_64.c | 3 +++ 1 file changed, 3 insertions(+)diff --git a/arch/powerpc/kernel/machine_kexec_64.cb/arch/powerpc/kernel/machine_kexec_64.c index 7206701..e08b9d0 100644--- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c@@ -162,6 +162,7 @@ static int kexec_all_irq_disabled = 0; static void kexec_smp_down(void *arg) { local_irq_disable(); + hard_irq_disable(); mb(); /* make sure our irqs are disabled before we say they are */ get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; while(kexec_all_irq_disabled == 0)@@ -244,6 +245,7 @@ static void kexec_prepare_cpus(void) wake_offline_cpus(); smp_call_function(kexec_smp_down, NULL, /* wait */0); local_irq_disable(); + hard_irq_disable(); mb(); /* make sure IRQs are disabled before we say they are */ get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF;@@ -281,6 +283,7 @@ static void kexec_prepare_cpus(void) if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0, 0); local_irq_disable(); + hard_irq_disable(); } #endif /* SMP */