aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_domain_save.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-11-08 15:44:02 +0000
committerKeir Fraser <keir@xen.org>2010-11-08 15:44:02 +0000
commit47a3fb9662188c9e2f02a8a428e5cc72ce3f451a (patch)
tree00d8ee313ffbbb361ef58cde403255598e5dea56 /tools/libxc/xc_domain_save.c
parent59e3eeb9ef559fa0db5efe69196aa78ee0c5bbea (diff)
downloadxen-47a3fb9662188c9e2f02a8a428e5cc72ce3f451a.tar.gz
xen-47a3fb9662188c9e2f02a8a428e5cc72ce3f451a.tar.bz2
xen-47a3fb9662188c9e2f02a8a428e5cc72ce3f451a.zip
x86: xsave save/restore support for both PV and HVM guests (version 2)
I have tested the patch in the following senarios: 1> Non-xsave platform 2> Xsave-capable platform, guest does not support xsave, xen support xsave 3> Xsave-capable platform, guest does support xsave, xen supports xsave 4> Guest (non-xsave) saved on platform without xsave, restored on a Xsave-capable system. All passed. Signed-off-by: Shan Haitao <haitao.shan@intel.com> Signed-off-by: Han Weidong <weidong.han@intel.com>
Diffstat (limited to 'tools/libxc/xc_domain_save.c')
-rw-r--r--tools/libxc/xc_domain_save.c76
1 files changed, 74 insertions, 2 deletions
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 1f3022cd43..27b38a6239 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -810,14 +810,39 @@ static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch,
? sizeof(ctxt.x64)
: sizeof(ctxt.x32));
uint32_t chunk2_sz = 0;
- uint32_t tot_sz = (chunk1_sz + 8) + (chunk2_sz + 8);
+ uint32_t chunk3_sz = 4;
+ uint32_t xcnt_size = 0;
+ uint32_t tot_sz;
+ DECLARE_DOMCTL;
+
+ domctl.cmd = XEN_DOMCTL_getvcpuextstate;
+ domctl.domain = dom;
+ domctl.u.vcpuextstate.vcpu = 0;
+ domctl.u.vcpuextstate.size = 0;
+ domctl.u.vcpuextstate.xfeature_mask = 0;
+ if ( xc_domctl(xch, &domctl) < 0 )
+ {
+ PERROR("No extended context for VCPU%d", i);
+ goto out;
+ }
+ xcnt_size = domctl.u.vcpuextstate.size + 2 * sizeof(uint64_t);
+
+ tot_sz = (chunk1_sz + 8) + (chunk2_sz + 8);
+ if ( domctl.u.vcpuextstate.xfeature_mask )
+ tot_sz += chunk3_sz + 8;
+
if ( write_exact(io_fd, &signature, sizeof(signature)) ||
write_exact(io_fd, &tot_sz, sizeof(tot_sz)) ||
write_exact(io_fd, "vcpu", 4) ||
write_exact(io_fd, &chunk1_sz, sizeof(chunk1_sz)) ||
write_exact(io_fd, &ctxt, chunk1_sz) ||
write_exact(io_fd, "extv", 4) ||
- write_exact(io_fd, &chunk2_sz, sizeof(chunk2_sz)) )
+ write_exact(io_fd, &chunk2_sz, sizeof(chunk2_sz)) ||
+ (domctl.u.vcpuextstate.xfeature_mask) ?
+ (write_exact(io_fd, "xcnt", 4) ||
+ write_exact(io_fd, &chunk3_sz, sizeof(chunk3_sz)) ||
+ write_exact(io_fd, &xcnt_size, 4)) :
+ 0 )
{
PERROR("write: extended info");
goto out;
@@ -905,6 +930,9 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
/* base of the region in which domain memory is mapped */
unsigned char *region_base = NULL;
+ /* A copy of the CPU eXtended States of the guest. */
+ DECLARE_HYPERCALL_BUFFER(void, buffer);
+
/* bitmap of pages:
- that should be sent this iteration (unless later marked as skip);
- to skip this iteration because already dirty;
@@ -1786,6 +1814,50 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
PERROR("Error when writing to state file (2)");
goto out;
}
+
+ /* Start to fetch CPU eXtended States */
+ /* Get buffer size first */
+ domctl.cmd = XEN_DOMCTL_getvcpuextstate;
+ domctl.domain = dom;
+ domctl.u.vcpuextstate.vcpu = i;
+ domctl.u.vcpuextstate.xfeature_mask = 0;
+ domctl.u.vcpuextstate.size = 0;
+ if ( xc_domctl(xch, &domctl) < 0 )
+ {
+ PERROR("No eXtended states (XSAVE) for VCPU%d", i);
+ goto out;
+ }
+
+ if ( !domctl.u.vcpuextstate.xfeature_mask )
+ continue;
+
+ /* Getting eXtended states data */
+ buffer = xc_hypercall_buffer_alloc(xch, buffer, domctl.u.vcpuextstate.size);
+ if ( !buffer )
+ {
+ PERROR("Insufficient memory for getting eXtended states for"
+ "VCPU%d", i);
+ goto out;
+ }
+ set_xen_guest_handle(domctl.u.vcpuextstate.buffer, buffer);
+ if ( xc_domctl(xch, &domctl) < 0 )
+ {
+ PERROR("No eXtended states (XSAVE) for VCPU%d", i);
+ xc_hypercall_buffer_free(xch, buffer);
+ goto out;
+ }
+
+ if ( wrexact(io_fd, &domctl.u.vcpuextstate.xfeature_mask,
+ sizeof(domctl.u.vcpuextstate.xfeature_mask)) ||
+ wrexact(io_fd, &domctl.u.vcpuextstate.size,
+ sizeof(domctl.u.vcpuextstate.size)) ||
+ wrexact(io_fd, buffer, domctl.u.vcpuextstate.size) )
+ {
+ PERROR("Error when writing to state file VCPU extended state");
+ xc_hypercall_buffer_free(xch, buffer);
+ goto out;
+ }
+ xc_hypercall_buffer_free(xch, buffer);
}
/*