]> Pileus Git - ~andy/linux/blobdiff - arch/powerpc/kernel/setup_64.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[~andy/linux] / arch / powerpc / kernel / setup_64.c
index 856dd4e99bfe459cdb430f5cba6fbc0b3229be89..f5f11a7d30e5502637d58656b7c587b37001ea81 100644 (file)
@@ -97,6 +97,36 @@ int dcache_bsize;
 int icache_bsize;
 int ucache_bsize;
 
+#if defined(CONFIG_PPC_BOOK3E) && defined(CONFIG_SMP)
+static void setup_tlb_core_data(void)
+{
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               int first = cpu_first_thread_sibling(cpu);
+
+               paca[cpu].tcd_ptr = &paca[first].tcd;
+
+               /*
+                * If we have threads, we need either tlbsrx.
+                * or e6500 tablewalk mode, or else TLB handlers
+                * will be racy and could produce duplicate entries.
+                */
+               if (smt_enabled_at_boot >= 2 &&
+                   !mmu_has_feature(MMU_FTR_USE_TLBRSRV) &&
+                   book3e_htw_mode != PPC_HTW_E6500) {
+                       /* Should we panic instead? */
+                       WARN_ONCE("%s: unsupported MMU configuration -- expect problems\n",
+                                 __func__);
+               }
+       }
+}
+#else
+static void setup_tlb_core_data(void)
+{
+}
+#endif
+
 #ifdef CONFIG_SMP
 
 static char *smt_enabled_cmdline;
@@ -445,6 +475,7 @@ void __init setup_system(void)
 
        smp_setup_cpu_maps();
        check_smt_enabled();
+       setup_tlb_core_data();
 
 #ifdef CONFIG_SMP
        /* Release secondary cpus out of their spinloops at 0x60 now that
@@ -520,9 +551,6 @@ static void __init irqstack_early_init(void)
 #ifdef CONFIG_PPC_BOOK3E
 static void __init exc_lvl_early_init(void)
 {
-       extern unsigned int interrupt_base_book3e;
-       extern unsigned int exc_debug_debug_book3e;
-
        unsigned int i;
 
        for_each_possible_cpu(i) {
@@ -535,8 +563,7 @@ static void __init exc_lvl_early_init(void)
        }
 
        if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC))
-               patch_branch(&interrupt_base_book3e + (0x040 / 4) + 1,
-                            (unsigned long)&exc_debug_debug_book3e, 0);
+               patch_exception(0x040, exc_debug_debug_book3e);
 }
 #else
 #define exc_lvl_early_init()
@@ -544,7 +571,8 @@ static void __init exc_lvl_early_init(void)
 
 /*
  * Stack space used when we detect a bad kernel stack pointer, and
- * early in SMP boots before relocation is enabled.
+ * early in SMP boots before relocation is enabled. Exclusive emergency
+ * stack for machine checks.
  */
 static void __init emergency_stack_init(void)
 {
@@ -567,6 +595,13 @@ static void __init emergency_stack_init(void)
                sp  = memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
                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);
+               sp += THREAD_SIZE;
+               paca[i].mc_emergency_sp = __va(sp);
+#endif
        }
 }