powerpc/setup: Add cpu_to_phys_id array
authorNicholas Piggin <npiggin@gmail.com>
Tue, 13 Feb 2018 15:08:18 +0000 (01:08 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 30 Mar 2018 12:34:27 +0000 (23:34 +1100)
Build an array that finds hardware CPU number from logical CPU
number in firmware CPU discovery. Use that rather than setting
paca of other CPUs directly, to begin with. Subsequent patch will
not have pacas allocated at this point.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Fix SMP=n build by adding #ifdef in arch_match_cpu_phys_id()]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/smp.h
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/setup-common.c

index ec7b299350d9a6986866b9ca2ce65fb482b065ff..cfecfee1194b9b72b56501a1cf0c9772138bb72c 100644 (file)
@@ -31,6 +31,7 @@
 
 extern int boot_cpuid;
 extern int spinning_secondaries;
+extern u32 *cpu_to_phys_id;
 
 extern void cpu_die(void);
 extern int cpu_to_chip_id(int cpu);
index 4dffef947b8ab57e47c8019c3e8f6f7b4ad04299..0d59a7128debcd89ef0298758dfdf94ad662e31e 100644 (file)
@@ -874,5 +874,15 @@ EXPORT_SYMBOL(cpu_to_chip_id);
 
 bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
 {
+#ifdef CONFIG_SMP
+       /*
+        * Early firmware scanning must use this rather than
+        * get_hard_smp_processor_id because we don't have pacas allocated
+        * until memory topology is discovered.
+        */
+       if (cpu_to_phys_id != NULL)
+               return (int)phys_id == cpu_to_phys_id[cpu];
+#endif
+
        return (int)phys_id == get_hard_smp_processor_id(cpu);
 }
index 9eaf26318d20f973d41f54e4b48120cdf62d8410..bd79a5644c789d8a4ed749d992b530fbb40cdba3 100644 (file)
@@ -437,6 +437,8 @@ static void __init cpu_init_thread_core_maps(int tpc)
 }
 
 
+u32 *cpu_to_phys_id = NULL;
+
 /**
  * setup_cpu_maps - initialize the following cpu maps:
  *                  cpu_possible_mask
@@ -463,6 +465,10 @@ void __init smp_setup_cpu_maps(void)
 
        DBG("smp_setup_cpu_maps()\n");
 
+       cpu_to_phys_id = __va(memblock_alloc(nr_cpu_ids * sizeof(u32),
+                                                       __alignof__(u32)));
+       memset(cpu_to_phys_id, 0, nr_cpu_ids * sizeof(u32));
+
        for_each_node_by_type(dn, "cpu") {
                const __be32 *intserv;
                __be32 cpu_be;
@@ -480,6 +486,7 @@ void __init smp_setup_cpu_maps(void)
                        intserv = of_get_property(dn, "reg", &len);
                        if (!intserv) {
                                cpu_be = cpu_to_be32(cpu);
+                               /* XXX: what is this? uninitialized?? */
                                intserv = &cpu_be;      /* assume logical == phys */
                                len = 4;
                        }
@@ -499,8 +506,8 @@ void __init smp_setup_cpu_maps(void)
                                                "enable-method", "spin-table");
 
                        set_cpu_present(cpu, avail);
-                       set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j]));
                        set_cpu_possible(cpu, true);
+                       cpu_to_phys_id[cpu] = be32_to_cpu(intserv[j]);
                        cpu++;
                }
 
@@ -570,6 +577,12 @@ void __init smp_setup_cpu_maps(void)
        setup_nr_cpu_ids();
 
        free_unused_pacas();
+
+       for_each_possible_cpu(cpu) {
+               if (cpu == smp_processor_id())
+                       continue;
+               set_hard_smp_processor_id(cpu, cpu_to_phys_id[cpu]);
+       }
 }
 #endif /* CONFIG_SMP */