aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/core/reboot.c19
-rw-r--r--tools/python/xen/lowlevel/xc/xc.c28
-rw-r--r--tools/python/xen/xend/XendConstants.py7
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py11
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.c35
-rw-r--r--xen/arch/x86/hvm/hvm.c1
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, &param) )
+ 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)
};