powerpc/e6500: kexec: Handle hardware threads
The new kernel will be expecting secondary threads to be disabled, not spinning. Signed-off-by: Scott Wood <scottwood@freescale.com>
This commit is contained in:
parent
939fbf0080
commit
f34b3e19fd
@ -182,6 +182,8 @@ exception_marker:
|
|||||||
|
|
||||||
#ifdef CONFIG_PPC_BOOK3E
|
#ifdef CONFIG_PPC_BOOK3E
|
||||||
_GLOBAL(fsl_secondary_thread_init)
|
_GLOBAL(fsl_secondary_thread_init)
|
||||||
|
mfspr r4,SPRN_BUCSR
|
||||||
|
|
||||||
/* Enable branch prediction */
|
/* Enable branch prediction */
|
||||||
lis r3,BUCSR_INIT@h
|
lis r3,BUCSR_INIT@h
|
||||||
ori r3,r3,BUCSR_INIT@l
|
ori r3,r3,BUCSR_INIT@l
|
||||||
@ -196,10 +198,24 @@ _GLOBAL(fsl_secondary_thread_init)
|
|||||||
* number. There are two threads per core, so shift everything
|
* number. There are two threads per core, so shift everything
|
||||||
* but the low bit right by two bits so that the cpu numbering is
|
* but the low bit right by two bits so that the cpu numbering is
|
||||||
* continuous.
|
* continuous.
|
||||||
|
*
|
||||||
|
* If the old value of BUCSR is non-zero, this thread has run
|
||||||
|
* before. Thus, we assume we are coming from kexec or a similar
|
||||||
|
* scenario, and PIR is already set to the correct value. This
|
||||||
|
* is a bit of a hack, but there are limited opportunities for
|
||||||
|
* getting information into the thread and the alternatives
|
||||||
|
* seemed like they'd be overkill. We can't tell just by looking
|
||||||
|
* at the old PIR value which state it's in, since the same value
|
||||||
|
* could be valid for one thread out of reset and for a different
|
||||||
|
* thread in Linux.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mfspr r3, SPRN_PIR
|
mfspr r3, SPRN_PIR
|
||||||
|
cmpwi r4,0
|
||||||
|
bne 1f
|
||||||
rlwimi r3, r3, 30, 2, 30
|
rlwimi r3, r3, 30, 2, 30
|
||||||
mtspr SPRN_PIR, r3
|
mtspr SPRN_PIR, r3
|
||||||
|
1:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_GLOBAL(generic_secondary_thread_init)
|
_GLOBAL(generic_secondary_thread_init)
|
||||||
|
@ -374,9 +374,55 @@ static void mpc85xx_smp_kexec_down(void *arg)
|
|||||||
#else
|
#else
|
||||||
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
|
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
|
||||||
{
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
int sibling = cpu_last_thread_sibling(cpu);
|
||||||
|
bool notified = false;
|
||||||
|
int disable_cpu;
|
||||||
|
int disable_threadbit = 0;
|
||||||
|
long start = mftb();
|
||||||
|
long now;
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
mpic_teardown_this_cpu(secondary);
|
mpic_teardown_this_cpu(secondary);
|
||||||
|
|
||||||
|
if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
|
||||||
|
/*
|
||||||
|
* We enter the crash kernel on whatever cpu crashed,
|
||||||
|
* even if it's a secondary thread. If that's the case,
|
||||||
|
* disable the corresponding primary thread.
|
||||||
|
*/
|
||||||
|
disable_threadbit = 1;
|
||||||
|
disable_cpu = cpu_first_thread_sibling(cpu);
|
||||||
|
} else if (sibling != crashing_cpu &&
|
||||||
|
cpu_thread_in_core(cpu) == 0 &&
|
||||||
|
cpu_thread_in_core(sibling) != 0) {
|
||||||
|
disable_threadbit = 2;
|
||||||
|
disable_cpu = sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disable_threadbit) {
|
||||||
|
while (paca[disable_cpu].kexec_state < KEXEC_STATE_REAL_MODE) {
|
||||||
|
barrier();
|
||||||
|
now = mftb();
|
||||||
|
if (!notified && now - start > 1000000) {
|
||||||
|
pr_info("%s/%d: waiting for cpu %d to enter KEXEC_STATE_REAL_MODE (%d)\n",
|
||||||
|
__func__, smp_processor_id(),
|
||||||
|
disable_cpu,
|
||||||
|
paca[disable_cpu].kexec_state);
|
||||||
|
notified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notified) {
|
||||||
|
pr_info("%s: cpu %d done waiting\n",
|
||||||
|
__func__, disable_cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtspr(SPRN_TENC, disable_threadbit);
|
||||||
|
while (mfspr(SPRN_TENSR) & disable_threadbit)
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user