|
@@ -615,6 +615,24 @@ void __init exc_lvl_early_init(void)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * Emergency stacks are used for a range of things, from asynchronous
|
|
|
+ * NMIs (system reset, machine check) to synchronous, process context.
|
|
|
+ * We set preempt_count to zero, even though that isn't necessarily correct. To
|
|
|
+ * get the right value we'd need to copy it from the previous thread_info, but
|
|
|
+ * doing that might fault causing more problems.
|
|
|
+ * TODO: what to do with accounting?
|
|
|
+ */
|
|
|
+static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu)
|
|
|
+{
|
|
|
+ ti->task = NULL;
|
|
|
+ ti->cpu = cpu;
|
|
|
+ ti->preempt_count = 0;
|
|
|
+ ti->local_flags = 0;
|
|
|
+ ti->flags = 0;
|
|
|
+ klp_init_thread_info(ti);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Stack space used when we detect a bad kernel stack pointer, and
|
|
|
* early in SMP boots before relocation is enabled. Exclusive emergency
|
|
@@ -633,24 +651,31 @@ void __init emergency_stack_init(void)
|
|
|
* Since we use these as temporary stacks during secondary CPU
|
|
|
* bringup, we need to get at them in real mode. This means they
|
|
|
* must also be within the RMO region.
|
|
|
+ *
|
|
|
+ * The IRQ stacks allocated elsewhere in this file are zeroed and
|
|
|
+ * initialized in kernel/irq.c. These are initialized here in order
|
|
|
+ * to have emergency stacks available as early as possible.
|
|
|
*/
|
|
|
limit = min(safe_stack_limit(), ppc64_rma_size);
|
|
|
|
|
|
for_each_possible_cpu(i) {
|
|
|
struct thread_info *ti;
|
|
|
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
|
|
|
- klp_init_thread_info(ti);
|
|
|
+ memset(ti, 0, THREAD_SIZE);
|
|
|
+ emerg_stack_init_thread_info(ti, i);
|
|
|
paca[i].emergency_sp = (void *)ti + THREAD_SIZE;
|
|
|
|
|
|
#ifdef CONFIG_PPC_BOOK3S_64
|
|
|
/* emergency stack for NMI exception handling. */
|
|
|
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
|
|
|
- klp_init_thread_info(ti);
|
|
|
+ memset(ti, 0, THREAD_SIZE);
|
|
|
+ emerg_stack_init_thread_info(ti, i);
|
|
|
paca[i].nmi_emergency_sp = (void *)ti + THREAD_SIZE;
|
|
|
|
|
|
/* emergency stack for machine check exception handling. */
|
|
|
ti = __va(memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit));
|
|
|
- klp_init_thread_info(ti);
|
|
|
+ memset(ti, 0, THREAD_SIZE);
|
|
|
+ emerg_stack_init_thread_info(ti, i);
|
|
|
paca[i].mc_emergency_sp = (void *)ti + THREAD_SIZE;
|
|
|
#endif
|
|
|
}
|