mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
[HVM] Save/restore: PV-on-HVM driver save/restore support
Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
This commit is contained in:
1 parent
56ada11259
commit
9dd742c907
6 files changed
+93
-8
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||