|
@@ -97,6 +97,14 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
|
|
|
*/
|
|
|
static int have_vcpu_info_placement = 1;
|
|
|
|
|
|
+static void clamp_max_cpus(void)
|
|
|
+{
|
|
|
+#ifdef CONFIG_SMP
|
|
|
+ if (setup_max_cpus > MAX_VIRT_CPUS)
|
|
|
+ setup_max_cpus = MAX_VIRT_CPUS;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
static void xen_vcpu_setup(int cpu)
|
|
|
{
|
|
|
struct vcpu_register_vcpu_info info;
|
|
@@ -104,13 +112,17 @@ static void xen_vcpu_setup(int cpu)
|
|
|
struct vcpu_info *vcpup;
|
|
|
|
|
|
BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
|
|
|
- per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
|
|
|
|
|
|
- if (!have_vcpu_info_placement)
|
|
|
- return; /* already tested, not available */
|
|
|
+ if (cpu < MAX_VIRT_CPUS)
|
|
|
+ per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
|
|
|
|
|
|
- vcpup = &per_cpu(xen_vcpu_info, cpu);
|
|
|
+ if (!have_vcpu_info_placement) {
|
|
|
+ if (cpu >= MAX_VIRT_CPUS)
|
|
|
+ clamp_max_cpus();
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
+ vcpup = &per_cpu(xen_vcpu_info, cpu);
|
|
|
info.mfn = arbitrary_virt_to_mfn(vcpup);
|
|
|
info.offset = offset_in_page(vcpup);
|
|
|
|
|
@@ -125,6 +137,7 @@ static void xen_vcpu_setup(int cpu)
|
|
|
if (err) {
|
|
|
printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err);
|
|
|
have_vcpu_info_placement = 0;
|
|
|
+ clamp_max_cpus();
|
|
|
} else {
|
|
|
/* This cpu is using the registered vcpu info, even if
|
|
|
later ones fail to. */
|