lkml.org 
[lkml]   [2017]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subject[PATCH 3.16 213/233] powerpc/64: Initialise thread_info for emergency stacks
3.16.48-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Nicholas Piggin <npiggin@gmail.com>

commit 34f19ff1b5a0d11e46df479623d6936460105c9f 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: Abdul Haleem <abdhalee@linux.vnet.ibm.com>
Signed-off-by: Nicholas 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: Michael Ellerman <mpe@ellerman.id.au>
[bwh: Backported to 3.16:
- There are only two emergency stacks
- No need to call klp_init_thread_info()
- Add the ti variable in emergency_stack_init()]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
arch/powerpc/kernel/setup_64.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)

--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -615,6 +615,23 @@ static void __init exc_lvl_early_init(vo
#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. Exclusive emergency
* stack for machine checks.
@@ -632,18 +649,29 @@ static void __init emergency_stack_init(
* 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);

#ifdef CONFIG_PPC_BOOK3S_64
/* emergency stack for machine check exception handling. */
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].mc_emergency_sp = __va(sp);
#endif
\
 
 \ /
  Last update: 2017-09-10 00:28    [W:1.019 / U:0.056 seconds]
©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site