public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: "Brown, Len" <len.brown@intel.com>
Cc: linux-acpi@vger.kernel.org,
	Xen-devel <xen-devel@lists.xensource.com>,
	the arch/x86 maintainers <x86@kernel.org>
Subject: Paravirtualizing bits of acpi access
Date: Fri, 20 Mar 2009 23:09:59 -0700	[thread overview]
Message-ID: <49C484B7.20100@goop.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 2371 bytes --]

Hi Len,

I have a patch here ported from the linux2.6.18-xen tree to make host S3 
suspend work under Xen (attached).

The salient part is this:

--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -46,6 +46,9 @@
 #include "accommon.h"
 #include "actables.h"
 
+#include <xen/acpi.h>
+#include <asm/xen/hypervisor.h>
+
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
 
@@ -337,14 +340,19 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	if (!xen_pv_domain()) {
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+						PM1Acontrol);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+						PM1Bcontrol);
+	} else
+		status = acpi_notify_hypervisor_state(sleep_state,
+						      PM1Acontrol, PM1Bcontrol);
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}


where acpi_notify_hypervisor_state() more or less maps directly onto a 
Xen hypercall, which in turn performs the corresponding acpi operation 
from within Xen.

I'm guessing you won't find this patch appealing as-is because it sticks 
a great big if (xen) into an otherwise arch (and OS?) independent piece 
of code.  In this particular instance, its fairly easy to envisage 
encapsulating these two register writes into their own function which 
architectures can override, which makes it fairly easy for me to put a 
Xen hook in somewhere on the arch/x86 side of the fence.

But because Xen ends up doing the low-level cpu state save/restore, 
several other parts of the S3 suspend path can be skipped on the Linux 
side.  I'm wondering if you have any thoughts about how that can be 
done, or if putting the Xen code in as-is is acceptable?

(BTW, xen_pv_domain() expands to a constant 0 when Xen isn't enabled in 
the config, so the Xen-dependent bits will collapse down to nothing.  
But it is defined in asm/xen/hypervisor.h, which is only present on x86 
and ia64 architectures; on the other hand, believe those are the only 
architectures using acpi.)

Thanks,
    J

[-- Attachment #2: xen-s3-sleep.patch --]
[-- Type: text/x-patch, Size: 5123 bytes --]

>From 7bdec2cce7de8fb41207238c61f3075220c70a55 Mon Sep 17 00:00:00 2001
From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Date: Mon, 23 Feb 2009 00:06:06 -0800
Subject: [PATCH] xen: Enable ACPI sleep in Xen

Open CONFIG_ACPI_SLEEP in xenlinux, to enable ACPI based
power management. Basically, user can trigger power event
now by "echo *** > /sys/power/state". Also gear to pm
interface defined between xenlinux and Xen.

Also sync to xen interface headers consequently

[ From http://xenbits.xensource.com/linux-2.6.18-xen.hg
 change c68699484a65 ]

Signed-off-by Ke Yu <ke.yu@intel.com>
Signed-off-by Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>

diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 7c243a2..a89de8d 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -12,6 +12,8 @@
 #include <asm/segment.h>
 #include <asm/desc.h>
 
+#include <asm/xen/hypervisor.h>
+
 #include "realmode/wakeup.h"
 #include "sleep.h"
 
@@ -37,6 +39,9 @@ int acpi_save_state_mem(void)
 {
 	struct wakeup_header *header;
 
+	if (xen_pv_domain())
+		return 0;	/* Xen will do this for us */
+
 	if (!acpi_realmode) {
 		printk(KERN_ERR "Could not allocate memory during boot, "
 		       "S3 disabled\n");
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4..bf719f1 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -46,6 +46,9 @@
 #include "accommon.h"
 #include "actables.h"
 
+#include <xen/acpi.h>
+#include <asm/xen/hypervisor.h>
+
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
 
@@ -337,14 +340,19 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	if (!xen_pv_domain()) {
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+						PM1Acontrol);
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+						PM1Bcontrol);
+	} else
+		status = acpi_notify_hypervisor_state(sleep_state,
+						      PM1Acontrol, PM1Bcontrol);
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 5192666..c855dec 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -59,7 +59,7 @@ static int acpi_sleep_prepare(u32 acpi_state)
 {
 #ifdef CONFIG_ACPI_SLEEP
 	/* do we have a wakeup address for S2 and S3? */
-	if (acpi_state == ACPI_STATE_S3) {
+	if (!xen_pv_domain() && acpi_state == ACPI_STATE_S3) {
 		if (!acpi_wakeup_address) {
 			return -EFAULT;
 		}
@@ -242,7 +242,16 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
 		break;
 
 	case ACPI_STATE_S3:
-		do_suspend_lowlevel();
+		if (!xen_pv_domain())
+			do_suspend_lowlevel();
+		else {
+			/*
+			 * Xen will save and restore CPU context, so
+			 * we can skip that and just go straight to
+			 * the suspend.
+			 */
+			acpi_enter_sleep_state(acpi_state);
+		}
 		break;
 	}
 
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 51cbaa5..0138113 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -76,3 +76,7 @@ config XEN_COMPAT_XENFS
 
 config XEN_XENBUS_FRONTEND
        tristate
+
+config XEN_S3
+       def_bool y
+       depends on XEN_DOM0 && ACPI
\ No newline at end of file
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index bb88673..4b01fc8 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -7,4 +7,6 @@ obj-$(CONFIG_XEN_BALLOON)		+= balloon.o
 obj-$(CONFIG_XEN_DEV_EVTCHN)	+= evtchn.o
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
-obj-$(CONFIG_XENFS)			+= xenfs/
\ No newline at end of file
+obj-$(CONFIG_XENFS)			+= xenfs/
+
+obj-$(CONFIG_XEN_S3)			+= acpi.o
\ No newline at end of file
diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c
new file mode 100644
index 0000000..e6d3d0e
--- /dev/null
+++ b/drivers/xen/acpi.c
@@ -0,0 +1,23 @@
+#include <xen/acpi.h>
+
+#include <xen/interface/platform.h>
+#include <asm/xen/hypercall.h>
+#include <asm/xen/hypervisor.h>
+
+int acpi_notify_hypervisor_state(u8 sleep_state,
+				 u32 pm1a_cnt, u32 pm1b_cnt)
+{
+	struct xen_platform_op op = {
+		.cmd = XENPF_enter_acpi_sleep,
+		.interface_version = XENPF_INTERFACE_VERSION,
+		.u = {
+			.enter_acpi_sleep = {
+				.pm1a_cnt_val = (u16)pm1a_cnt,
+				.pm1b_cnt_val = (u16)pm1b_cnt,
+				.sleep_state = sleep_state,
+			},
+		},
+	};
+
+	return HYPERVISOR_dom0_op(&op);
+}
diff --git a/include/xen/acpi.h b/include/xen/acpi.h
new file mode 100644
index 0000000..0d1e462
--- /dev/null
+++ b/include/xen/acpi.h
@@ -0,0 +1,9 @@
+#ifndef _XEN_ACPI_H
+#define _XEN_ACPI_H
+
+#include <linux/types.h>
+
+int acpi_notify_hypervisor_state(u8 sleep_state,
+				 u32 pm1a_cnt, u32 pm1b_cnd);
+
+#endif	/* _XEN_ACPI_H */

             reply	other threads:[~2009-03-21  6:10 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-21  6:09 Jeremy Fitzhardinge [this message]
2009-03-21 17:10 ` Paravirtualizing bits of acpi access Rafael J. Wysocki
2009-03-22  4:26   ` Jeremy Fitzhardinge
2009-03-22 11:28     ` Rafael J. Wysocki
2009-03-22 13:14       ` Ingo Molnar
2009-03-22 13:17         ` Rafael J. Wysocki
2009-03-22 17:07       ` Jeremy Fitzhardinge
2009-03-22 18:00         ` Rafael J. Wysocki
2009-03-23  3:29         ` Tian, Kevin
2009-03-23 18:20           ` [Xen-devel] " Rafael J. Wysocki
2009-03-23 19:07             ` Jeremy Fitzhardinge
2009-03-23 20:27               ` Rafael J. Wysocki
2009-03-23 20:42                 ` Jeremy Fitzhardinge
2009-03-24  5:14                 ` Jeremy Fitzhardinge
2009-03-24  5:33                   ` Tian, Kevin
2009-03-24  5:42                     ` Jeremy Fitzhardinge
2009-03-24  5:45                       ` Tian, Kevin
2009-03-24  7:05                         ` Jeremy Fitzhardinge
2009-03-24 16:45                           ` Bjorn Helgaas
2009-03-24 17:28                             ` Jeremy Fitzhardinge
2009-03-24 17:51                               ` [Xen-devel] " Cihula, Joseph
2009-03-27 21:57                                 ` Len Brown
2009-03-27 23:20                                   ` Jeremy Fitzhardinge
2009-03-28  1:01                                     ` Len Brown
2009-03-28  2:19                                       ` Tian, Kevin
2009-03-28  3:19                                       ` Jeremy Fitzhardinge
2009-03-28 13:56                                         ` Rafael J. Wysocki
2009-03-24 23:40                               ` Tian, Kevin
2009-03-24 23:51                               ` Tian, Kevin
2009-03-25  0:45                                 ` Jeremy Fitzhardinge
2009-03-23 19:52             ` [Xen-devel] " Matthew Garrett
2009-03-23 20:22               ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49C484B7.20100@goop.org \
    --to=jeremy@goop.org \
    --cc=len.brown@intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox