]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/x86/xen/enlighten.c
Merge branch 'upstream/pvhvm' into upstream/xen
[karo-tx-linux.git] / arch / x86 / xen / enlighten.c
index 6f5345378abc897277d490233365dea2c07a1f20..d4ff5e83621d14d75e1fe3f7632fe09a5ab8670c 100644 (file)
@@ -106,6 +106,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;
@@ -113,13 +121,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);
 
@@ -134,6 +146,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. */
@@ -740,7 +753,6 @@ static void set_xen_basic_apic_ops(void)
 
 #endif
 
-
 static void xen_clts(void)
 {
        struct multicall_space mcs;
@@ -1033,6 +1045,23 @@ static void xen_crash_shutdown(struct pt_regs *regs)
        xen_reboot(SHUTDOWN_crash);
 }
 
+static int
+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+       xen_reboot(SHUTDOWN_crash);
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block xen_panic_block = {
+       .notifier_call= xen_panic_event,
+};
+
+int xen_panic_handler_init(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &xen_panic_block);
+       return 0;
+}
+
 static const struct machine_ops __initdata xen_machine_ops = {
        .restart = xen_restart,
        .halt = xen_machine_halt,