ia64/xen-unstable

view unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c @ 16242:3d97c1c1f7c8

pv-on-hvm: fixes for unmodified drivers build and modern Linux

- The adjustments to README and overrides.mk are generic.
- The removal of explicit linux/config.h inclusion should also not
cause any issues.
- The introduction of irq_handler_t should eliminiate warnings on
2.6.19+ kernels (I didn't check they're there, but since the
request_irq prototype changed, I'm sure there's at least
one. However, as a result changes to the Linux tree are expected to
be required.
- The change setup_xen_features -> xen_setup_features follows the
naming in mainline 2.6.23 but would apparently also require changes
to the Linux tree.
- The changes SA_* -> IRQF_ and pci_module_init ->
pci_register_driver should also not cause issues.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 25 15:54:19 2007 +0100 (2007-10-25)
parents f779ee15c553
children 1c826ea72a80
line source
1 #include <linux/cpumask.h>
2 #include <linux/preempt.h>
3 #include <xen/evtchn.h>
4 #include <xen/gnttab.h>
5 #include <xen/xenbus.h>
6 #include "platform-pci.h"
7 #include <asm/hypervisor.h>
9 struct ap_suspend_info {
10 int do_spin;
11 atomic_t nr_spinning;
12 };
14 /*
15 * Use a rwlock to protect the hypercall page from being executed in AP context
16 * while the BSP is re-initializing it after restore.
17 */
18 static DEFINE_RWLOCK(suspend_lock);
20 #ifdef CONFIG_SMP
22 /*
23 * Spinning prevents, for example, APs touching grant table entries while
24 * the shared grant table is not mapped into the address space imemdiately
25 * after resume.
26 */
27 static void ap_suspend(void *_info)
28 {
29 struct ap_suspend_info *info = _info;
31 BUG_ON(!irqs_disabled());
33 atomic_inc(&info->nr_spinning);
34 mb();
36 while (info->do_spin) {
37 cpu_relax();
38 read_lock(&suspend_lock);
39 HYPERVISOR_yield();
40 read_unlock(&suspend_lock);
41 }
43 mb();
44 atomic_dec(&info->nr_spinning);
45 }
47 #define initiate_ap_suspend(i) smp_call_function(ap_suspend, i, 0, 0)
49 #else /* !defined(CONFIG_SMP) */
51 #define initiate_ap_suspend(i) 0
53 #endif
55 static int bp_suspend(void)
56 {
57 int suspend_cancelled;
59 BUG_ON(!irqs_disabled());
61 suspend_cancelled = HYPERVISOR_shutdown(SHUTDOWN_suspend);
63 if (!suspend_cancelled) {
64 write_lock(&suspend_lock);
65 platform_pci_resume();
66 write_unlock(&suspend_lock);
67 gnttab_resume();
68 irq_resume();
69 }
71 return suspend_cancelled;
72 }
74 int __xen_suspend(int fast_suspend)
75 {
76 int err, suspend_cancelled, nr_cpus;
77 struct ap_suspend_info info;
79 xenbus_suspend();
81 preempt_disable();
83 /* Prevent any races with evtchn_interrupt() handler. */
84 disable_irq(xen_platform_pdev->irq);
86 info.do_spin = 1;
87 atomic_set(&info.nr_spinning, 0);
88 smp_mb();
90 nr_cpus = num_online_cpus() - 1;
92 err = initiate_ap_suspend(&info);
93 if (err < 0) {
94 preempt_enable();
95 xenbus_suspend_cancel();
96 return err;
97 }
99 while (atomic_read(&info.nr_spinning) != nr_cpus)
100 cpu_relax();
102 local_irq_disable();
103 suspend_cancelled = bp_suspend();
104 local_irq_enable();
106 smp_mb();
107 info.do_spin = 0;
108 while (atomic_read(&info.nr_spinning) != 0)
109 cpu_relax();
111 enable_irq(xen_platform_pdev->irq);
113 preempt_enable();
115 if (!suspend_cancelled)
116 xenbus_resume();
117 else
118 xenbus_suspend_cancel();
120 return 0;
121 }