Commit 095c7965 authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt

powerpc: Use more accurate limit for first segment memory allocations

Author: Milton Miller <miltonm@bga.com>

On large machines we are running out of room below 256MB. In some cases we
only need to ensure the allocation is in the first segment, which may be
256MB or 1TB.

Add slb0_limit and use it to specify the upper limit for the irqstack and
emergency stacks.

On a large ppc64 box, this fixes a panic at boot when the crashkernel=
option is specified (previously we would run out of memory below 256MB).
Signed-off-by: default avatarMilton Miller <miltonm@bga.com>
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 5d7a8721
...@@ -424,9 +424,18 @@ void __init setup_system(void) ...@@ -424,9 +424,18 @@ void __init setup_system(void)
DBG(" <- setup_system()\n"); DBG(" <- setup_system()\n");
} }
static u64 slb0_limit(void)
{
if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) {
return 1UL << SID_SHIFT_1T;
}
return 1UL << SID_SHIFT;
}
#ifdef CONFIG_IRQSTACKS #ifdef CONFIG_IRQSTACKS
static void __init irqstack_early_init(void) static void __init irqstack_early_init(void)
{ {
u64 limit = slb0_limit();
unsigned int i; unsigned int i;
/* /*
...@@ -436,10 +445,10 @@ static void __init irqstack_early_init(void) ...@@ -436,10 +445,10 @@ static void __init irqstack_early_init(void)
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
softirq_ctx[i] = (struct thread_info *) softirq_ctx[i] = (struct thread_info *)
__va(lmb_alloc_base(THREAD_SIZE, __va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000)); THREAD_SIZE, limit));
hardirq_ctx[i] = (struct thread_info *) hardirq_ctx[i] = (struct thread_info *)
__va(lmb_alloc_base(THREAD_SIZE, __va(lmb_alloc_base(THREAD_SIZE,
THREAD_SIZE, 0x10000000)); THREAD_SIZE, limit));
} }
} }
#else #else
...@@ -470,7 +479,7 @@ static void __init exc_lvl_early_init(void) ...@@ -470,7 +479,7 @@ static void __init exc_lvl_early_init(void)
*/ */
static void __init emergency_stack_init(void) static void __init emergency_stack_init(void)
{ {
unsigned long limit; u64 limit;
unsigned int i; unsigned int i;
/* /*
...@@ -482,7 +491,7 @@ static void __init emergency_stack_init(void) ...@@ -482,7 +491,7 @@ static void __init emergency_stack_init(void)
* bringup, we need to get at them in real mode. This means they * bringup, we need to get at them in real mode. This means they
* must also be within the RMO region. * must also be within the RMO region.
*/ */
limit = min(0x10000000ULL, lmb.rmo_size); limit = min(slb0_limit(), lmb.rmo_size);
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
unsigned long sp; unsigned long 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