示例#1
0
	/*
	 * We'll stop somewhere inside this hypercall. When it returns,
	 * we'll start resuming after the restore.
	 */
	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));

	shutting_down = SHUTDOWN_INVALID;

	post_suspend();

	gnttab_resume();

	irq_resume();

	time_resume();

	switch_idle_mm();

	local_irq_enable();

	xencons_resume();

	xenbus_resume();

	smp_resume();

	return err;
}
#endif /* CONFIG_XEN */

extern int __xen_suspend(int fast_suspend);

static int shutdown_process(void *__unused)
{
	static char *envp[] = { "HOME=/", "TERM=linux",
				"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
	static char *poweroff_argv[] = { "/sbin/poweroff", NULL };

#ifdef CONFIG_XEN
	extern asmlinkage long sys_reboot(int magic1, int magic2,
					  unsigned int cmd, void *arg);
#endif

	if ((shutting_down == SHUTDOWN_POWEROFF) ||
	    (shutting_down == SHUTDOWN_HALT)) {
		if (call_usermodehelper("/sbin/poweroff", poweroff_argv,
					envp, 0) < 0) {
#ifdef CONFIG_XEN
			sys_reboot(LINUX_REBOOT_MAGIC1,
				   LINUX_REBOOT_MAGIC2,
				   LINUX_REBOOT_CMD_POWER_OFF,
				   NULL);
#endif /* CONFIG_XEN */
		}
	}

	shutting_down = SHUTDOWN_INVALID; /* could try again */

	return 0;
}

#ifndef CONFIG_XEN /* pv-on-hvm */
static int xen_suspend(void *__unused)
{
	int err = __xen_suspend(fast_suspend);
	if (err)
		printk(KERN_ERR "Xen suspend failed (%d)\n", err);
	shutting_down = SHUTDOWN_INVALID;
	return 0;
}
示例#2
0
static int xen_suspend(void *__unused)
{
	int err, old_state;

	daemonize("suspend");
	err = set_cpus_allowed(current, cpumask_of_cpu(0));
	if (err) {
		printk(KERN_ERR "Xen suspend can't run on CPU0 (%d)\n", err);
		goto fail;
	}

	do {
		err = __xen_suspend(fast_suspend, xen_resume_notifier);
		if (err) {
			printk(KERN_ERR "Xen suspend failed (%d)\n", err);
			goto fail;
		}
		if (!suspend_cancelled)
			setup_suspend_evtchn();
		old_state = cmpxchg(
			&shutting_down, SHUTDOWN_RESUMING, SHUTDOWN_INVALID);
	} while (old_state == SHUTDOWN_SUSPEND);

	switch (old_state) {
	case SHUTDOWN_INVALID:
	case SHUTDOWN_SUSPEND:
		BUG();
	case SHUTDOWN_RESUMING:
		break;
	default:
		schedule_work(&shutdown_work);
		break;
	}

	return 0;

 fail:
	old_state = xchg(&shutting_down, SHUTDOWN_INVALID);
	BUG_ON(old_state != SHUTDOWN_SUSPEND);
	return 0;
}