[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1352972396-13489-5-git-send-email-tiejun.chen@windriver.com>
Date: Thu, 15 Nov 2012 17:39:54 +0800
From: Tiejun Chen <tiejun.chen@...driver.com>
To: <benh@...nel.crashing.org>
CC: <linuxppc-dev@...ts.ozlabs.org>, <linux-kernel@...r.kernel.org>
Subject: [PATCH 4/6] book3e/kexec/kdump: introduce a kexec kernel flag
We need to introduce a flag to indicate we're already running
a kexec kernel then we can go proper path. For example, We
shouldn't access spin_table from the bootloader to up any secondary
cpu for kexec kernel, and kexec kernel already know how to jump to
generic_secondary_smp_init.
Signed-off-by: Tiejun Chen <tiejun.chen@...driver.com>
---
arch/powerpc/include/asm/smp.h | 3 +++
arch/powerpc/kernel/head_64.S | 12 ++++++++++++
arch/powerpc/kernel/misc_64.S | 6 ++++++
arch/powerpc/platforms/85xx/smp.c | 14 ++++++++++++++
4 files changed, 35 insertions(+)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index e807e9d..aadbe9b 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -190,6 +190,9 @@ extern void generic_secondary_thread_init(void);
extern unsigned long __secondary_hold_spinloop;
extern unsigned long __secondary_hold_acknowledge;
extern char __secondary_hold;
+#ifdef CONFIG_KEXEC
+extern unsigned long __run_at_kexec;
+#endif
extern void __early_start(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d51ffc0..9c30d9f 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -89,6 +89,12 @@ __secondary_hold_spinloop:
__secondary_hold_acknowledge:
.llong 0x0
+#if defined(CONFIG_KEXEC) || defined(CONFIG_CRASH_DUMP)
+ .globl __run_at_kexec
+__run_at_kexec:
+ .llong 0x0 /* Flag for the secondary kernel from kexec. */
+#endif
+
#ifdef CONFIG_RELOCATABLE
/* This flag is set to 1 by a loader if the kernel should run
* at the loaded address instead of the linked address. This
@@ -441,6 +447,12 @@ _STATIC(__after_prom_start)
#if defined(CONFIG_PPC_BOOK3E)
tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */
#endif
+#if defined(CONFIG_KEXEC) || defined(CONFIG_CRASH_DUMP)
+ /* If relocated we need to restore this flag on that relocated address. */
+ ld r7,__run_at_kexec-_stext(r3)
+ std r7,__run_at_kexec-_stext(r26)
+#endif
+
lwz r7,__run_at_load-_stext(r26)
#if defined(CONFIG_PPC_BOOK3E)
tophys(r26,r26) /* Restore for the remains. */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index ffe6043..b81f8ac 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -608,6 +608,12 @@ _GLOBAL(kexec_sequence)
bl .copy_and_flush /* (dest, src, copy limit, start offset) */
1: /* assume normal blr return */
+ /* notify we're going into kexec kernel for SMP. */
+ LOAD_REG_ADDR(r3,__run_at_kexec)
+ li r4,1
+ std r4,0(r3)
+ sync
+
/* release other cpus to the new kernel secondary start at 0x60 */
mflr r5
li r6,1
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 6fcfa12..c7febd5 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -137,6 +137,9 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
int hw_cpu = get_hard_smp_processor_id(nr);
int ioremappable;
int ret = 0;
+#if defined(CONFIG_KEXEC) || defined(CONFIG_CRASH_DUMP)
+ unsigned long *ptr;
+#endif
WARN_ON(nr < 0 || nr >= NR_CPUS);
WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
@@ -213,6 +216,14 @@ out:
#else
smp_generic_kick_cpu(nr);
+#if defined(CONFIG_KEXEC) || defined(CONFIG_CRASH_DUMP)
+ ptr = (unsigned long *)((unsigned long)&__run_at_kexec);
+ /* We shouldn't access spin_table from the bootloader to up any
+ * secondary cpu for kexec kernel, and kexec kernel already
+ * know how to jump to generic_secondary_smp_init.
+ */
+ if (!*ptr) {
+#endif
out_be32(&spin_table->pir, hw_cpu);
out_be64((u64 *)(&spin_table->addr_h),
__pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
@@ -220,6 +231,9 @@ out:
if (!ioremappable)
flush_dcache_range((ulong)spin_table,
(ulong)spin_table + sizeof(struct epapr_spin_table));
+#if defined(CONFIG_KEXEC) || defined(CONFIG_CRASH_DUMP)
+ }
+#endif
#endif
local_irq_restore(flags);
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists