mfn_to_pfn(xen_start_info->console.domU.mfn);
}
-static void post_suspend(void)
+static void post_suspend(int suspend_cancelled)
{
int i, j, k, fpp;
extern unsigned long max_pfn;
extern unsigned long *pfn_to_mfn_frame_list_list;
extern unsigned long *pfn_to_mfn_frame_list[];
+ if (suspend_cancelled) {
+ xen_start_info->store_mfn =
+ pfn_to_mfn(xen_start_info->store_mfn);
+ xen_start_info->console.domU.mfn =
+ pfn_to_mfn(xen_start_info->console.domU.mfn);
+ }
+
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
#define switch_idle_mm() ((void)0)
#define mm_pin_all() ((void)0)
#define pre_suspend() ((void)0)
-#define post_suspend() ((void)0)
+#define post_suspend(x) ((void)0)
#endif
int __xen_suspend(void)
{
- int err;
+ int err, suspend_cancelled;
extern void time_resume(void);
pre_suspend();
/*
- * We'll stop somewhere inside this hypercall. When it returns,
- * we'll start resuming after the restore.
+ * This hypercall returns 1 if suspend was cancelled or the domain was
+ * merely checkpointed, and 0 if it is resuming in a new domain.
*/
- HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+ suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
- post_suspend();
+ post_suspend(suspend_cancelled);
gnttab_resume();
- irq_resume();
+ if (!suspend_cancelled)
+ irq_resume();
time_resume();
local_irq_enable();
- xencons_resume();
-
- xenbus_resume();
+ if (!suspend_cancelled) {
+ xencons_resume();
+ xenbus_resume();
+ } else {
+ xenbus_suspend_cancel();
+ }
smp_resume();
void xs_suspend(void)
{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
-
down_write(&xs_state.suspend_mutex);
-
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- list_for_each_entry(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_unwatch(watch->node, token);
- }
-
mutex_lock(&xs_state.request_mutex);
}
up_write(&xs_state.suspend_mutex);
}
+void xs_suspend_cancel(void)
+{
+ mutex_unlock(&xs_state.request_mutex);
+ up_write(&xs_state.suspend_mutex);
+}
+
static int xenwatch_handle_callback(void *data)
{
struct xs_stored_msg *msg = data;
void unregister_xenbus_watch(struct xenbus_watch *watch);
void xs_suspend(void);
void xs_resume(void);
+void xs_suspend_cancel(void);
/* Used by xenbus_dev to borrow kernel's store connection. */
void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-/* Called from xen core code. */
+/* Prepare for domain suspend: then resume or cancel the suspend. */
void xenbus_suspend(void);
void xenbus_resume(void);
+void xenbus_suspend_cancel(void);
#define XENBUS_IS_ERR_READ(str) ({ \
if (!IS_ERR(str) && strlen(str) == 0) { \