aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-01 13:53:14 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-01 13:53:14 +0000
commit60999322eb87ccd91f5208bdd684f1762d664c2e (patch)
tree6b08eb3020ecc7c0fc4828cfff3229154ffaa9b8
parentd47a8e863a56c4e2db18198ebfe21100be086b77 (diff)
downloadxen-60999322eb87ccd91f5208bdd684f1762d664c2e.tar.gz
xen-60999322eb87ccd91f5208bdd684f1762d664c2e.tar.bz2
xen-60999322eb87ccd91f5208bdd684f1762d664c2e.zip
libxc: create a domain_info_context structure to store guest_width and p2m_size for macros.
Macro now refers to guest_width and p2m_size through a dinfo pointer. Signed-off-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
-rw-r--r--tools/libxc/xc_core.c13
-rw-r--r--tools/libxc/xc_core_x86.c30
-rw-r--r--tools/libxc/xc_core_x86.h2
-rw-r--r--tools/libxc/xc_domain_restore.c82
-rw-r--r--tools/libxc/xc_domain_save.c74
-rw-r--r--tools/libxc/xc_offline_page.c10
-rw-r--r--tools/libxc/xc_resume.c21
-rw-r--r--tools/libxc/xg_private.h18
-rw-r--r--tools/libxc/xg_save_restore.h12
9 files changed, 134 insertions, 128 deletions
diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c
index 9778ea0a94..d5e686b7cf 100644
--- a/tools/libxc/xc_core.c
+++ b/tools/libxc/xc_core.c
@@ -427,7 +427,8 @@ xc_domain_dumpcore_via_callback(int xc_handle,
{
xc_dominfo_t info;
shared_info_any_t *live_shinfo = NULL;
- unsigned int guest_width;
+ struct domain_info_context _dinfo = {};
+ struct domain_info_context *dinfo = &_dinfo;
int nr_vcpus = 0;
char *dump_mem, *dump_mem_start = NULL;
@@ -462,7 +463,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
struct xc_core_section_headers *sheaders = NULL;
Elf64_Shdr *shdr;
- if ( get_guest_width(xc_handle, domid, &guest_width) != 0 )
+ if ( get_guest_width(xc_handle, domid, &dinfo->guest_width) != 0 )
{
PERROR("Could not get address size for domain");
return sts;
@@ -547,7 +548,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
goto out;
}
- sts = xc_core_arch_map_p2m(xc_handle, guest_width, &info, live_shinfo,
+ sts = xc_core_arch_map_p2m(xc_handle, dinfo->guest_width, &info, live_shinfo,
&p2m, &p2m_size);
if ( sts != 0 )
goto out;
@@ -745,7 +746,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
goto out;
/* elf note section: xen version */
- sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle, guest_width);
+ sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle, dinfo->guest_width);
if ( sts != 0 )
goto out;
@@ -805,9 +806,9 @@ xc_domain_dumpcore_via_callback(int xc_handle,
if ( !auto_translated_physmap )
{
- if ( guest_width >= sizeof(unsigned long) )
+ if ( dinfo->guest_width >= sizeof(unsigned long) )
{
- if ( guest_width == sizeof(unsigned long) )
+ if ( dinfo->guest_width == sizeof(unsigned long) )
gmfn = p2m[i];
else
gmfn = ((uint64_t *)p2m)[i];
diff --git a/tools/libxc/xc_core_x86.c b/tools/libxc/xc_core_x86.c
index fc2a7a1192..520cb68f58 100644
--- a/tools/libxc/xc_core_x86.c
+++ b/tools/libxc/xc_core_x86.c
@@ -22,7 +22,7 @@
#include "xc_core.h"
#include "xc_e820.h"
-#define GET_FIELD(_p, _f) ((guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))
+#define GET_FIELD(_p, _f) ((dinfo->guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))
#ifndef MAX
#define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b))
@@ -76,7 +76,7 @@ xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
}
static int
-xc_core_arch_map_p2m_rw(int xc_handle, unsigned int guest_width, xc_dominfo_t *info,
+xc_core_arch_map_p2m_rw(int xc_handle, struct domain_info_context *dinfo, xc_dominfo_t *info,
shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
unsigned long *pfnp, int rw)
{
@@ -88,14 +88,14 @@ xc_core_arch_map_p2m_rw(int xc_handle, unsigned int guest_width, xc_dominfo_t *i
xen_pfn_t *p2m_frame_list = NULL;
uint32_t dom = info->domid;
- unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
int ret = -1;
int err;
int i;
- if ( p2m_size < info->nr_pages )
+ dinfo->p2m_size = nr_gpfns(xc_handle, info->domid);
+ if ( dinfo->p2m_size < info->nr_pages )
{
- ERROR("p2m_size < nr_pages -1 (%lx < %lx", p2m_size, info->nr_pages - 1);
+ ERROR("p2m_size < nr_pages -1 (%lx < %lx", dinfo->p2m_size, info->nr_pages - 1);
goto out;
}
@@ -118,13 +118,13 @@ xc_core_arch_map_p2m_rw(int xc_handle, unsigned int guest_width, xc_dominfo_t *i
memcpy(p2m_frame_list_list, live_p2m_frame_list_list, PAGE_SIZE);
/* Canonicalize guest's unsigned long vs ours */
- if ( guest_width > sizeof(unsigned long) )
+ if ( dinfo->guest_width > sizeof(unsigned long) )
for ( i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++ )
- if ( i < PAGE_SIZE/guest_width )
+ if ( i < PAGE_SIZE/dinfo->guest_width )
p2m_frame_list_list[i] = ((uint64_t *)p2m_frame_list_list)[i];
else
p2m_frame_list_list[i] = 0;
- else if ( guest_width < sizeof(unsigned long) )
+ else if ( dinfo->guest_width < sizeof(unsigned long) )
for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- )
p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
@@ -149,10 +149,10 @@ xc_core_arch_map_p2m_rw(int xc_handle, unsigned int guest_width, xc_dominfo_t *i
memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE);
/* Canonicalize guest's unsigned long vs ours */
- if ( guest_width > sizeof(unsigned long) )
+ if ( dinfo->guest_width > sizeof(unsigned long) )
for ( i = 0; i < P2M_FL_ENTRIES; i++ )
p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i];
- else if ( guest_width < sizeof(unsigned long) )
+ else if ( dinfo->guest_width < sizeof(unsigned long) )
for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- )
p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i];
@@ -167,7 +167,7 @@ xc_core_arch_map_p2m_rw(int xc_handle, unsigned int guest_width, xc_dominfo_t *i
goto out;
}
- *pfnp = p2m_size;
+ *pfnp = dinfo->p2m_size;
ret = 0;
@@ -195,7 +195,9 @@ xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, xc_dominfo_t *info
shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
unsigned long *pfnp)
{
- return xc_core_arch_map_p2m_rw(xc_handle, guest_width, info,
+ struct domain_info_context _dinfo = { .guest_width = guest_width };
+ struct domain_info_context *dinfo = &_dinfo;
+ return xc_core_arch_map_p2m_rw(xc_handle, dinfo, info,
live_shinfo, live_p2m, pfnp, 0);
}
@@ -204,7 +206,9 @@ xc_core_arch_map_p2m_writable(int xc_handle, unsigned int guest_width, xc_dominf
shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
unsigned long *pfnp)
{
- return xc_core_arch_map_p2m_rw(xc_handle, guest_width, info,
+ struct domain_info_context _dinfo = { .guest_width = guest_width };
+ struct domain_info_context *dinfo = &_dinfo;
+ return xc_core_arch_map_p2m_rw(xc_handle, dinfo, info,
live_shinfo, live_p2m, pfnp, 1);
}
/*
diff --git a/tools/libxc/xc_core_x86.h b/tools/libxc/xc_core_x86.h
index 739d90ef29..00955e23ea 100644
--- a/tools/libxc/xc_core_x86.h
+++ b/tools/libxc/xc_core_x86.h
@@ -22,7 +22,7 @@
#define XC_CORE_X86_H
#define ELF_ARCH_DATA ELFDATA2LSB
-#define ELF_ARCH_MACHINE (guest_width == 8 ? EM_X86_64 : EM_386)
+#define ELF_ARCH_MACHINE (dinfo->guest_width == 8 ? EM_X86_64 : EM_386)
struct xc_core_arch_context {
/* nothing */
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index cf6a63c25a..d446b999cd 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -41,8 +41,6 @@ static unsigned long hvirt_start;
/* #levels of page tables used by the current guest */
static unsigned int pt_levels;
-/* number of pfns this guest has (i.e. number of entries in the P2M) */
-static unsigned long p2m_size;
/* number of 'in use' pfns in the guest (i.e. #P2M entries with a valid mfn) */
static unsigned long nr_pfns;
@@ -53,12 +51,12 @@ static xen_pfn_t *live_p2m = NULL;
/* A table mapping each PFN to its new MFN. */
static xen_pfn_t *p2m = NULL;
-/* Address size of the guest, in bytes */
-unsigned int guest_width;
-
/* If have enough continuous memory for super page allocation */
static unsigned no_superpage_mem = 0;
+static struct domain_info_context _dinfo;
+static struct domain_info_context *dinfo = &_dinfo;
+
/*
**
**
@@ -427,7 +425,7 @@ alloc_page:
pfn = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
pagetype = region_pfn_type[i] & XEN_DOMCTL_PFINFO_LTAB_MASK;
- if ( pfn > p2m_size )
+ if ( pfn > dinfo->p2m_size )
{
ERROR("pfn out of range");
return 1;
@@ -595,13 +593,13 @@ static xen_pfn_t *load_p2m_frame_list(
/* Pick a guest word-size and PT depth from the ctxt size */
if ( chunk_bytes == sizeof (ctxt.x32) )
{
- guest_width = 4;
+ dinfo->guest_width = 4;
if ( pt_levels > 2 )
pt_levels = 3;
}
else if ( chunk_bytes == sizeof (ctxt.x64) )
{
- guest_width = 8;
+ dinfo->guest_width = 8;
pt_levels = 4;
}
else
@@ -902,7 +900,7 @@ static int buffer_tail_pv(struct tailbuf_pv *buf, int fd,
buf->vcpucount++;
}
// DPRINTF("VCPU count: %d\n", buf->vcpucount);
- vcpulen = ((guest_width == 8) ? sizeof(vcpu_guest_context_x86_64_t)
+ vcpulen = ((dinfo->guest_width == 8) ? sizeof(vcpu_guest_context_x86_64_t)
: sizeof(vcpu_guest_context_x86_32_t)) * buf->vcpucount;
if ( ext_vcpucontext )
vcpulen += 128 * buf->vcpucount;
@@ -1214,7 +1212,7 @@ static int apply_batch(int xc_handle, uint32_t dom, xen_pfn_t* region_mfn,
++curpage;
- if ( pfn > p2m_size )
+ if ( pfn > dinfo->p2m_size )
{
ERROR("pfn out of range");
return -1;
@@ -1264,7 +1262,7 @@ static int apply_batch(int xc_handle, uint32_t dom, xen_pfn_t* region_mfn,
else if ( pagetype != XEN_DOMCTL_PFINFO_NOTAB )
{
ERROR("Bogus page type %lx page table is out of range: "
- "i=%d p2m_size=%lu", pagetype, i, p2m_size);
+ "i=%d p2m_size=%lu", pagetype, i, dinfo->p2m_size);
return -1;
}
@@ -1365,15 +1363,15 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
if ( hvm )
superpages = 1;
- if ( read_exact(io_fd, &p2m_size, sizeof(unsigned long)) )
+ if ( read_exact(io_fd, &dinfo->p2m_size, sizeof(unsigned long)) )
{
ERROR("read: p2m_size");
goto out;
}
- DPRINTF("xc_domain_restore start: p2m_size = %lx\n", p2m_size);
+ DPRINTF("xc_domain_restore start: p2m_size = %lx\n", dinfo->p2m_size);
if ( !get_platform_info(xc_handle, dom,
- &max_mfn, &hvirt_start, &pt_levels, &guest_width) )
+ &max_mfn, &hvirt_start, &pt_levels, &dinfo->guest_width) )
{
ERROR("Unable to get platform info.");
return 1;
@@ -1382,8 +1380,8 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
/* The *current* word size of the guest isn't very interesting; for now
* assume the guest will be the same as we are. We'll fix that later
* if we discover otherwise. */
- guest_width = sizeof(unsigned long);
- pt_levels = (guest_width == 8) ? 4 : (pt_levels == 2) ? 2 : 3;
+ dinfo->guest_width = sizeof(unsigned long);
+ pt_levels = (dinfo->guest_width == 8) ? 4 : (pt_levels == 2) ? 2 : 3;
if ( !hvm )
{
@@ -1397,7 +1395,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
memset(&domctl, 0, sizeof(domctl));
domctl.domain = dom;
domctl.cmd = XEN_DOMCTL_set_address_size;
- domctl.u.address_size.size = guest_width * 8;
+ domctl.u.address_size.size = dinfo->guest_width * 8;
frc = do_domctl(xc_handle, &domctl);
if ( frc != 0 )
{
@@ -1407,8 +1405,8 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
}
/* We want zeroed memory so use calloc rather than malloc. */
- p2m = calloc(p2m_size, sizeof(xen_pfn_t));
- pfn_type = calloc(p2m_size, sizeof(unsigned long));
+ p2m = calloc(dinfo->p2m_size, sizeof(xen_pfn_t));
+ pfn_type = calloc(dinfo->p2m_size, sizeof(unsigned long));
region_mfn = xg_memalign(PAGE_SIZE, ROUNDUP(
MAX_BATCH_SIZE * sizeof(xen_pfn_t), PAGE_SHIFT));
@@ -1441,7 +1439,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
/* Mark all PFNs as invalid; we allocate on demand */
- for ( pfn = 0; pfn < p2m_size; pfn++ )
+ for ( pfn = 0; pfn < dinfo->p2m_size; pfn++ )
p2m[pfn] = INVALID_P2M_ENTRY;
mmu = xc_alloc_mmu_updates(xc_handle, dom);
@@ -1465,7 +1463,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
{
int j, curbatch;
- this_pc = (n * 100) / p2m_size;
+ this_pc = (n * 100) / dinfo->p2m_size;
if ( (this_pc - prev_pc) >= 5 )
{
PPRINTF("\b\b\b\b%3d%%", this_pc);
@@ -1594,7 +1592,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
int j, k;
/* First pass: find all L3TABs current in > 4G mfns and get new mfns */
- for ( i = 0; i < p2m_size; i++ )
+ for ( i = 0; i < dinfo->p2m_size; i++ )
{
if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) ==
XEN_DOMCTL_PFINFO_L3TAB) &&
@@ -1644,7 +1642,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
/* Second pass: find all L1TABs and uncanonicalize them */
j = 0;
- for ( i = 0; i < p2m_size; i++ )
+ for ( i = 0; i < dinfo->p2m_size; i++ )
{
if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) ==
XEN_DOMCTL_PFINFO_L1TAB) )
@@ -1653,7 +1651,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
j++;
}
- if ( (i == (p2m_size-1)) || (j == MAX_BATCH_SIZE) )
+ if ( (i == (dinfo->p2m_size-1)) || (j == MAX_BATCH_SIZE) )
{
region_base = xc_map_foreign_batch(
xc_handle, dom, PROT_READ | PROT_WRITE, region_mfn, j);
@@ -1691,7 +1689,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
* will barf when doing the type-checking.
*/
nr_pins = 0;
- for ( i = 0; i < p2m_size; i++ )
+ for ( i = 0; i < dinfo->p2m_size; i++ )
{
if ( (pfn_type[i] & XEN_DOMCTL_PFINFO_LPINTAB) == 0 )
continue;
@@ -1792,9 +1790,9 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
if ( !(vcpumap & (1ULL << i)) )
continue;
- memcpy(&ctxt, vcpup, ((guest_width == 8) ? sizeof(ctxt.x64)
+ memcpy(&ctxt, vcpup, ((dinfo->guest_width == 8) ? sizeof(ctxt.x64)
: sizeof(ctxt.x32)));
- vcpup += (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);
@@ -1808,7 +1806,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
* resume record.
*/
pfn = GET_FIELD(&ctxt, user_regs.edx);
- if ( (pfn >= p2m_size) ||
+ if ( (pfn >= dinfo->p2m_size) ||
(pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
{
ERROR("Suspend record frame number is bad");
@@ -1818,7 +1816,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
SET_FIELD(&ctxt, user_regs.edx, mfn);
start_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
- SET_FIELD(start_info, nr_pages, p2m_size);
+ SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
SET_FIELD(start_info, shared_info, shared_info_frame<<PAGE_SHIFT);
SET_FIELD(start_info, flags, 0);
*store_mfn = p2m[GET_FIELD(start_info, store_mfn)];
@@ -1839,7 +1837,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
for ( j = 0; (512*j) < GET_FIELD(&ctxt, gdt_ents); j++ )
{
pfn = GET_FIELD(&ctxt, gdt_frames[j]);
- if ( (pfn >= p2m_size) ||
+ if ( (pfn >= dinfo->p2m_size) ||
(pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
{
ERROR("GDT frame number %i (0x%lx) is bad",
@@ -1851,10 +1849,10 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
/* Uncanonicalise the page table base pointer. */
pfn = UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3]));
- if ( pfn >= p2m_size )
+ if ( pfn >= dinfo->p2m_size )
{
ERROR("PT base is bad: pfn=%lu p2m_size=%lu type=%08lx",
- pfn, p2m_size, pfn_type[pfn]);
+ pfn, dinfo->p2m_size, pfn_type[pfn]);
goto out;
}
@@ -1862,7 +1860,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) )
{
ERROR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
- pfn, p2m_size, pfn_type[pfn],
+ pfn, dinfo->p2m_size, pfn_type[pfn],
(unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
goto out;
}
@@ -1872,17 +1870,17 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
if ( (pt_levels == 4) && (ctxt.x64.ctrlreg[1] & 1) )
{
pfn = UNFOLD_CR3(ctxt.x64.ctrlreg[1] & ~1);
- if ( pfn >= p2m_size )
+ if ( pfn >= dinfo->p2m_size )
{
ERROR("User PT base is bad: pfn=%lu p2m_size=%lu",
- pfn, p2m_size);
+ pfn, dinfo->p2m_size);
goto out;
}
if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) !=
((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) )
{
ERROR("User PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx",
- pfn, p2m_size, pfn_type[pfn],
+ pfn, dinfo->p2m_size, pfn_type[pfn],
(unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT);
goto out;
}
@@ -1940,7 +1938,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
for ( i = 0; i < P2M_FL_ENTRIES; i++ )
{
pfn = p2m_frame_list[i];
- if ( (pfn >= p2m_size) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
+ if ( (pfn >= dinfo->p2m_size) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) )
{
ERROR("PFN-to-MFN frame number %i (%#lx) is bad", i, pfn);
goto out;
@@ -1958,14 +1956,14 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
/* If the domain we're restoring has a different word size to ours,
* we need to adjust the live_p2m assignment appropriately */
- if ( guest_width > sizeof (xen_pfn_t) )
- for ( i = p2m_size - 1; i >= 0; i-- )
+ if ( dinfo->guest_width > sizeof (xen_pfn_t) )
+ for ( i = dinfo->p2m_size - 1; i >= 0; i-- )
((int64_t *)live_p2m)[i] = (long)p2m[i];
- else if ( guest_width < sizeof (xen_pfn_t) )
- for ( i = 0; i < p2m_size; i++ )
+ else if ( dinfo->guest_width < sizeof (xen_pfn_t) )
+ for ( i = 0; i < dinfo->p2m_size; i++ )
((uint32_t *)live_p2m)[i] = p2m[i];
else
- memcpy(live_p2m, p2m, p2m_size * sizeof(xen_pfn_t));
+ memcpy(live_p2m, p2m, dinfo->p2m_size * sizeof(xen_pfn_t));
munmap(live_p2m, P2M_FL_ENTRIES * PAGE_SIZE);
DPRINTF("Domain ready to be built.\n");
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 9d706a92d3..10679af9e5 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -39,8 +39,6 @@ static unsigned long hvirt_start;
/* #levels of page tables used by the current guest */
static unsigned int pt_levels;
-/* number of pfns this guest has (i.e. number of entries in the P2M) */
-static unsigned long p2m_size;
/* Live mapping of the table mapping each PFN to its current MFN. */
static xen_pfn_t *live_p2m = NULL;
@@ -49,8 +47,8 @@ static xen_pfn_t *live_p2m = NULL;
static xen_pfn_t *live_m2p = NULL;
static unsigned long m2p_mfn0;
-/* Address size of the guest */
-unsigned int guest_width;
+static struct domain_info_context _dinfo;
+static struct domain_info_context *dinfo = &_dinfo;
/* buffer for output */
struct outbuf {
@@ -66,7 +64,7 @@ struct outbuf {
#define mfn_to_pfn(_mfn) (live_m2p[(_mfn)])
#define pfn_to_mfn(_pfn) \
- ((xen_pfn_t) ((guest_width==8) \
+ ((xen_pfn_t) ((dinfo->guest_width==8) \
? (((uint64_t *)live_p2m)[(_pfn)]) \
: ((((uint32_t *)live_p2m)[(_pfn)]) == 0xffffffffU \
? (-1UL) : (((uint32_t *)live_p2m)[(_pfn)]))))
@@ -77,7 +75,7 @@ struct outbuf {
*/
#define MFN_IS_IN_PSEUDOPHYS_MAP(_mfn) \
(((_mfn) < (max_mfn)) && \
- ((mfn_to_pfn(_mfn) < (p2m_size)) && \
+ ((mfn_to_pfn(_mfn) < (dinfo->p2m_size)) && \
(pfn_to_mfn(mfn_to_pfn(_mfn)) == (_mfn))))
/*
@@ -87,7 +85,7 @@ struct outbuf {
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define BITMAP_SIZE (BITS_TO_LONGS(p2m_size) * sizeof(unsigned long))
+#define BITMAP_SIZE (BITS_TO_LONGS(dinfo->p2m_size) * sizeof(unsigned long))
#define BITMAP_ENTRY(_nr,_bmap) \
((volatile unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
@@ -401,7 +399,7 @@ static int print_stats(int xc_handle, uint32_t domid, int pages_sent,
}
-static int analysis_phase(int xc_handle, uint32_t domid, int p2m_size,
+static int analysis_phase(int xc_handle, uint32_t domid,
unsigned long *arr, int runs)
{
long long start, now;
@@ -415,7 +413,7 @@ static int analysis_phase(int xc_handle, uint32_t domid, int p2m_size,
int i;
xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN,
- arr, p2m_size, NULL, 0, NULL);
+ arr, dinfo->p2m_size, NULL, 0, NULL);
DPRINTF("#Flush\n");
for ( i = 0; i < 40; i++ )
{
@@ -576,7 +574,7 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn,
* compat m2p, so we quietly zap them. This doesn't
* count as a race, so don't report it. */
if ( !(type == XEN_DOMCTL_PFINFO_L2TAB
- && sizeof (unsigned long) > guest_width) )
+ && sizeof (unsigned long) > dinfo->guest_width) )
race = 1; /* inform the caller; fatal if !live */
}
else
@@ -673,7 +671,6 @@ err0:
static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
int io_fd,
uint32_t dom,
- unsigned long p2m_size,
shared_info_any_t *live_shinfo)
{
vcpu_guest_context_any_t ctxt;
@@ -705,13 +702,13 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
memcpy(p2m_frame_list_list, live_p2m_frame_list_list, PAGE_SIZE);
/* Canonicalize guest's unsigned long vs ours */
- if ( guest_width > sizeof(unsigned long) )
+ if ( dinfo->guest_width > sizeof(unsigned long) )
for ( i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++ )
- if ( i < PAGE_SIZE/guest_width )
+ if ( i < PAGE_SIZE/dinfo->guest_width )
p2m_frame_list_list[i] = ((uint64_t *)p2m_frame_list_list)[i];
else
p2m_frame_list_list[i] = 0;
- else if ( guest_width < sizeof(unsigned long) )
+ else if ( dinfo->guest_width < sizeof(unsigned long) )
for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- )
p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
@@ -735,10 +732,10 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE);
/* Canonicalize guest's unsigned long vs ours */
- if ( guest_width > sizeof(unsigned long) )
+ if ( dinfo->guest_width > sizeof(unsigned long) )
for ( i = 0; i < P2M_FL_ENTRIES; i++ )
p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i];
- else if ( guest_width < sizeof(unsigned long) )
+ else if ( dinfo->guest_width < sizeof(unsigned long) )
for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- )
p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i];
@@ -759,7 +756,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
live_p2m = p2m; /* So that translation macros will work */
/* Canonicalise the pfn-to-mfn table frame-number list. */
- for ( i = 0; i < p2m_size; i += FPP )
+ for ( i = 0; i < dinfo->p2m_size; i += FPP )
{
if ( !MFN_IS_IN_PSEUDOPHYS_MAP(p2m_frame_list[i/FPP]) )
{
@@ -794,7 +791,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
*/
{
unsigned long signature = ~0UL;
- uint32_t chunk1_sz = ((guest_width==8)
+ uint32_t chunk1_sz = ((dinfo->guest_width==8)
? sizeof(ctxt.x64)
: sizeof(ctxt.x32));
uint32_t chunk2_sz = 0;
@@ -927,7 +924,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
initialize_mbit_rate();
if ( !get_platform_info(xc_handle, dom,
- &max_mfn, &hvirt_start, &pt_levels, &guest_width) )
+ &max_mfn, &hvirt_start, &pt_levels, &dinfo->guest_width) )
{
ERROR("Unable to get platform info.");
return 1;
@@ -954,7 +951,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
/* Get the size of the P2M table */
- p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;
+ dinfo->p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;
/* Domain is still running at this point */
if ( live )
@@ -1000,7 +997,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
last_iter = !live;
/* pretend we sent all the pages last iteration */
- sent_last_iter = p2m_size;
+ sent_last_iter = dinfo->p2m_size;
/* Setup to_send / to_fix and to_skip bitmaps */
to_send = xg_memalign(PAGE_SIZE, ROUNDUP(BITMAP_SIZE, PAGE_SHIFT));
@@ -1045,7 +1042,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
}
- analysis_phase(xc_handle, dom, p2m_size, to_skip, 0);
+ analysis_phase(xc_handle, dom, to_skip, 0);
pfn_type = xg_memalign(PAGE_SIZE, ROUNDUP(
MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT));
@@ -1073,7 +1070,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
/* Start writing out the saved-domain record. */
- if ( write_exact(io_fd, &p2m_size, sizeof(unsigned long)) )
+ if ( write_exact(io_fd, &dinfo->p2m_size, sizeof(unsigned long)) )
{
PERROR("write: p2m_size");
goto out;
@@ -1084,8 +1081,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
int err = 0;
/* Map the P2M table, and write the list of P2M frames */
- live_p2m = map_and_save_p2m_table(xc_handle, io_fd, dom,
- p2m_size, live_shinfo);
+ live_p2m = map_and_save_p2m_table(xc_handle, io_fd, dom, live_shinfo);
if ( live_p2m == NULL )
{
ERROR("Failed to map/save the p2m frame list");
@@ -1096,7 +1092,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
* Quick belt and braces sanity check.
*/
- for ( i = 0; i < p2m_size; i++ )
+ for ( i = 0; i < dinfo->p2m_size; i++ )
{
mfn = pfn_to_mfn(i);
if( (mfn != INVALID_P2M_ENTRY) && (mfn_to_pfn(mfn) != i) )
@@ -1144,9 +1140,9 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
DPRINTF("Saving memory pages: iter %d 0%%", iter);
- while ( N < p2m_size )
+ while ( N < dinfo->p2m_size )
{
- unsigned int this_pc = (N * 100) / p2m_size;
+ unsigned int this_pc = (N * 100) / dinfo->p2m_size;
if ( (this_pc - prev_pc) >= 5 )
{
@@ -1160,8 +1156,8 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
but this is fast enough for the moment. */
frc = xc_shadow_control(
xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip,
- p2m_size, NULL, 0, NULL);
- if ( frc != p2m_size )
+ dinfo->p2m_size, NULL, 0, NULL);
+ if ( frc != dinfo->p2m_size )
{
ERROR("Error peeking shadow bitmap");
goto out;
@@ -1171,7 +1167,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
/* load pfn_type[] with the mfn of all the pages we're doing in
this batch. */
for ( batch = 0;
- (batch < MAX_BATCH_SIZE) && (N < p2m_size);
+ (batch < MAX_BATCH_SIZE) && (N < dinfo->p2m_size);
N++ )
{
int n = N;
@@ -1433,7 +1429,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
DPRINTF("Total pages sent= %ld (%.2fx)\n",
- total_sent, ((float)total_sent)/p2m_size );
+ total_sent, ((float)total_sent)/dinfo->p2m_size );
DPRINTF("(of which %ld were fixups)\n", needed_to_fix );
}
@@ -1462,7 +1458,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
if ( ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) ||
(iter >= max_iters) ||
(sent_this_iter+skip_this_iter < 50) ||
- (total_sent > p2m_size*max_factor) )
+ (total_sent > dinfo->p2m_size*max_factor) )
{
DPRINTF("Start last iteration\n");
last_iter = 1;
@@ -1493,7 +1489,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
if ( xc_shadow_control(xc_handle, dom,
XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
- p2m_size, NULL, 0, &stats) != p2m_size )
+ dinfo->p2m_size, NULL, 0, &stats) != dinfo->p2m_size )
{
ERROR("Error flushing shadow PT");
goto out;
@@ -1626,7 +1622,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
unsigned int i,j;
unsigned long pfntab[1024];
- for ( i = 0, j = 0; i < p2m_size; i++ )
+ for ( i = 0, j = 0; i < dinfo->p2m_size; i++ )
{
if ( !is_mapped(pfn_to_mfn(i)) )
j++;
@@ -1638,13 +1634,13 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
goto out;
}
- for ( i = 0, j = 0; i < p2m_size; )
+ for ( i = 0, j = 0; i < dinfo->p2m_size; )
{
if ( !is_mapped(pfn_to_mfn(i)) )
pfntab[j++] = i;
i++;
- if ( (j == 1024) || (i == p2m_size) )
+ if ( (j == 1024) || (i == dinfo->p2m_size) )
{
if ( write_exact(io_fd, &pfntab, sizeof(unsigned long)*j) )
{
@@ -1717,7 +1713,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
FOLD_CR3(mfn_to_pfn(UNFOLD_CR3(ctxt.x64.ctrlreg[1])));
}
- if ( write_exact(io_fd, &ctxt, ((guest_width==8)
+ if ( write_exact(io_fd, &ctxt, ((dinfo->guest_width==8)
? sizeof(ctxt.x64)
: sizeof(ctxt.x32))) )
{
@@ -1789,7 +1785,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
if ( xc_shadow_control(xc_handle, dom,
XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
- p2m_size, NULL, 0, &stats) != p2m_size )
+ dinfo->p2m_size, NULL, 0, &stats) != dinfo->p2m_size )
{
ERROR("Error flushing shadow PT");
}
diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
index c386d883e9..eb6d998aa0 100644
--- a/tools/libxc/xc_offline_page.c
+++ b/tools/libxc/xc_offline_page.c
@@ -45,8 +45,8 @@ struct pte_backup
int cur;
};
-/* Global definition for some MACRO */
-int guest_width, p2m_size;
+static struct domain_info_context _dinfo;
+static struct domain_info_context *dinfo = &_dinfo;
int xc_mark_page_online(int xc, unsigned long start,
unsigned long end, uint32_t *status)
@@ -234,7 +234,7 @@ static int init_mem_info(int xc_handle, int domid,
ERROR("Unable to get PT level info.");
return -EFAULT;
}
- guest_width = minfo->guest_width;
+ dinfo->guest_width = minfo->guest_width;
shared_info_frame = info->shared_info_frame;
@@ -255,7 +255,7 @@ static int init_mem_info(int xc_handle, int domid,
munmap(live_shinfo, PAGE_SIZE);
live_shinfo = NULL;
- p2m_size = minfo->p2m_size;
+ dinfo->p2m_size = minfo->p2m_size;
minfo->max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL);
if ( !(minfo->m2p_table =
@@ -286,7 +286,7 @@ static int init_mem_info(int xc_handle, int domid,
for (i = 0; i < minfo->p2m_size ; i+=1024)
{
- int count = ((p2m_size - i ) > 1024 ) ? 1024: (p2m_size - i);
+ int count = ((dinfo->p2m_size - i ) > 1024 ) ? 1024: (dinfo->p2m_size - i);
if ( ( rc = xc_get_pfn_type_batch(xc_handle, domid, count,
minfo->pfn_type + i)) )
{
diff --git a/tools/libxc/xc_resume.c b/tools/libxc/xc_resume.c
index ad0f137b0d..2816609b0d 100644
--- a/tools/libxc/xc_resume.c
+++ b/tools/libxc/xc_resume.c
@@ -26,7 +26,9 @@ static int modify_returncode(int xc_handle, uint32_t domid)
vcpu_guest_context_any_t ctxt;
xc_dominfo_t info;
xen_capabilities_info_t caps;
- int rc, guest_width;
+ struct domain_info_context _dinfo = {};
+ struct domain_info_context *dinfo = &_dinfo;
+ int rc;
if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
{
@@ -48,13 +50,13 @@ static int modify_returncode(int xc_handle, uint32_t domid)
PERROR("Could not get Xen capabilities\n");
return -1;
}
- guest_width = strstr(caps, "x86_64") ? 8 : 4;
+ dinfo->guest_width = strstr(caps, "x86_64") ? 8 : 4;
}
else
{
/* Probe PV guest address width. */
- guest_width = pv_guest_width(xc_handle, domid);
- if ( guest_width < 0 )
+ dinfo->guest_width = pv_guest_width(xc_handle, domid);
+ if ( dinfo->guest_width < 0 )
return -1;
}
@@ -102,8 +104,9 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
xc_dominfo_t info;
int i, rc = -1;
#if defined(__i386__) || defined(__x86_64__)
- int guest_width;
- unsigned long mfn, p2m_size = 0;
+ struct domain_info_context _dinfo = { .p2m_size = 0 };
+ struct domain_info_context *dinfo = &_dinfo;
+ unsigned long mfn;
vcpu_guest_context_any_t ctxt;
start_info_t *start_info;
shared_info_t *shinfo = NULL;
@@ -128,8 +131,8 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
return rc;
}
- guest_width = pv_guest_width(xc_handle, domid);
- if ( guest_width != sizeof(long) )
+ dinfo->guest_width = pv_guest_width(xc_handle, domid);
+ if ( dinfo->guest_width != sizeof(long) )
{
ERROR("Cannot resume uncooperative cross-address-size guests");
return rc;
@@ -144,7 +147,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
goto out;
}
- p2m_size = shinfo->arch.max_pfn;
+ dinfo->p2m_size = shinfo->arch.max_pfn;
p2m_frame_list_list =
xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ,
diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h
index 1e74509b0a..aef011dd2a 100644
--- a/tools/libxc/xg_private.h
+++ b/tools/libxc/xg_private.h
@@ -144,23 +144,27 @@ typedef l4_pgentry_64_t l4_pgentry_t;
/* XXX SMH: following skanky macros rely on variable p2m_size being set */
/* XXX TJD: also, "guest_width" should be the guest's sizeof(unsigned long) */
-/* Number of xen_pfn_t in a page */
+struct domain_info_context {
+ unsigned int guest_width;
+ unsigned long p2m_size;
+};
-#define FPP (PAGE_SIZE/(guest_width))
+/* Number of xen_pfn_t in a page */
+#define FPP (PAGE_SIZE/(dinfo->guest_width))
/* Number of entries in the pfn_to_mfn_frame_list_list */
-#define P2M_FLL_ENTRIES (((p2m_size)+(FPP*FPP)-1)/(FPP*FPP))
+#define P2M_FLL_ENTRIES (((dinfo->p2m_size)+(FPP*FPP)-1)/(FPP*FPP))
/* Number of entries in the pfn_to_mfn_frame_list */
-#define P2M_FL_ENTRIES (((p2m_size)+FPP-1)/FPP)
+#define P2M_FL_ENTRIES (((dinfo->p2m_size)+FPP-1)/FPP)
/* Size in bytes of the pfn_to_mfn_frame_list */
-#define P2M_GUEST_FL_SIZE ((P2M_FL_ENTRIES) * (guest_width))
+#define P2M_GUEST_FL_SIZE ((P2M_FL_ENTRIES) * (dinfo->guest_width))
#define P2M_TOOLS_FL_SIZE ((P2M_FL_ENTRIES) * \
- MAX((sizeof (xen_pfn_t)), guest_width))
+ MAX((sizeof (xen_pfn_t)), dinfo->guest_width))
/* Masks for PTE<->PFN conversions */
-#define MADDR_BITS_X86 ((guest_width == 8) ? 52 : 44)
+#define MADDR_BITS_X86 ((dinfo->guest_width == 8) ? 52 : 44)
#define MFN_MASK_X86 ((1ULL << (MADDR_BITS_X86 - PAGE_SHIFT_X86)) - 1)
#define MADDR_MASK_X86 (MFN_MASK_X86 << PAGE_SHIFT_X86)
diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h
index 5d39982c00..9c2b67a7b8 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -112,34 +112,34 @@ static inline int get_platform_info(int xc_handle, uint32_t dom,
#define is_mapped(pfn_type) (!((pfn_type) & 0x80000000UL))
-#define GET_FIELD(_p, _f) ((guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))
+#define GET_FIELD(_p, _f) ((dinfo->guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))
#define SET_FIELD(_p, _f, _v) do { \
- if (guest_width == 8) \
+ if (dinfo->guest_width == 8) \
(_p)->x64._f = (_v); \
else \
(_p)->x32._f = (_v); \
} while (0)
#define UNFOLD_CR3(_c) \
- ((uint64_t)((guest_width == 8) \
+ ((uint64_t)((dinfo->guest_width == 8) \
? ((_c) >> 12) \
: (((uint32_t)(_c) >> 12) | ((uint32_t)(_c) << 20))))
#define FOLD_CR3(_c) \
- ((uint64_t)((guest_width == 8) \
+ ((uint64_t)((dinfo->guest_width == 8) \
? ((uint64_t)(_c)) << 12 \
: (((uint32_t)(_c) << 12) | ((uint32_t)(_c) >> 20))))
#define MEMCPY_FIELD(_d, _s, _f) do { \
- if (guest_width == 8) \
+ if (dinfo->guest_width == 8) \
memcpy(&(_d)->x64._f, &(_s)->x64._f,sizeof((_d)->x64._f)); \
else \
memcpy(&(_d)->x32._f, &(_s)->x32._f,sizeof((_d)->x32._f)); \
} while (0)
#define MEMSET_ARRAY_FIELD(_p, _f, _v) do { \
- if (guest_width == 8) \
+ if (dinfo->guest_width == 8) \
memset(&(_p)->x64._f[0], (_v), sizeof((_p)->x64._f)); \
else \
memset(&(_p)->x32._f[0], (_v), sizeof((_p)->x32._f)); \