x86: avoid invalid phys_proc_id reference
authorChao Peng <chao.p.peng@linux.intel.com>
Mon, 13 Jul 2015 11:46:48 +0000 (13:46 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 13 Jul 2015 11:46:48 +0000 (13:46 +0200)
phys_proc_id is invalidated in remove_siblinginfo() which gets called
before cpu_smpboot_free(). This means calling cpu_to_socket(cpu) in
cpu_smpboot_free() is not possible to be correct.

This patch moves the invalidating of phys_proc_id from
remove_siblinginfo() to cpu_smpboot_free() so that cpu_to_socket(cpu)
can be used in cpu_smpboot_free().

The same is done for cpu_core_id/compute_unit_id and due to that
cpu_sibling_setup_map is private to the file so it's moved as well.

Reported-by: Dario Faggioli <dario.faggioli@citrix.com>
Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
xen/arch/x86/smpboot.c

index cc4eb0145584fc700e6a712469effa77c144a414..7ead91157bc71d95bd3fca297fbc2775f8d89e58 100644 (file)
@@ -666,6 +666,7 @@ void cpu_exit_clear(unsigned int cpu)
 static void cpu_smpboot_free(unsigned int cpu)
 {
     unsigned int order, socket = cpu_to_socket(cpu);
+    struct cpuinfo_x86 *c = cpu_data;
 
     if ( cpumask_empty(socket_cpumask[socket]) )
     {
@@ -673,6 +674,11 @@ static void cpu_smpboot_free(unsigned int cpu)
         socket_cpumask[socket] = NULL;
     }
 
+    c[cpu].phys_proc_id = XEN_INVALID_SOCKET_ID;
+    c[cpu].cpu_core_id = XEN_INVALID_CORE_ID;
+    c[cpu].compute_unit_id = INVALID_CUID;
+    cpumask_clear_cpu(cpu, &cpu_sibling_setup_map);
+
     free_cpumask_var(per_cpu(cpu_sibling_mask, cpu));
     free_cpumask_var(per_cpu(cpu_core_mask, cpu));
 
@@ -882,7 +888,6 @@ static void
 remove_siblinginfo(int cpu)
 {
     int sibling;
-    struct cpuinfo_x86 *c = cpu_data;
 
     cpumask_clear_cpu(cpu, socket_cpumask[cpu_to_socket(cpu)]);
 
@@ -891,17 +896,13 @@ remove_siblinginfo(int cpu)
         cpumask_clear_cpu(cpu, per_cpu(cpu_core_mask, sibling));
         /* Last thread sibling in this cpu core going down. */
         if ( cpumask_weight(per_cpu(cpu_sibling_mask, cpu)) == 1 )
-            c[sibling].booted_cores--;
+            cpu_data[sibling].booted_cores--;
     }
    
     for_each_cpu(sibling, per_cpu(cpu_sibling_mask, cpu))
         cpumask_clear_cpu(cpu, per_cpu(cpu_sibling_mask, sibling));
     cpumask_clear(per_cpu(cpu_sibling_mask, cpu));
     cpumask_clear(per_cpu(cpu_core_mask, cpu));
-    c[cpu].phys_proc_id = XEN_INVALID_SOCKET_ID;
-    c[cpu].cpu_core_id = XEN_INVALID_CORE_ID;
-    c[cpu].compute_unit_id = INVALID_CUID;
-    cpumask_clear_cpu(cpu, &cpu_sibling_setup_map);
 }
 
 void __cpu_disable(void)