diff options
| -rw-r--r-- | drivers/xen/manage.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index a6bd2e9ca106..5b7a0a9402e7 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
| @@ -37,6 +37,8 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; | |||
| 37 | struct suspend_info { | 37 | struct suspend_info { |
| 38 | int cancelled; | 38 | int cancelled; |
| 39 | unsigned long arg; /* extra hypercall argument */ | 39 | unsigned long arg; /* extra hypercall argument */ |
| 40 | void (*pre)(void); | ||
| 41 | void (*post)(int cancelled); | ||
| 40 | }; | 42 | }; |
| 41 | 43 | ||
| 42 | static void xen_hvm_post_suspend(int cancelled) | 44 | static void xen_hvm_post_suspend(int cancelled) |
| @@ -74,6 +76,9 @@ static int xen_hvm_suspend(void *data) | |||
| 74 | return err; | 76 | return err; |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 79 | if (si->pre) | ||
| 80 | si->pre(); | ||
| 81 | |||
| 77 | /* | 82 | /* |
| 78 | * This hypercall returns 1 if suspend was cancelled | 83 | * This hypercall returns 1 if suspend was cancelled |
| 79 | * or the domain was merely checkpointed, and 0 if it | 84 | * or the domain was merely checkpointed, and 0 if it |
| @@ -81,7 +86,8 @@ static int xen_hvm_suspend(void *data) | |||
| 81 | */ | 86 | */ |
| 82 | si->cancelled = HYPERVISOR_suspend(si->arg); | 87 | si->cancelled = HYPERVISOR_suspend(si->arg); |
| 83 | 88 | ||
| 84 | xen_hvm_post_suspend(si->cancelled); | 89 | if (si->post) |
| 90 | si->post(si->cancelled); | ||
| 85 | 91 | ||
| 86 | if (!si->cancelled) { | 92 | if (!si->cancelled) { |
| 87 | xen_irq_resume(); | 93 | xen_irq_resume(); |
| @@ -108,7 +114,8 @@ static int xen_suspend(void *data) | |||
| 108 | return err; | 114 | return err; |
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | xen_pre_suspend(); | 117 | if (si->pre) |
| 118 | si->pre(); | ||
| 112 | 119 | ||
| 113 | /* | 120 | /* |
| 114 | * This hypercall returns 1 if suspend was cancelled | 121 | * This hypercall returns 1 if suspend was cancelled |
| @@ -117,7 +124,8 @@ static int xen_suspend(void *data) | |||
| 117 | */ | 124 | */ |
| 118 | si->cancelled = HYPERVISOR_suspend(si->arg); | 125 | si->cancelled = HYPERVISOR_suspend(si->arg); |
| 119 | 126 | ||
| 120 | xen_post_suspend(si->cancelled); | 127 | if (si->post) |
| 128 | si->post(si->cancelled); | ||
| 121 | 129 | ||
| 122 | if (!si->cancelled) { | 130 | if (!si->cancelled) { |
| 123 | xen_irq_resume(); | 131 | xen_irq_resume(); |
| @@ -165,10 +173,15 @@ static void do_suspend(void) | |||
| 165 | 173 | ||
| 166 | si.cancelled = 1; | 174 | si.cancelled = 1; |
| 167 | 175 | ||
| 168 | if (xen_hvm_domain()) | 176 | if (xen_hvm_domain()) { |
| 169 | si.arg = 0UL; | 177 | si.arg = 0UL; |
| 170 | else | 178 | si.pre = NULL; |
| 179 | si.post = &xen_hvm_post_suspend; | ||
| 180 | } else { | ||
| 171 | si.arg = virt_to_mfn(xen_start_info); | 181 | si.arg = virt_to_mfn(xen_start_info); |
| 182 | si.pre = &xen_pre_suspend; | ||
| 183 | si.post = &xen_post_suspend; | ||
| 184 | } | ||
| 172 | 185 | ||
| 173 | if (xen_hvm_domain()) | 186 | if (xen_hvm_domain()) |
| 174 | err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); | 187 | err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); |
