| Submitter | Phileas Fogg |
|---|---|
| Date | Feb. 22, 2013, 11:41 p.m. |
| Message ID | <51280223.9070109@mail.ru> |
| Download | mbox | patch |
| Permalink | /patch/222687/ |
| State | Not Applicable |
| Headers | show |
Comments
Benjamin Herrenschmidt wrote: > On Fri, 2013-02-22 at 21:49 +0100, Phileas Fogg wrote: >> 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.c > > Awesome ! :-) > > Care to send a patch with a Signed-off-by: ? > > Cheers, > Ben. > > 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. regards From c17cdf38dfe180b4a571827bb547aaf9b678cf29 Mon Sep 17 00:00:00 2001 From: Phileas Fogg <phileas-fogg@mail.ru> 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(+)
Patch
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/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 */