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-f...@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(+)

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 */
--
1.8.1.4
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to