aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_domain_restore.c
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2010-10-22 15:14:51 +0100
committerIan Campbell <ian.campbell@citrix.com>2010-10-22 15:14:51 +0100
commit231c3160913a957cb9aeb693a7966ac3f8ecc780 (patch)
treea12d65e9125a77388c212a7791d38c76ae4ef88c /tools/libxc/xc_domain_restore.c
parent79647c5bc9c62feeed8a1e50e7c73001ae10b23d (diff)
downloadxen-231c3160913a957cb9aeb693a7966ac3f8ecc780.tar.gz
xen-231c3160913a957cb9aeb693a7966ac3f8ecc780.tar.bz2
xen-231c3160913a957cb9aeb693a7966ac3f8ecc780.zip
libxc: convert shadow domctl interfaces and save/restore over to hypercall buffers
Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/libxc/xc_domain_restore.c')
-rw-r--r--tools/libxc/xc_domain_restore.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 316f32dac5..047cd774a7 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -1063,7 +1063,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
shared_info_any_t *new_shared_info;
/* A copy of the CPU context of the guest. */
- vcpu_guest_context_any_t ctxt;
+ DECLARE_HYPERCALL_BUFFER(vcpu_guest_context_any_t, ctxt);
/* A table containing the type of each PFN (/not/ MFN!). */
unsigned long *pfn_type = NULL;
@@ -1113,6 +1113,15 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
if ( superpages )
return 1;
+ ctxt = xc_hypercall_buffer_alloc(xch, ctxt, sizeof(*ctxt));
+
+ if ( ctxt == NULL )
+ {
+ PERROR("Unable to allocate VCPU ctxt buffer");
+ return 1;
+ }
+
+
if ( (orig_io_fd_flags = fcntl(io_fd, F_GETFL, 0)) < 0 ) {
PERROR("unable to read IO FD flags");
goto out;
@@ -1539,26 +1548,20 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
}
}
- if ( lock_pages(xch, &ctxt, sizeof(ctxt)) )
- {
- PERROR("Unable to lock ctxt");
- return 1;
- }
-
vcpup = tailbuf.u.pv.vcpubuf;
for ( i = 0; i <= max_vcpu_id; i++ )
{
if ( !(vcpumap & (1ULL << i)) )
continue;
- memcpy(&ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt.x64)
- : sizeof(ctxt.x32)));
- vcpup += (dinfo->guest_width == 8) ? sizeof(ctxt.x64) : sizeof(ctxt.x32);
+ memcpy(ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt->x64)
+ : sizeof(ctxt->x32)));
+ vcpup += (dinfo->guest_width == 8) ? sizeof(ctxt->x64) : sizeof(ctxt->x32);
DPRINTF("read VCPU %d\n", i);
if ( !new_ctxt_format )
- SET_FIELD(&ctxt, flags, GET_FIELD(&ctxt, flags) | VGCF_online);
+ SET_FIELD(ctxt, flags, GET_FIELD(ctxt, flags) | VGCF_online);
if ( i == 0 )
{
@@ -1566,7 +1569,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
* Uncanonicalise the suspend-record frame number and poke
* resume record.
*/
- pfn = GET_FIELD(&ctxt, user_regs.edx);
+ pfn = GET_FIELD(ctxt, user_regs.edx);
if ( (pfn >= dinfo->p2m_size) ||
(pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
{
@@ -1574,7 +1577,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
goto out;
}
mfn = ctx->p2m[pfn];
- SET_FIELD(&ctxt, user_regs.edx, mfn);
+ SET_FIELD(ctxt, user_regs.edx, mfn);
start_info = xc_map_foreign_range(
xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
@@ -1589,15 +1592,15 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
munmap(start_info, PAGE_SIZE);
}
/* Uncanonicalise each GDT frame number. */
- if ( GET_FIELD(&ctxt, gdt_ents) > 8192 )
+ if ( GET_FIELD(ctxt, gdt_ents) > 8192 )
{
ERROR("GDT entry count out of range");
goto out;
}
- for ( j = 0; (512*j) < GET_FIELD(&ctxt, gdt_ents); j++ )
+ for ( j = 0; (512*j) < GET_FIELD(ctxt, gdt_ents); j++ )
{
- pfn = GET_FIELD(&ctxt, gdt_frames[j]);
+ pfn = GET_FIELD(ctxt, gdt_frames[j]);
if ( (pfn >= dinfo->p2m_size) ||
(pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
{
@@ -1605,10 +1608,10 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
j, (unsigned long)pfn);
goto out;
}
- SET_FIELD(&ctxt, gdt_frames[j], ctx->p2m[pfn]);
+ SET_FIELD(ctxt, gdt_frames[j], ctx->p2m[pfn]);
}
/* Uncanonicalise the page table base pointer. */
- pfn = UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3]));
+ pfn = UNFOLD_CR3(GET_FIELD(ctxt, ctrlreg[3]));
if ( pfn >= dinfo->p2m_size )
{
@@ -1625,12 +1628,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
(unsigned long)ctx->pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
goto out;
}
- SET_FIELD(&ctxt, ctrlreg[3], FOLD_CR3(ctx->p2m[pfn]));
+ SET_FIELD(ctxt, ctrlreg[3], FOLD_CR3(ctx->p2m[pfn]));
/* Guest pagetable (x86/64) stored in otherwise-unused CR1. */
- if ( (ctx->pt_levels == 4) && (ctxt.x64.ctrlreg[1] & 1) )
+ if ( (ctx->pt_levels == 4) && (ctxt->x64.ctrlreg[1] & 1) )
{
- pfn = UNFOLD_CR3(ctxt.x64.ctrlreg[1] & ~1);
+ pfn = UNFOLD_CR3(ctxt->x64.ctrlreg[1] & ~1);
if ( pfn >= dinfo->p2m_size )
{
ERROR("User PT base is bad: pfn=%lu p2m_size=%lu",
@@ -1645,12 +1648,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
(unsigned long)ctx->pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
goto out;
}
- ctxt.x64.ctrlreg[1] = FOLD_CR3(ctx->p2m[pfn]);
+ ctxt->x64.ctrlreg[1] = FOLD_CR3(ctx->p2m[pfn]);
}
domctl.cmd = XEN_DOMCTL_setvcpucontext;
domctl.domain = (domid_t)dom;
domctl.u.vcpucontext.vcpu = i;
- set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt.c);
+ xc_set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
frc = xc_domctl(xch, &domctl);
if ( frc != 0 )
{
@@ -1791,6 +1794,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
out:
if ( (rc != 0) && (dom != 0) )
xc_domain_destroy(xch, dom);
+ xc_hypercall_buffer_free(xch, ctxt);
free(mmu);
free(ctx->p2m);
free(pfn_type);