Merge tag 'stable/for-linus-3.5-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-3.10.git] / arch / x86 / xen / smp.c
index ce9e98b..afb250d 100644 (file)
@@ -194,6 +194,7 @@ static void __init xen_fill_possible_map(void)
 static void __init xen_filter_cpu_maps(void)
 {
        int i, rc;
+       unsigned int subtract = 0;
 
        if (!xen_initial_domain())
                return;
@@ -208,8 +209,22 @@ static void __init xen_filter_cpu_maps(void)
                } else {
                        set_cpu_possible(i, false);
                        set_cpu_present(i, false);
+                       subtract++;
                }
        }
+#ifdef CONFIG_HOTPLUG_CPU
+       /* This is akin to using 'nr_cpus' on the Linux command line.
+        * Which is OK as when we use 'dom0_max_vcpus=X' we can only
+        * have up to X, while nr_cpu_ids is greater than X. This
+        * normally is not a problem, except when CPU hotplugging
+        * is involved and then there might be more than X CPUs
+        * in the guest - which will not work as there is no
+        * hypercall to expand the max number of VCPUs an already
+        * running guest has. So cap it up to X. */
+       if (subtract)
+               nr_cpu_ids = nr_cpu_ids - subtract;
+#endif
+
 }
 
 static void __init xen_smp_prepare_boot_cpu(void)
@@ -266,18 +281,8 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
                set_cpu_possible(cpu, false);
        }
 
-       for_each_possible_cpu (cpu) {
-               struct task_struct *idle;
-
-               if (cpu == 0)
-                       continue;
-
-               idle = fork_idle(cpu);
-               if (IS_ERR(idle))
-                       panic("failed fork for CPU %d", cpu);
-
+       for_each_possible_cpu(cpu)
                set_cpu_present(cpu, true);
-       }
 }
 
 static int __cpuinit
@@ -347,9 +352,8 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu)
+static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)
 {
-       struct task_struct *idle = idle_task(cpu);
        int rc;
 
        per_cpu(current_task, cpu) = idle;
@@ -650,10 +654,10 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
        xen_init_lock_cpu(0);
 }
 
-static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
+static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
        int rc;
-       rc = native_cpu_up(cpu);
+       rc = native_cpu_up(cpu, tidle);
        WARN_ON (xen_smp_intr_init(cpu));
        return rc;
 }