From 702d4eb9b3de4398ab99cf0a4e799e552c7ab756 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:54:50 +0000 Subject: xen: no need to delay xen_setup_shutdown_event for hvm guests anymore Now that xenstore_ready is used correctly for PV on HVM guests too, we don't need to delay the initialization of xen_setup_shutdown_event anymore. Signed-off-by: Stefano Stabellini Acked-by: Jeremy Fitzhardinge --- drivers/xen/manage.c | 17 ++++------------- drivers/xen/platform-pci.c | 3 --- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 24177272bcb8..b2a8d7856ce3 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -291,27 +291,18 @@ static int shutdown_event(struct notifier_block *notifier, return NOTIFY_DONE; } -static int __init __setup_shutdown_event(void) -{ - /* Delay initialization in the PV on HVM case */ - if (xen_hvm_domain()) - return 0; - - if (!xen_pv_domain()) - return -ENODEV; - - return xen_setup_shutdown_event(); -} - int xen_setup_shutdown_event(void) { static struct notifier_block xenstore_notifier = { .notifier_call = shutdown_event }; + + if (!xen_domain()) + return -ENODEV; register_xenstore_notifier(&xenstore_notifier); return 0; } EXPORT_SYMBOL_GPL(xen_setup_shutdown_event); -subsys_initcall(__setup_shutdown_event); +subsys_initcall(xen_setup_shutdown_event); diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index afbe041f42c5..319dd0a94d51 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -156,9 +156,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, if (ret) goto out; xenbus_probe(NULL); - ret = xen_setup_shutdown_event(); - if (ret) - goto out; return 0; out: -- cgit v1.2.3 From c80a420995e721099906607b07c09a24543b31d9 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:55:00 +0000 Subject: xen-blkfront: handle Xen major numbers other than XENVBD This patch makes sure blkfront handles correctly virtual device numbers corresponding to Xen emulated IDE and SCSI disks: in those cases blkfront translates the major number to XENVBD and the minor number to a low xvd minor. Note: this behaviour is different from what old xenlinux PV guests used to do: they used to steal an IDE or SCSI major number and use it instead. Signed-off-by: Stefano Stabellini Acked-by: Jeremy Fitzhardinge --- drivers/block/xen-blkfront.c | 79 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index d7aa39e349a6..64d9c6dfc634 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -120,6 +120,10 @@ static DEFINE_SPINLOCK(minor_lock); #define EXTENDED (1<feature_flush ? "enabled" : "disabled"); } +static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) +{ + int major; + major = BLKIF_MAJOR(vdevice); + *minor = BLKIF_MINOR(vdevice); + switch (major) { + case XEN_IDE0_MAJOR: + *offset = (*minor / 64) + EMULATED_HD_DISK_NAME_OFFSET; + *minor = ((*minor / 64) * PARTS_PER_DISK) + + EMULATED_HD_DISK_MINOR_OFFSET; + break; + case XEN_IDE1_MAJOR: + *offset = (*minor / 64) + 2 + EMULATED_HD_DISK_NAME_OFFSET; + *minor = (((*minor / 64) + 2) * PARTS_PER_DISK) + + EMULATED_HD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK0_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK1_MAJOR: + case XEN_SCSI_DISK2_MAJOR: + case XEN_SCSI_DISK3_MAJOR: + case XEN_SCSI_DISK4_MAJOR: + case XEN_SCSI_DISK5_MAJOR: + case XEN_SCSI_DISK6_MAJOR: + case XEN_SCSI_DISK7_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + + ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) + + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + + ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16 * PARTS_PER_DISK) + + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK8_MAJOR: + case XEN_SCSI_DISK9_MAJOR: + case XEN_SCSI_DISK10_MAJOR: + case XEN_SCSI_DISK11_MAJOR: + case XEN_SCSI_DISK12_MAJOR: + case XEN_SCSI_DISK13_MAJOR: + case XEN_SCSI_DISK14_MAJOR: + case XEN_SCSI_DISK15_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + + ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) + + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + + ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16 * PARTS_PER_DISK) + + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XENVBD_MAJOR: + *offset = *minor / PARTS_PER_DISK; + break; + default: + printk(KERN_WARNING "blkfront: your disk configuration is " + "incorrect, please use an xvd device instead\n"); + return -ENODEV; + } + return 0; +} static int xlvbd_alloc_gendisk(blkif_sector_t capacity, struct blkfront_info *info, @@ -441,7 +504,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, { struct gendisk *gd; int nr_minors = 1; - int err = -ENODEV; + int err; unsigned int offset; int minor; int nr_parts; @@ -456,12 +519,20 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, } if (!VDEV_IS_EXTENDED(info->vdevice)) { - minor = BLKIF_MINOR(info->vdevice); - nr_parts = PARTS_PER_DISK; + err = xen_translate_vdev(info->vdevice, &minor, &offset); + if (err) + return err; + nr_parts = PARTS_PER_DISK; } else { minor = BLKIF_MINOR_EXT(info->vdevice); nr_parts = PARTS_PER_EXT_DISK; + offset = minor / nr_parts; + if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) + printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " + "emulated IDE disks,\n\t choose an xvd device name" + "from xvde on\n", info->vdevice); } + err = -ENODEV; if ((minor % nr_parts) == 0) nr_minors = nr_parts; @@ -475,8 +546,6 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, if (gd == NULL) goto release; - offset = minor / nr_parts; - if (nr_minors > 1) { if (offset < 26) sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); -- cgit v1.2.3 From 53d5522cad291a0e93a385e0594b6aea6b54a071 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:55:05 +0000 Subject: xen: make the ballon driver work for hvm domains Signed-off-by: Stefano Stabellini --- drivers/xen/balloon.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 43f9f02c7db0..9294f25dcb2c 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -232,7 +232,7 @@ static int increase_reservation(unsigned long nr_pages) set_phys_to_machine(pfn, frame_list[i]); /* Link back into the page tables if not highmem. */ - if (pfn < max_low_pfn) { + if (!xen_hvm_domain() && pfn < max_low_pfn) { int ret; ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), @@ -280,7 +280,7 @@ static int decrease_reservation(unsigned long nr_pages) scrub_page(page); - if (!PageHighMem(page)) { + if (!xen_hvm_domain() && !PageHighMem(page)) { ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), __pte_ma(0), 0); @@ -392,15 +392,19 @@ static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { - unsigned long pfn, extra_pfn_end; + unsigned long pfn, nr_pages, extra_pfn_end; struct page *page; - if (!xen_pv_domain()) + if (!xen_domain()) return -ENODEV; pr_info("xen_balloon: Initialising balloon driver.\n"); - balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); + if (xen_pv_domain()) + nr_pages = xen_start_info->nr_pages; + else + nr_pages = max_pfn; + balloon_stats.current_pages = min(nr_pages, max_pfn); balloon_stats.target_pages = balloon_stats.current_pages; balloon_stats.balloon_low = 0; balloon_stats.balloon_high = 0; -- cgit v1.2.3 From 552717231e50b478dfd19d63fd97879476ae051d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: do not respond to unknown xenstore control requests The PV xenbus control/shutdown node is written by the toolstack as a request to the guest to perform a particular action (shutdown, reboot, suspend etc). The guest is expected to acknowledge that it will complete a request by clearing the control node. Previously it would acknowledge any request, even if it did not know what to do with it. Specifically in the case where CONFIG_PM_SLEEP is not enabled the kernel would acknowledge a suspend request even though it was not actually going to do anything. Instead make the kernel only acknowledge requests if it is actually going to do something with it. This will improve the toolstack's ability to diagnose and deal with failures. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index b2a8d7856ce3..972bf783a182 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -172,12 +172,39 @@ out: } #endif /* CONFIG_PM_SLEEP */ +struct shutdown_handler { + const char *command; + void (*cb)(void); +}; + +static void do_poweroff(void) +{ + shutting_down = SHUTDOWN_POWEROFF; + orderly_poweroff(false); +} + +static void do_reboot(void) +{ + shutting_down = SHUTDOWN_POWEROFF; /* ? */ + ctrl_alt_del(); +} + static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; struct xenbus_transaction xbt; int err; + static struct shutdown_handler handlers[] = { + { "poweroff", do_poweroff }, + { "halt", do_poweroff }, + { "reboot", do_reboot }, +#ifdef CONFIG_PM_SLEEP + { "suspend", do_suspend }, +#endif + {NULL, NULL}, + }; + static struct shutdown_handler *handler; if (shutting_down != SHUTDOWN_INVALID) return; @@ -194,7 +221,14 @@ static void shutdown_handler(struct xenbus_watch *watch, return; } - xenbus_write(xbt, "control", "shutdown", ""); + for (handler = &handlers[0]; handler->command; handler++) { + if (strcmp(str, handler->command) == 0) + break; + } + + /* Only acknowledge commands which we are prepared to handle. */ + if (handler->cb) + xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { @@ -202,17 +236,8 @@ static void shutdown_handler(struct xenbus_watch *watch, goto again; } - if (strcmp(str, "poweroff") == 0 || - strcmp(str, "halt") == 0) { - shutting_down = SHUTDOWN_POWEROFF; - orderly_poweroff(false); - } else if (strcmp(str, "reboot") == 0) { - shutting_down = SHUTDOWN_POWEROFF; /* ? */ - ctrl_alt_del(); -#ifdef CONFIG_PM_SLEEP - } else if (strcmp(str, "suspend") == 0) { - do_suspend(); -#endif + if (handler->cb) { + handler->cb(); } else { printk(KERN_INFO "Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; -- cgit v1.2.3 From bd1c0ad28451df4610d352c7e438213c84de0c28 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: use HYPERVISOR_suspend for PVHVM case instead of open coding Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 972bf783a182..4dd01865ad18 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -38,7 +38,6 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; static int xen_hvm_suspend(void *data) { int err; - struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -50,7 +49,12 @@ static int xen_hvm_suspend(void *data) return err; } - *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); + /* + * This hypercall returns 1 if suspend was cancelled + * or the domain was merely checkpointed, and 0 if it + * is resuming in a new domain. + */ + *cancelled = HYPERVISOR_suspend(0UL); xen_hvm_post_suspend(*cancelled); gnttab_resume(); -- cgit v1.2.3 From ceb180294790c8a6a437533488616f6b591b49d0 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: refactor cancellation flag into a structure Will add extra fields in subsequent patches. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 4dd01865ad18..5c0184fb9d84 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -34,11 +34,15 @@ enum shutdown_state { /* Ignore multiple shutdown requests. */ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; +struct suspend_info { + int cancelled; +}; + #ifdef CONFIG_PM_SLEEP static int xen_hvm_suspend(void *data) { + struct suspend_info *si = data; int err; - int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -54,12 +58,12 @@ static int xen_hvm_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - *cancelled = HYPERVISOR_suspend(0UL); + si->cancelled = HYPERVISOR_suspend(0UL); - xen_hvm_post_suspend(*cancelled); + xen_hvm_post_suspend(si->cancelled); gnttab_resume(); - if (!*cancelled) { + if (!si->cancelled) { xen_irq_resume(); xen_console_resume(); xen_timer_resume(); @@ -72,8 +76,8 @@ static int xen_hvm_suspend(void *data) static int xen_suspend(void *data) { + struct suspend_info *si = data; int err; - int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -93,13 +97,13 @@ static int xen_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - *cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); + si->cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); - xen_post_suspend(*cancelled); + xen_post_suspend(si->cancelled); gnttab_resume(); xen_mm_unpin_all(); - if (!*cancelled) { + if (!si->cancelled) { xen_irq_resume(); xen_console_resume(); xen_timer_resume(); @@ -113,7 +117,7 @@ static int xen_suspend(void *data) static void do_suspend(void) { int err; - int cancelled = 1; + struct suspend_info si; shutting_down = SHUTDOWN_SUSPEND; @@ -143,20 +147,22 @@ static void do_suspend(void) goto out_resume; } + si.cancelled = 1; + if (xen_hvm_domain()) - err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0)); + err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); else - err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); + err = stop_machine(xen_suspend, &si, cpumask_of(0)); dpm_resume_noirq(PMSG_RESUME); if (err) { printk(KERN_ERR "failed to start xen_suspend: %d\n", err); - cancelled = 1; + si.cancelled = 1; } out_resume: - if (!cancelled) { + if (!si.cancelled) { xen_arch_resume(); xs_resume(); } else -- cgit v1.2.3 From 36b401e2c2788c7b4881115ddbbff603fe4cf78d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: pass extra hypercall argument via suspend_info struct Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5c0184fb9d84..6ce6b91e7645 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -36,6 +36,7 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; struct suspend_info { int cancelled; + unsigned long arg; /* extra hypercall argument */ }; #ifdef CONFIG_PM_SLEEP @@ -58,7 +59,7 @@ static int xen_hvm_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - si->cancelled = HYPERVISOR_suspend(0UL); + si->cancelled = HYPERVISOR_suspend(si->arg); xen_hvm_post_suspend(si->cancelled); gnttab_resume(); @@ -97,7 +98,7 @@ static int xen_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - si->cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); + si->cancelled = HYPERVISOR_suspend(si->arg); xen_post_suspend(si->cancelled); gnttab_resume(); @@ -149,6 +150,11 @@ static void do_suspend(void) si.cancelled = 1; + if (xen_hvm_domain()) + si.arg = 0UL; + else + si.arg = virt_to_mfn(xen_start_info); + if (xen_hvm_domain()) err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); else -- cgit v1.2.3 From 03c8142bd2fb3b87effa6ecb2f8957be588bc85f Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: add "arch" to pre/post suspend hooks xen_pre_device_suspend is unused on ia64. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 6ce6b91e7645..134eb73ca596 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -61,7 +61,7 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_hvm_post_suspend(si->cancelled); + xen_arch_hvm_post_suspend(si->cancelled); gnttab_resume(); if (!si->cancelled) { @@ -91,7 +91,7 @@ static int xen_suspend(void *data) xen_mm_pin_all(); gnttab_suspend(); - xen_pre_suspend(); + xen_arch_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled @@ -100,7 +100,7 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_post_suspend(si->cancelled); + xen_arch_post_suspend(si->cancelled); gnttab_resume(); xen_mm_unpin_all(); -- cgit v1.2.3 From 82043bb60d24d2897074905c94be5a53071e8913 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: refactor non-arch specific pre/post suspend hooks Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 134eb73ca596..33312c09829e 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -39,6 +39,23 @@ struct suspend_info { unsigned long arg; /* extra hypercall argument */ }; +static void xen_hvm_post_suspend(void) +{ + gnttab_resume(); +} + +static void xen_pre_suspend(void) +{ + xen_mm_pin_all(); + gnttab_suspend(); +} + +static void xen_post_suspend(void) +{ + gnttab_resume(); + xen_mm_unpin_all(); +} + #ifdef CONFIG_PM_SLEEP static int xen_hvm_suspend(void *data) { @@ -62,7 +79,7 @@ static int xen_hvm_suspend(void *data) si->cancelled = HYPERVISOR_suspend(si->arg); xen_arch_hvm_post_suspend(si->cancelled); - gnttab_resume(); + xen_hvm_post_suspend(); if (!si->cancelled) { xen_irq_resume(); @@ -89,8 +106,7 @@ static int xen_suspend(void *data) return err; } - xen_mm_pin_all(); - gnttab_suspend(); + xen_pre_suspend(); xen_arch_pre_suspend(); /* @@ -101,8 +117,7 @@ static int xen_suspend(void *data) si->cancelled = HYPERVISOR_suspend(si->arg); xen_arch_post_suspend(si->cancelled); - gnttab_resume(); - xen_mm_unpin_all(); + xen_post_suspend(); if (!si->cancelled) { xen_irq_resume(); -- cgit v1.2.3 From 07af38102fc4f260cc5a2418ec833707f53cdf70 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: move arch specific pre/post suspend hooks into generic hooks Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 33312c09829e..a6bd2e9ca106 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -39,8 +39,9 @@ struct suspend_info { unsigned long arg; /* extra hypercall argument */ }; -static void xen_hvm_post_suspend(void) +static void xen_hvm_post_suspend(int cancelled) { + xen_arch_hvm_post_suspend(cancelled); gnttab_resume(); } @@ -48,10 +49,12 @@ static void xen_pre_suspend(void) { xen_mm_pin_all(); gnttab_suspend(); + xen_arch_pre_suspend(); } -static void xen_post_suspend(void) +static void xen_post_suspend(int cancelled) { + xen_arch_post_suspend(cancelled); gnttab_resume(); xen_mm_unpin_all(); } @@ -78,8 +81,7 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_arch_hvm_post_suspend(si->cancelled); - xen_hvm_post_suspend(); + xen_hvm_post_suspend(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -107,7 +109,6 @@ static int xen_suspend(void *data) } xen_pre_suspend(); - xen_arch_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled @@ -116,8 +117,7 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_arch_post_suspend(si->cancelled); - xen_post_suspend(); + xen_post_suspend(si->cancelled); if (!si->cancelled) { xen_irq_resume(); -- cgit v1.2.3 From 55fb4acef7089a6d4d93ed8caae6c258d06cfaf7 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: pull pre/post suspend hooks out into suspend_info Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') 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; struct suspend_info { int cancelled; unsigned long arg; /* extra hypercall argument */ + void (*pre)(void); + void (*post)(int cancelled); }; static void xen_hvm_post_suspend(int cancelled) @@ -74,6 +76,9 @@ static int xen_hvm_suspend(void *data) return err; } + if (si->pre) + si->pre(); + /* * This hypercall returns 1 if suspend was cancelled * or the domain was merely checkpointed, and 0 if it @@ -81,7 +86,8 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_hvm_post_suspend(si->cancelled); + if (si->post) + si->post(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -108,7 +114,8 @@ static int xen_suspend(void *data) return err; } - xen_pre_suspend(); + if (si->pre) + si->pre(); /* * This hypercall returns 1 if suspend was cancelled @@ -117,7 +124,8 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_post_suspend(si->cancelled); + if (si->post) + si->post(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -165,10 +173,15 @@ static void do_suspend(void) si.cancelled = 1; - if (xen_hvm_domain()) + if (xen_hvm_domain()) { si.arg = 0UL; - else + si.pre = NULL; + si.post = &xen_hvm_post_suspend; + } else { si.arg = virt_to_mfn(xen_start_info); + si.pre = &xen_pre_suspend; + si.post = &xen_post_suspend; + } if (xen_hvm_domain()) err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); -- cgit v1.2.3 From b056b6a0144de90707cd22cf7b4f60bf69c86d59 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: remove xen_hvm_suspend It is now identical to xen_suspend, the differences are encapsulated in the suspend_info struct. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5b7a0a9402e7..ebb292859b59 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -62,44 +62,6 @@ static void xen_post_suspend(int cancelled) } #ifdef CONFIG_PM_SLEEP -static int xen_hvm_suspend(void *data) -{ - struct suspend_info *si = data; - int err; - - BUG_ON(!irqs_disabled()); - - err = sysdev_suspend(PMSG_SUSPEND); - if (err) { - printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n", - err); - return err; - } - - if (si->pre) - si->pre(); - - /* - * This hypercall returns 1 if suspend was cancelled - * or the domain was merely checkpointed, and 0 if it - * is resuming in a new domain. - */ - si->cancelled = HYPERVISOR_suspend(si->arg); - - if (si->post) - si->post(si->cancelled); - - if (!si->cancelled) { - xen_irq_resume(); - xen_console_resume(); - xen_timer_resume(); - } - - sysdev_resume(); - - return 0; -} - static int xen_suspend(void *data) { struct suspend_info *si = data; @@ -183,10 +145,7 @@ static void do_suspend(void) si.post = &xen_post_suspend; } - if (xen_hvm_domain()) - err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); - else - err = stop_machine(xen_suspend, &si, cpumask_of(0)); + err = stop_machine(xen_suspend, &si, cpumask_of(0)); dpm_resume_noirq(PMSG_RESUME); -- cgit v1.2.3