int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid) { dom->guest_xc = xc; dom->guest_domid = domid; dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL); if ( xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0 ) { xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities"); return -1; } xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__, dom->xen_version >> 16, dom->xen_version & 0xff, dom->xen_caps); return 0; }
int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch, domid_t domid) { dom->xch = xch; dom->guest_domid = domid; dom->xen_version = xc_version(xch, XENVER_version, NULL); if ( xc_version(xch, XENVER_capabilities, &dom->xen_caps) < 0 ) { xc_dom_panic(xch, XC_INTERNAL_ERROR, "can't get xen capabilities"); return -1; } DOMPRINTF("%s: ver %d.%d, caps %s", __FUNCTION__, dom->xen_version >> 16, dom->xen_version & 0xff, dom->xen_caps); return 0; }
static int modify_returncode(xc_interface *xch, uint32_t domid) { vcpu_guest_context_any_t ctxt; xc_dominfo_t info; xen_capabilities_info_t caps; struct domain_info_context _dinfo = {}; struct domain_info_context *dinfo = &_dinfo; int rc; if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 || info.domid != domid ) { PERROR("Could not get domain info"); return -1; } if ( !info.shutdown || (info.shutdown_reason != SHUTDOWN_suspend) ) { ERROR("Dom %d not suspended: (shutdown %d, reason %d)", domid, info.shutdown, info.shutdown_reason); errno = EINVAL; return -1; } if ( info.hvm ) { /* HVM guests without PV drivers have no return code to modify. */ uint64_t irq = 0; xc_hvm_param_get(xch, domid, HVM_PARAM_CALLBACK_IRQ, &irq); if ( !irq ) return 0; /* HVM guests have host address width. */ if ( xc_version(xch, XENVER_capabilities, &caps) != 0 ) { PERROR("Could not get Xen capabilities"); return -1; } dinfo->guest_width = strstr(caps, "x86_64") ? 8 : 4; } else { /* Probe PV guest address width. */ if ( xc_domain_get_guest_width(xch, domid, &dinfo->guest_width) ) return -1; } if ( (rc = xc_vcpu_getcontext(xch, domid, 0, &ctxt)) != 0 ) return rc; SET_FIELD(&ctxt, user_regs.eax, 1, dinfo->guest_width); if ( (rc = xc_vcpu_setcontext(xch, domid, 0, &ctxt)) != 0 ) return rc; return 0; }
/* Collect Xen version information */ static int xenstat_collect_xen_version(xenstat_node * node) { long vnum = 0; xen_extraversion_t version; /* Collect Xen version information if not already collected */ if (node->handle->xen_version[0] == '\0') { /* Get the Xen version number and extraversion string */ vnum = xc_version(node->handle->xc_handle, XENVER_version, NULL); if (vnum < 0) return 0; if (xc_version(node->handle->xc_handle, XENVER_extraversion, &version) < 0) return 0; /* Format the version information as a string and store it */ snprintf(node->handle->xen_version, VERSION_SIZE, "%ld.%ld%s", ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, version); }
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; struct domain_info_context _dinfo = {}; struct domain_info_context *dinfo = &_dinfo; int rc; if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 ) { PERROR("Could not get domain info"); return -1; } if ( info.hvm ) { /* HVM guests without PV drivers have no return code to modify. */ unsigned long irq = 0; xc_get_hvm_param(xc_handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq); if ( !irq ) return 0; /* HVM guests have host address width. */ if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 ) { PERROR("Could not get Xen capabilities\n"); return -1; } dinfo->guest_width = strstr(caps, "x86_64") ? 8 : 4; } else { /* Probe PV guest address width. */ dinfo->guest_width = pv_guest_width(xc_handle, domid); if ( dinfo->guest_width < 0 ) return -1; } if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 ) return rc; SET_FIELD(&ctxt, user_regs.eax, 1); if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 ) return rc; return 0; }
/* check that this domain uses a paging method that we support */ int get_page_info_xen (xa_instance_t *instance) { int ret = XA_SUCCESS; int i = 0, j = 0; #ifdef ENABLE_XEN #ifdef HAVE_CONTEXT_ANY vcpu_guest_context_any_t ctxt_any; #endif /* HAVE_CONTEXT_ANY */ vcpu_guest_context_t ctxt; #ifdef HAVE_CONTEXT_ANY if ((ret = xc_vcpu_getcontext( instance->m.xen.xc_handle, instance->m.xen.domain_id, 0, /*TODO vcpu, assuming only 1 for now */ &ctxt_any)) != 0){ #else if ((ret = xc_vcpu_getcontext( instance->m.xen.xc_handle, instance->m.xen.domain_id, 0, /*TODO vcpu, assuming only 1 for now */ &ctxt)) != 0){ #endif /* HAVE_CONTEXT_ANY */ fprintf(stderr, "ERROR: failed to get context information.\n"); ret = XA_FAILURE; goto error_exit; } #ifdef HAVE_CONTEXT_ANY ctxt = ctxt_any.c; #endif /* HAVE_CONTEXT_ANY */ /* For details on the registers involved in the x86 paging configuation see the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A: System Programming Guide, Part 1. */ /* PG Flag --> CR0, bit 31 == 1 --> paging enabled */ if (!xa_get_bit(ctxt.ctrlreg[0], 31)){ fprintf(stderr, "ERROR: Paging disabled for this VM, not supported.\n"); ret = XA_FAILURE; goto error_exit; } /* PAE Flag --> CR4, bit 5 == 0 --> pae disabled */ instance->pae = xa_get_bit(ctxt.ctrlreg[4], 5); xa_dbprint("**set instance->pae = %d\n", instance->pae); /* PSE Flag --> CR4, bit 4 == 0 --> pse disabled */ instance->pse = xa_get_bit(ctxt.ctrlreg[4], 4); xa_dbprint("**set instance->pse = %d\n", instance->pse); /* testing to see CR3 value */ instance->cr3 = ctxt.ctrlreg[3] & 0xFFFFF000; xa_dbprint("**set instance->cr3 = 0x%.8x\n", instance->cr3); #endif /* ENABLE_XEN */ error_exit: return ret; } void init_page_offset (xa_instance_t *instance) { if (XA_OS_LINUX == instance->os_type){ instance->page_offset = 0xc0000000; } else if (XA_OS_WINDOWS == instance->os_type){ instance->page_offset = 0x80000000; } else{ instance->page_offset = 0; } xa_dbprint("**set instance->page_offset = 0x%.8x\n", instance->page_offset); /* assume 4k pages for now, update when 4M page is found */ instance->page_shift = 12; instance->page_size = 1 << instance->page_shift; } void init_xen_version (xa_instance_t *instance) { #ifdef ENABLE_XEN #define VERSION_STR_LEN 100 char versionStr[VERSION_STR_LEN]; int versions; int major; int minor; xen_extraversion_t extra; int cmd0 = XENVER_version; int cmd1 = XENVER_extraversion; /* get the major and minor versions */ versions = xc_version(instance->m.xen.xc_handle, cmd0, NULL); major = versions >> 16; minor = versions & ((1 << 16) - 1); xa_dbprint("--major = %d\n", major); xa_dbprint("--minor = %d\n", minor); /* get the extra version */ xc_version(instance->m.xen.xc_handle, cmd1, &extra); xa_dbprint("--extra = %s\n", (char *) extra); /* put everything together for easy comparison testing */ memset(versionStr, 0, VERSION_STR_LEN); sprintf(versionStr, "%d.%d%s", major, minor, (char *)extra); /* see if we recognize this version */ instance->m.xen.xen_version = XA_XENVER_UNKNOWN; if (fnmatch("3.0.4*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_0_4; xa_dbprint("**set instance->m.xen.xen_version = 3.0.4\n"); } else if (fnmatch("3.1.0*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_1_0; xa_dbprint("**set instance->m.xen.xen_version = 3.1.0\n"); } else if (fnmatch("3.1.1*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_1_1; xa_dbprint("**set instance->m.xen.xen_version = 3.1.1\n"); } else if (fnmatch("3.1.2*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_1_2; xa_dbprint("**set instance->m.xen.xen_version = 3.1.2\n"); } else if (fnmatch("3.1.3*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_1_3; xa_dbprint("**set instance->m.xen.xen_version = 3.1.3\n"); } else if (fnmatch("3.1.4*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_1_4; xa_dbprint("**set instance->m.xen.xen_version = 3.1.4\n"); } else if (fnmatch("3.2.0*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_2_0; xa_dbprint("**set instance->m.xen.xen_version = 3.2.0\n"); } else if (fnmatch("3.2.1*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_2_1; xa_dbprint("**set instance->m.xen.xen_version = 3.2.1\n"); } else if (fnmatch("3.2.2*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_2_2; xa_dbprint("**set instance->m.xen.xen_version = 3.2.2\n"); } else if (fnmatch("3.2.3*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_2_3; xa_dbprint("**set instance->m.xen.xen_version = 3.2.3\n"); } else if (fnmatch("3.3.0*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_3_0; xa_dbprint("**set instance->m.xen.xen_version = 3.3.0\n"); } else if (fnmatch("3.3.1*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_3_1; xa_dbprint("**set instance->m.xen.xen_version = 3.3.1\n"); } else if (fnmatch("3.4.0*", versionStr, 0) == 0){ instance->m.xen.xen_version = XA_XENVER_3_4_0; xa_dbprint("**set instance->m.xen.xen_version = 3.4.0\n"); } if (instance->m.xen.xen_version == XA_XENVER_UNKNOWN){ fprintf(stderr, "WARNING: This Xen version not supported by XenAccess "); fprintf(stderr, "(%s).\n", versionStr); } #endif /* ENABLE_XEN */ }