mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 04:01:48 -04:00
Merge branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm
* 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm: xen: suspend: remove xen_hvm_suspend xen: suspend: pull pre/post suspend hooks out into suspend_info xen: suspend: move arch specific pre/post suspend hooks into generic hooks xen: suspend: refactor non-arch specific pre/post suspend hooks xen: suspend: add "arch" to pre/post suspend hooks xen: suspend: pass extra hypercall argument via suspend_info struct xen: suspend: refactor cancellation flag into a structure xen: suspend: use HYPERVISOR_suspend for PVHVM case instead of open coding xen: switch to new schedop hypercall by default. xen: use new schedop interface for suspend xen: do not respond to unknown xenstore control requests xen: fix compile issue if XEN is enabled but XEN_PVHVM is disabled xen: PV on HVM: support PV spinlocks and IPIs xen: make the ballon driver work for hvm domains xen-blkfront: handle Xen major numbers other than XENVBD xen: do not use xen_info on HVM, set pv_info name to "Xen HVM" xen: no need to delay xen_setup_shutdown_event for hvm guests anymore
This commit is contained in:
commit
76ca078328
13 changed files with 257 additions and 101 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -34,42 +34,38 @@ enum shutdown_state {
|
|||
/* Ignore multiple shutdown requests. */
|
||||
static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int xen_hvm_suspend(void *data)
|
||||
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)
|
||||
{
|
||||
int err;
|
||||
struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
|
||||
int *cancelled = data;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
*cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
|
||||
|
||||
xen_hvm_post_suspend(*cancelled);
|
||||
xen_arch_hvm_post_suspend(cancelled);
|
||||
gnttab_resume();
|
||||
|
||||
if (!*cancelled) {
|
||||
xen_irq_resume();
|
||||
xen_console_resume();
|
||||
xen_timer_resume();
|
||||
}
|
||||
|
||||
sysdev_resume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xen_pre_suspend(void)
|
||||
{
|
||||
xen_mm_pin_all();
|
||||
gnttab_suspend();
|
||||
xen_arch_pre_suspend();
|
||||
}
|
||||
|
||||
static void xen_post_suspend(int cancelled)
|
||||
{
|
||||
xen_arch_post_suspend(cancelled);
|
||||
gnttab_resume();
|
||||
xen_mm_unpin_all();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int xen_suspend(void *data)
|
||||
{
|
||||
struct suspend_info *si = data;
|
||||
int err;
|
||||
int *cancelled = data;
|
||||
|
||||
BUG_ON(!irqs_disabled());
|
||||
|
||||
|
|
@ -80,22 +76,20 @@ static int xen_suspend(void *data)
|
|||
return err;
|
||||
}
|
||||
|
||||
xen_mm_pin_all();
|
||||
gnttab_suspend();
|
||||
xen_pre_suspend();
|
||||
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.
|
||||
*/
|
||||
*cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
|
||||
si->cancelled = HYPERVISOR_suspend(si->arg);
|
||||
|
||||
xen_post_suspend(*cancelled);
|
||||
gnttab_resume();
|
||||
xen_mm_unpin_all();
|
||||
if (si->post)
|
||||
si->post(si->cancelled);
|
||||
|
||||
if (!*cancelled) {
|
||||
if (!si->cancelled) {
|
||||
xen_irq_resume();
|
||||
xen_console_resume();
|
||||
xen_timer_resume();
|
||||
|
|
@ -109,7 +103,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;
|
||||
|
||||
|
|
@ -139,20 +133,29 @@ static void do_suspend(void)
|
|||
goto out_resume;
|
||||
}
|
||||
|
||||
if (xen_hvm_domain())
|
||||
err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0));
|
||||
else
|
||||
err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
|
||||
si.cancelled = 1;
|
||||
|
||||
if (xen_hvm_domain()) {
|
||||
si.arg = 0UL;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -172,12 +175,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 +224,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 +239,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;
|
||||
|
|
@ -291,27 +319,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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue