From 5f78b4f36998a026f7a563c9bbce47c66f7af080 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 1 Apr 2005 06:44:03 -0800 Subject: [SPARC64]: Make sure per-cpu area address creates legal TSB value. Older UltraSPARC chips only have a 43-bit sign extended TSB register. So we have to make sure the address we end up with will produce a valid value within that range. Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 57f7f0f45d097..6dff06a44e76e 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1214,10 +1214,24 @@ void __init setup_per_cpu_areas(void) for (size = 1UL; size < goal; size <<= 1UL) __per_cpu_shift++; - ptr = alloc_bootmem_pages(size * NR_CPUS); + /* Make sure the resulting __per_cpu_base value + * will fit in the 43-bit sign extended IMMU + * TSB register. + */ + ptr = __alloc_bootmem(size * NR_CPUS, PAGE_SIZE, + (unsigned long) __per_cpu_start); __per_cpu_base = ptr - __per_cpu_start; + if ((__per_cpu_shift < PAGE_SHIFT) || + (__per_cpu_base & ~PAGE_MASK) || + (__per_cpu_base != (((long) __per_cpu_base << 20) >> 20))) { + prom_printf("PER_CPU: Invalid layout, " + "ptr[%p] shift[%lx] base[%lx]\n", + ptr, __per_cpu_shift, __per_cpu_base); + prom_halt(); + } + for (i = 0; i < NR_CPUS; i++, ptr += size) memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); @@ -1226,7 +1240,5 @@ void __init setup_per_cpu_areas(void) * entry and exit loading of %g5. That is why it * has to be page aligned. */ - BUG_ON((__per_cpu_shift < PAGE_SHIFT) || - (__per_cpu_base & ~PAGE_MASK)); cpu_setup_percpu_base(hard_smp_processor_id()); } -- cgit 1.2.3-korg