[v4][PATCH 5/8] book3e/kexec/kdump: introduce a kexec kernel flag

2013-08-25 Thread Tiejun Chen
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 
---
 arch/powerpc/include/asm/smp.h|1 +
 arch/powerpc/kernel/head_64.S |   10 ++
 arch/powerpc/kernel/misc_64.S |6 ++
 arch/powerpc/platforms/85xx/smp.c |   20 +++-
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 98da78e..92f7e61 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -207,6 +207,7 @@ extern void generic_secondary_thread_init(void);
 extern unsigned long __secondary_hold_spinloop;
 extern unsigned long __secondary_hold_acknowledge;
 extern char __secondary_hold;
+extern unsigned long __run_at_kexec;
 
 extern void __early_start(void);
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index fd42f8a..fa74d20 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -89,6 +89,10 @@ __secondary_hold_spinloop:
 __secondary_hold_acknowledge:
.llong  0x0
 
+   .globl  __run_at_kexec
+__run_at_kexec:
+   .llong  0x0 /* Flag for the secondary kernel from kexec. */
+
 #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
@@ -426,6 +430,7 @@ _STATIC(__after_prom_start)
add r25,r25,r26
 1: mr  r3,r25
bl  .relocate
+
 #if defined(CONFIG_PPC_BOOK3E)
/* In relocatable case we always have to load the address of label 
'name'
 * to set IVPR. So after .relocate we have to update IVPR with current
@@ -463,6 +468,11 @@ _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 049be29..adf60b6 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -639,6 +639,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 */
mflrr5
li  r6,1
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index ea9c626..549948a 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -150,6 +150,9 @@ static int smp_85xx_kick_cpu(int nr)
int hw_cpu = get_hard_smp_processor_id(nr);
int ioremappable;
int ret = 0;
+#ifdef CONFIG_PPC64
+   unsigned long *ptr = NULL;
+#endif
 
WARN_ON(nr < 0 || nr >= NR_CPUS);
WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
@@ -238,11 +241,18 @@ out:
 #else
smp_generic_kick_cpu(nr);
 
-   flush_spin_table(spin_table);
-   out_be32(_table->pir, hw_cpu);
-   out_be64((u64 *)(_table->addr_h),
- __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
-   flush_spin_table(spin_table);
+   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) {
+   flush_spin_table(spin_table);
+   out_be32(_table->pir, hw_cpu);
+   out_be64((u64 *)(_table->addr_h),
+__pa((u64)*((unsigned long long 
*)generic_secondary_smp_init)));
+   flush_spin_table(spin_table);
+   }
 #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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[v4][PATCH 5/8] book3e/kexec/kdump: introduce a kexec kernel flag

2013-08-25 Thread Tiejun Chen
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.c...@windriver.com
---
 arch/powerpc/include/asm/smp.h|1 +
 arch/powerpc/kernel/head_64.S |   10 ++
 arch/powerpc/kernel/misc_64.S |6 ++
 arch/powerpc/platforms/85xx/smp.c |   20 +++-
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 98da78e..92f7e61 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -207,6 +207,7 @@ extern void generic_secondary_thread_init(void);
 extern unsigned long __secondary_hold_spinloop;
 extern unsigned long __secondary_hold_acknowledge;
 extern char __secondary_hold;
+extern unsigned long __run_at_kexec;
 
 extern void __early_start(void);
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index fd42f8a..fa74d20 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -89,6 +89,10 @@ __secondary_hold_spinloop:
 __secondary_hold_acknowledge:
.llong  0x0
 
+   .globl  __run_at_kexec
+__run_at_kexec:
+   .llong  0x0 /* Flag for the secondary kernel from kexec. */
+
 #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
@@ -426,6 +430,7 @@ _STATIC(__after_prom_start)
add r25,r25,r26
 1: mr  r3,r25
bl  .relocate
+
 #if defined(CONFIG_PPC_BOOK3E)
/* In relocatable case we always have to load the address of label 
'name'
 * to set IVPR. So after .relocate we have to update IVPR with current
@@ -463,6 +468,11 @@ _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 049be29..adf60b6 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -639,6 +639,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 */
mflrr5
li  r6,1
diff --git a/arch/powerpc/platforms/85xx/smp.c 
b/arch/powerpc/platforms/85xx/smp.c
index ea9c626..549948a 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -150,6 +150,9 @@ static int smp_85xx_kick_cpu(int nr)
int hw_cpu = get_hard_smp_processor_id(nr);
int ioremappable;
int ret = 0;
+#ifdef CONFIG_PPC64
+   unsigned long *ptr = NULL;
+#endif
 
WARN_ON(nr  0 || nr = NR_CPUS);
WARN_ON(hw_cpu  0 || hw_cpu = NR_CPUS);
@@ -238,11 +241,18 @@ out:
 #else
smp_generic_kick_cpu(nr);
 
-   flush_spin_table(spin_table);
-   out_be32(spin_table-pir, hw_cpu);
-   out_be64((u64 *)(spin_table-addr_h),
- __pa((u64)*((unsigned long long *)generic_secondary_smp_init)));
-   flush_spin_table(spin_table);
+   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) {
+   flush_spin_table(spin_table);
+   out_be32(spin_table-pir, hw_cpu);
+   out_be64((u64 *)(spin_table-addr_h),
+__pa((u64)*((unsigned long long 
*)generic_secondary_smp_init)));
+   flush_spin_table(spin_table);
+   }
 #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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/