aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_domain_save.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-11-03 08:17:39 +0000
committerKeir Fraser <keir@xen.org>2010-11-03 08:17:39 +0000
commitd0cf8141501afe4e4e257260f093ddd5a760f9af (patch)
tree08bd9986696314c6469b4f5567a5b13f03ba2a2e /tools/libxc/xc_domain_save.c
parent5a4cecd8281530b9165b0186877d5a9db2dcef00 (diff)
downloadxen-d0cf8141501afe4e4e257260f093ddd5a760f9af.tar.gz
xen-d0cf8141501afe4e4e257260f093ddd5a760f9af.tar.bz2
xen-d0cf8141501afe4e4e257260f093ddd5a760f9af.zip
x86: xsave save/restore support for both PV and HVM guests.
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.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 1f3022cd43..26c45a8701 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -810,14 +810,35 @@ 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) + (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)) ||
+ write_exact(io_fd, "xcnt", 4) ||
+ write_exact(io_fd, &chunk3_sz, sizeof(chunk3_sz)) ||
+ write_exact(io_fd, &xcnt_size, 4) )
{
PERROR("write: extended info");
goto out;
@@ -905,6 +926,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 +1810,53 @@ 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;
+ }
+
+ /* 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);
+ goto out;
+ }
+
+ if ( wrexact(io_fd, &domctl.u.vcpuextstate.xfeature_mask,
+ sizeof(domctl.u.vcpuextstate.xfeature_mask)) )
+ {
+ PERROR("Error when writing to state file (2)");
+ goto out;
+ }
+ if ( wrexact(io_fd, &domctl.u.vcpuextstate.size,
+ sizeof(domctl.u.vcpuextstate.size)) )
+ {
+ PERROR("Error when writing to state file (2)");
+ goto out;
+ }
+ if ( wrexact(io_fd, buffer, domctl.u.vcpuextstate.size) )
+ {
+ PERROR("Error when writing to state file (2)");
+ goto out;
+ }
+ xc_hypercall_buffer_free(xch, buffer);
}
/*