Commit 7c9465d1 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Ben Hutchings

powerpc/64: Initialise thread_info for emergency stacks

commit 34f19ff1 upstream.

Emergency stacks have their thread_info mostly uninitialised, which in
particular means garbage preempt_count values.

Emergency stack code runs with interrupts disabled entirely, and is
used very rarely, so this has been unnoticed so far. It was found by a
proposed new powerpc watchdog that takes a soft-NMI directly from the
masked_interrupt handler and using the emergency stack. That crashed
at BUG_ON(in_nmi()) in nmi_enter(). preempt_count()s were found to be
garbage.

To fix this, zero the entire THREAD_SIZE allocation, and initialize
the thread_info.
Reported-by: default avatarAbdul Haleem <abdhalee@linux.vnet.ibm.com>
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
[mpe: Move it all into setup_64.c, use a function not a macro. Fix
      crashes on Cell by setting preempt_count to 0 not HARDIRQ_OFFSET]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
[bwh: Backported to 3.2:
 - There's only one emergency stack
 - No need to call klp_init_thread_info()
 - Add the ti variable in emergency_stack_init()]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 852ea2ac
......@@ -508,6 +508,23 @@ static void __init exc_lvl_early_init(void)
#define exc_lvl_early_init()
#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;
}
/*
* Stack space used when we detect a bad kernel stack pointer, and
* early in SMP boots before relocation is enabled.
......@@ -525,12 +542,20 @@ static 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) {
unsigned long sp;
struct thread_info *ti;
sp = memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
ti = __va(sp);
memset(ti, 0, THREAD_SIZE);
emerg_stack_init_thread_info(ti, i);
sp += THREAD_SIZE;
paca[i].emergency_sp = __va(sp);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment