diff options
author | Paul Durrant <paul.durrant@citrix.com> | 2011-11-25 15:30:41 +0000 |
---|---|---|
committer | Paul Durrant <paul.durrant@citrix.com> | 2011-11-25 15:30:41 +0000 |
commit | 26ddefddf050f692444bde22226f9726556c5a20 (patch) | |
tree | 23ec0efce002770e08d3d6ec6b47de7707c188f6 /tools/libxc/xc_domain_restore.c | |
parent | 5e0f79980e4ace10de74923f604ba523ede0ef90 (diff) | |
download | xen-26ddefddf050f692444bde22226f9726556c5a20.tar.gz xen-26ddefddf050f692444bde22226f9726556c5a20.tar.bz2 xen-26ddefddf050f692444bde22226f9726556c5a20.zip |
Fix save/restore for HVM domains with viridian=1
xc_domain_save/restore currently pay no attention to
HVM_PARAM_VIRIDIAN which results in an HVM domain running a recent
version on Windows (post-Vista) locking up on a domain restore due to
EOIs (done via a viridian MSR write) being silently dropped. This
patch adds an extra save entry for the viridian parameter and also
adds code in the viridian kernel module to catch attempted use of
viridian functionality when the HVM parameter has not been set.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/libxc/xc_domain_restore.c')
-rw-r--r-- | tools/libxc/xc_domain_restore.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 5cf099c92e..882678a9c5 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -675,6 +675,7 @@ typedef struct { uint64_t vm86_tss; uint64_t console_pfn; uint64_t acpi_ioport_location; + uint64_t viridian; } pagebuf_t; static int pagebuf_init(pagebuf_t* buf) @@ -809,6 +810,16 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx, } return pagebuf_get_one(xch, ctx, buf, fd, dom); + case XC_SAVE_ID_HVM_VIRIDIAN: + /* Skip padding 4 bytes then read the acpi ioport location. */ + if ( RDEXACT(fd, &buf->viridian, sizeof(uint32_t)) || + RDEXACT(fd, &buf->viridian, sizeof(uint64_t)) ) + { + PERROR("error read the viridian flag"); + return -1; + } + return pagebuf_get_one(xch, ctx, buf, fd, dom); + default: if ( (count > MAX_BATCH_SIZE) || (count < 0) ) { ERROR("Max batch size exceeded (%d). Giving up.", count); @@ -1440,6 +1451,9 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, fcntl(io_fd, F_SETFL, orig_io_fd_flags | O_NONBLOCK); } + if (pagebuf.viridian != 0) + xc_set_hvm_param(xch, dom, HVM_PARAM_VIRIDIAN, 1); + if (pagebuf.acpi_ioport_location == 1) { DBGPRINTF("Use new firmware ioport from the checkpoint\n"); xc_set_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, 1); |