From 2b14e535adc4fe734f6588d80b20a0dd8575a4f8 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Fri, 25 May 2012 23:30:15 +0200 Subject: [PATCH] pvops: ACPI S3 patches for 3.4 kernel --- ...rovide-registration-for-acpi_suspend.patch | 112 ++++++++++ ...nable-ACPI-sleep-via-the-__acpi_os_p.patch | 197 ++++++++++++++++++ ...egister-to-the-acpi_suspend_lowlevel.patch | 53 +++++ series-pvops.conf | 3 + 4 files changed, 365 insertions(+) create mode 100644 patches.xen/pvops-3.4-0001-x86-acpi-sleep-Provide-registration-for-acpi_suspend.patch create mode 100644 patches.xen/pvops-3.4-0002-xen-acpi-sleep-Enable-ACPI-sleep-via-the-__acpi_os_p.patch create mode 100644 patches.xen/pvops-3.4-0003-xen-acpi-sleep-Register-to-the-acpi_suspend_lowlevel.patch diff --git a/patches.xen/pvops-3.4-0001-x86-acpi-sleep-Provide-registration-for-acpi_suspend.patch b/patches.xen/pvops-3.4-0001-x86-acpi-sleep-Provide-registration-for-acpi_suspend.patch new file mode 100644 index 0000000..55cc9f1 --- /dev/null +++ b/patches.xen/pvops-3.4-0001-x86-acpi-sleep-Provide-registration-for-acpi_suspend.patch @@ -0,0 +1,112 @@ +From b2ed886e43ec90bae86d6cae6582b457e76d1fd8 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Thu, 8 Dec 2011 17:16:43 +0800 +Subject: x86/acpi/sleep: Provide registration for acpi_suspend_lowlevel. + +Which by default will be x86_acpi_suspend_lowlevel. +This registration allows us to register another callback +if there is a need to use another platform specific callback. + +CC: Thomas Gleixner +CC: "H. Peter Anvin" +CC: x86@kernel.org +CC: Len Brown +CC: Joseph Cihula +CC: Shane Wang +CC: linux-pm@lists.linux-foundation.org +CC: linux-acpi@vger.kernel.org +CC: Len Brown +Signed-off-by: Liang Tang +[v1: Fix when CONFIG_ACPI_SLEEP is not set] +Signed-off-by: Konrad Rzeszutek Wilk +--- + arch/x86/include/asm/acpi.h | 2 +- + arch/x86/kernel/acpi/boot.c | 7 +++++++ + arch/x86/kernel/acpi/sleep.c | 4 ++-- + arch/x86/kernel/acpi/sleep.h | 2 ++ + drivers/acpi/sleep.c | 2 ++ + 5 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h +index 610001d..68cf060 100644 +--- a/arch/x86/include/asm/acpi.h ++++ b/arch/x86/include/asm/acpi.h +@@ -115,7 +115,7 @@ static inline void acpi_disable_pci(void) + } + + /* Low-level suspend routine. */ +-extern int acpi_suspend_lowlevel(void); ++extern int (*acpi_suspend_lowlevel)(void); + + extern const unsigned char acpi_wakeup_code[]; + #define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code))) +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index ce664f3..c3a5b95 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -44,6 +44,7 @@ + #include + #include + ++#include "sleep.h" /* To include x86_acpi_suspend_lowlevel */ + static int __initdata acpi_force = 0; + u32 acpi_rsdt_forced; + int acpi_disabled; +@@ -558,6 +559,12 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi, + int (*__acpi_register_gsi)(struct device *dev, u32 gsi, + int trigger, int polarity) = acpi_register_gsi_pic; + ++#ifdef CONFIG_ACPI_SLEEP ++int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel; ++#else ++int (*acpi_suspend_lowlevel)(void); ++#endif ++ + /* + * success: return IRQ number (>=0) + * failure: return < 0 +diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c +index 103b6ab..4d2d0b1 100644 +--- a/arch/x86/kernel/acpi/sleep.c ++++ b/arch/x86/kernel/acpi/sleep.c +@@ -25,12 +25,12 @@ static char temp_stack[4096]; + acpi_enter_sleep_state(3, wake_sleep_flags); + } + /** +- * acpi_suspend_lowlevel - save kernel state ++ * x86_acpi_suspend_lowlevel - save kernel state + * + * Create an identity mapped page table and copy the wakeup routine to + * low memory. + */ +-int acpi_suspend_lowlevel(void) ++int x86_acpi_suspend_lowlevel(void) + { + struct wakeup_header *header; + /* address in low memory of the wakeup routine. */ +diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h +index 416d4be..4d3feb5 100644 +--- a/arch/x86/kernel/acpi/sleep.h ++++ b/arch/x86/kernel/acpi/sleep.h +@@ -13,3 +13,5 @@ extern unsigned long acpi_copy_wakeup_routine(unsigned long); + extern void wakeup_long64(void); + + extern void do_suspend_lowlevel(void); ++ ++extern int x86_acpi_suspend_lowlevel(void); +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index 0a7ed69..44dbdde 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -254,6 +254,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) + break; + + case ACPI_STATE_S3: ++ if (!acpi_suspend_lowlevel) ++ return -ENOSYS; + error = acpi_suspend_lowlevel(); + if (error) + return error; +-- +1.7.6.4 + diff --git a/patches.xen/pvops-3.4-0002-xen-acpi-sleep-Enable-ACPI-sleep-via-the-__acpi_os_p.patch b/patches.xen/pvops-3.4-0002-xen-acpi-sleep-Enable-ACPI-sleep-via-the-__acpi_os_p.patch new file mode 100644 index 0000000..48da1d1 --- /dev/null +++ b/patches.xen/pvops-3.4-0002-xen-acpi-sleep-Enable-ACPI-sleep-via-the-__acpi_os_p.patch @@ -0,0 +1,197 @@ +From 9b10575276a220543b8791f2cb8268fbd4a0bc2e Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Thu, 8 Dec 2011 17:32:23 +0800 +Subject: xen/acpi/sleep: Enable ACPI sleep via the __acpi_os_prepare_sleep + +Provide the registration callback to call in the Xen's +ACPI sleep functionality. This means that during S3/S5 +we make a hypercall XENPF_enter_acpi_sleep with the +proper PM1A/PM1B registers. + +Based of Ke Yu's initial idea. +[ From http://xenbits.xensource.com/linux-2.6.18-xen.hg +change c68699484a65 ] + +[v1: Added Copyright and license] +[v2: Added check if PM1A/B the 16-bits MSB contain something. The spec + only uses 16-bits but might have more in future] +Signed-off-by: Liang Tang +Signed-off-by: Konrad Rzeszutek Wilk +--- + arch/x86/xen/enlighten.c | 3 ++ + drivers/xen/Makefile | 2 +- + drivers/xen/acpi.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ + include/xen/acpi.h | 58 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 124 insertions(+), 1 deletions(-) + create mode 100644 drivers/xen/acpi.c + create mode 100644 include/xen/acpi.h + +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 12eb07b..a5277c2 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1275,6 +1276,8 @@ asmlinkage void __init xen_start_kernel(void) + + /* Make sure ACS will be enabled */ + pci_request_acs(); ++ ++ xen_acpi_sleep_register(); + } + #ifdef CONFIG_PCI + /* PCI BIOS service won't work from a PV guest. */ +diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile +index aa31337..77a845f 100644 +--- a/drivers/xen/Makefile ++++ b/drivers/xen/Makefile +@@ -17,7 +17,7 @@ obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o + obj-$(CONFIG_XEN_PVHVM) += platform-pci.o + obj-$(CONFIG_XEN_TMEM) += tmem.o + obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o +-obj-$(CONFIG_XEN_DOM0) += pci.o ++obj-$(CONFIG_XEN_DOM0) += pci.o acpi.o + obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/ + obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o + obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o +diff --git a/drivers/xen/acpi.c b/drivers/xen/acpi.c +new file mode 100644 +index 0000000..119d42a +--- /dev/null ++++ b/drivers/xen/acpi.c +@@ -0,0 +1,62 @@ ++/****************************************************************************** ++ * acpi.c ++ * acpi file for domain 0 kernel ++ * ++ * Copyright (c) 2011 Konrad Rzeszutek Wilk ++ * Copyright (c) 2011 Yu Ke ke.yu@intel.com ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++int xen_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, ++ }, ++ }, ++ }; ++ ++ if ((pm1a_cnt & 0xffff0000) || (pm1b_cnt & 0xffff0000)) { ++ WARN(1, "Using more than 16bits of PM1A/B 0x%x/0x%x!" ++ "Email xen-devel@lists.xensource.com Thank you.\n", \ ++ pm1a_cnt, pm1b_cnt); ++ return -1; ++ } ++ ++ HYPERVISOR_dom0_op(&op); ++ return 1; ++} +diff --git a/include/xen/acpi.h b/include/xen/acpi.h +new file mode 100644 +index 0000000..48a9c01 +--- /dev/null ++++ b/include/xen/acpi.h +@@ -0,0 +1,58 @@ ++/****************************************************************************** ++ * acpi.h ++ * acpi file for domain 0 kernel ++ * ++ * Copyright (c) 2011 Konrad Rzeszutek Wilk ++ * Copyright (c) 2011 Yu Ke ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ ++#ifndef _XEN_ACPI_H ++#define _XEN_ACPI_H ++ ++#include ++ ++#ifdef CONFIG_XEN_DOM0 ++#include ++#include ++#include ++ ++int xen_acpi_notify_hypervisor_state(u8 sleep_state, ++ u32 pm1a_cnt, u32 pm1b_cnd); ++ ++static inline void xen_acpi_sleep_register(void) ++{ ++ if (xen_initial_domain()) ++ acpi_os_set_prepare_sleep( ++ &xen_acpi_notify_hypervisor_state); ++} ++#else ++static inline void xen_acpi_sleep_register(void) ++{ ++} ++#endif ++ ++#endif /* _XEN_ACPI_H */ +-- +1.7.6.4 + diff --git a/patches.xen/pvops-3.4-0003-xen-acpi-sleep-Register-to-the-acpi_suspend_lowlevel.patch b/patches.xen/pvops-3.4-0003-xen-acpi-sleep-Register-to-the-acpi_suspend_lowlevel.patch new file mode 100644 index 0000000..a348c8d --- /dev/null +++ b/patches.xen/pvops-3.4-0003-xen-acpi-sleep-Register-to-the-acpi_suspend_lowlevel.patch @@ -0,0 +1,53 @@ +From 5000cd48f33e3e4d31cdeda0751188794f8bebf4 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Thu, 8 Dec 2011 17:34:58 +0800 +Subject: xen/acpi/sleep: Register to the acpi_suspend_lowlevel a callback. + +We piggyback on "x86/acpi: Provide registration for acpi_suspend_lowlevel." +to register a Xen version of the callback. The callback does not +do anything special - except it omits the x86_acpi_suspend_lowlevel. +It does that b/c during suspend it tries to save cr8 values (which +the hypervisor does not support), and then on resume path the +cr3, cr8, idt, and gdt are all resumed which clashes with what +the hypervisor has set up for the guest. + +Signed-off-by: Liang Tang +Signed-off-by: Konrad Rzeszutek Wilk +--- + include/xen/acpi.h | 16 +++++++++++++++- + 1 files changed, 15 insertions(+), 1 deletions(-) + +diff --git a/include/xen/acpi.h b/include/xen/acpi.h +index 48a9c01..ebaabbb 100644 +--- a/include/xen/acpi.h ++++ b/include/xen/acpi.h +@@ -43,11 +43,25 @@ + int xen_acpi_notify_hypervisor_state(u8 sleep_state, + u32 pm1a_cnt, u32 pm1b_cnd); + ++static inline int xen_acpi_suspend_lowlevel(void) ++{ ++ /* ++ * 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_S3, 0); ++ return 0; ++} ++ + static inline void xen_acpi_sleep_register(void) + { +- if (xen_initial_domain()) ++ if (xen_initial_domain()) { + acpi_os_set_prepare_sleep( + &xen_acpi_notify_hypervisor_state); ++ ++ acpi_suspend_lowlevel = xen_acpi_suspend_lowlevel; ++ } + } + #else + static inline void xen_acpi_sleep_register(void) +-- +1.7.6.4 + diff --git a/series-pvops.conf b/series-pvops.conf index a638e90..2c2f308 100644 --- a/series-pvops.conf +++ b/series-pvops.conf @@ -1,3 +1,6 @@ +patches.xen/pvops-3.4-0001-x86-acpi-sleep-Provide-registration-for-acpi_suspend.patch +patches.xen/pvops-3.4-0002-xen-acpi-sleep-Enable-ACPI-sleep-via-the-__acpi_os_p.patch +patches.xen/pvops-3.4-0003-xen-acpi-sleep-Register-to-the-acpi_suspend_lowlevel.patch patches.xen/pvops-3.4-enable-netfront-in-dom0.patch patches.xen/pvops-netback-calculate-correctly-the-SKB-slots.patch patches.xen/pvops-3.4-0100-usb-xen-pvusb-driver.patch