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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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);
	}
Example #5
0
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;
}
Example #6
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 */
}