diff options
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/core/reboot.c | 19 | ||||
-rw-r--r-- | tools/python/xen/lowlevel/xc/xc.c | 28 | ||||
-rw-r--r-- | tools/python/xen/xend/XendConstants.py | 7 | ||||
-rw-r--r-- | tools/python/xen/xend/XendDomainInfo.py | 11 | ||||
-rw-r--r-- | unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 35 | ||||
-rw-r--r-- | xen/arch/x86/hvm/hvm.c | 1 |
6 files changed, 93 insertions, 8 deletions
diff --git a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c index 0dcd2fa252..aa6215c93e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c @@ -33,7 +33,24 @@ static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); #ifdef CONFIG_XEN int __xen_suspend(int fast_suspend); #else -#define __xen_suspend(fast_suspend) 0 +extern void xenbus_suspend(void); +extern void xenbus_resume(void); +extern void platform_pci_suspend(void); +extern void platform_pci_resume(void); +int __xen_suspend(int fast_suspend) +{ + xenbus_suspend(); + platform_pci_suspend(); + + /* pvdrv sleep in this hyper-call when save */ + HYPERVISOR_shutdown(SHUTDOWN_suspend); + + platform_pci_resume(); + xenbus_resume(); + printk("PV stuff on HVM resume successfully!\n"); + + return 0; +} #endif static int shutdown_process(void *__unused) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 975b7d3a38..c40a900cb3 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -467,6 +467,26 @@ static PyObject *pyxc_linux_build(XcObject *self, return pyxc_error_to_exception(); } +static PyObject *pyxc_get_hvm_param(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + uint32_t dom; + int param; + unsigned long value; + + static char *kwd_list[] = { "domid", "param", NULL }; + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, + &dom, ¶m) ) + return NULL; + + if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 ) + return pyxc_error_to_exception(); + + return Py_BuildValue("i", value); + +} + static PyObject *pyxc_hvm_build(XcObject *self, PyObject *args, PyObject *kwds) @@ -1225,6 +1245,14 @@ static PyMethodDef pyxc_methods[] = { " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "hvm_get_param", + (PyCFunction)pyxc_get_hvm_param, + METH_VARARGS | METH_KEYWORDS, "\n" + "get a parameter of HVM guest OS.\n" + " dom [int]: Identifier of domain to build into.\n" + " param [int]: No. of HVM param.\n" + "Returns: [int] value of the param.\n" }, + { "sched_id_get", (PyCFunction)pyxc_sched_id_get, METH_NOARGS, "\n" diff --git a/tools/python/xen/xend/XendConstants.py b/tools/python/xen/xend/XendConstants.py index e6bc787340..d7469ce5fe 100644 --- a/tools/python/xen/xend/XendConstants.py +++ b/tools/python/xen/xend/XendConstants.py @@ -37,6 +37,13 @@ DOMAIN_SHUTDOWN_REASONS = { REVERSE_DOMAIN_SHUTDOWN_REASONS = \ dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()]) +HVM_PARAM_CALLBACK_IRQ = 0 +HVM_PARAM_STORE_PFN = 1 +HVM_PARAM_STORE_EVTCHN = 2 +HVM_PARAM_PAE_ENABLED = 4 +HVM_PARAM_IOREQ_PFN = 5 +HVM_PARAM_BUFIOREQ_PFN = 6 + restart_modes = [ "restart", "destroy", diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 4b155c3dac..3fdba4d8f2 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -448,11 +448,12 @@ class XendDomainInfo: self._removeVm('xend/previous_restart_time') self.storeDom("control/shutdown", reason) - ## shutdown hypercall for hvm domain desides xenstore write - if self.info.is_hvm(): - for code in DOMAIN_SHUTDOWN_REASONS.keys(): - if DOMAIN_SHUTDOWN_REASONS[code] == reason: - break + ## HVM domain shutdown itself if has PV driver, + ## otherwise remote shutdown it + hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ) + if self.info.is_hvm() and not hvm_pvdrv: + code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason] + log.info("HVM save:remote shutdown dom %d!", self.domid) xc.domain_shutdown(self.domid, code) diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index bb7120b028..c9f6d73109 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -36,6 +36,7 @@ #include <asm/pgtable.h> #include <xen/interface/memory.h> #include <xen/features.h> +#include <xen/gnttab.h> #ifdef __ia64__ #include <asm/xen/xencomm.h> #endif @@ -61,9 +62,11 @@ MODULE_LICENSE("GPL"); unsigned long *phys_to_machine_mapping; EXPORT_SYMBOL(phys_to_machine_mapping); +static unsigned long shared_info_frame; +static uint64_t callback_via; + static int __devinit init_xen_info(void) { - unsigned long shared_info_frame; struct xen_add_to_physmap xatp; extern void *shared_info_area; @@ -219,7 +222,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, int i, ret; long ioaddr, iolen; long mmio_addr, mmio_len; - uint64_t callback_via; i = pci_enable_device(pdev); if (i) @@ -303,6 +305,35 @@ static struct pci_driver platform_driver = { static int pci_device_registered; +void platform_pci_suspend(void) +{ + gnttab_suspend(); +} +EXPORT_SYMBOL_GPL(platform_pci_suspend); + +void platform_pci_resume(void) +{ + struct xen_add_to_physmap xatp; + phys_to_machine_mapping = NULL; + + /* do 2 things for PV driver restore on HVM + * 1: rebuild share info + * 2: set callback irq again + */ + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = XENMAPSPACE_shared_info; + xatp.gpfn = shared_info_frame; + if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) + BUG(); + + if (( set_callback_via(callback_via))) + printk("platform_pci_resume failure!\n"); + + gnttab_resume(); +} +EXPORT_SYMBOL_GPL(platform_pci_resume); + static int __init platform_pci_module_init(void) { int rc; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 2c783bfe7a..8bdd956186 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -556,6 +556,7 @@ static hvm_hypercall_t *hvm_hypercall_table[NR_hypercalls] = { HYPERCALL(multicall), HYPERCALL(xen_version), HYPERCALL(event_channel_op), + HYPERCALL(sched_op), HYPERCALL(hvm_op) }; |