diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c index 9778ea0..d5e686b 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 fc2a7a1..520cb68 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 739d90e..00955e2 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 cf6a63c..d446b99 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<= 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<p2m_size, pfn_type[pfn], (unsigned long)pt_levels<= 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<p2m_size, pfn_type[pfn], (unsigned long)pt_levels<= 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 9d706a9..10679af 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 c386d88..eb6d998 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 ad0f137..2816609 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 1e74509..aef011d 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 5d39982..9c2b67a 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)); \