status_t driver_init_vmi(vmi_instance_t vmi,
                         uint32_t init_flags,
                         vmi_init_data_t *init_data)
{
    status_t rc = VMI_FAILURE;
    if (vmi->driver.init_vmi_ptr)
        rc = vmi->driver.init_vmi_ptr(vmi, init_flags, init_data);
 
    return rc;
}

 
driver.init_vmi_ptr = &xen_init_vmi;
 
 
status_t
xen_init_vmi(
    vmi_instance_t vmi,
    uint32_t init_flags,
    vmi_init_data_t *init_data)
{
    status_t ret = VMI_FAILURE;
    xen_instance_t *xen = xen_get_instance(vmi);
    int rc;
 
    /* setup the info struct */
    rc = xen->libxcw.xc_domain_getinfo(xen->xchandle,
                                       xen->domainid,
                                       1,
                                       &xen->info);
    if (rc != 1) {
        errprint("Failed to get domain info for Xen.\n");
        goto _bail;
    }
 
    /* record the count of VCPUs used by this instance */
    vmi->num_vcpus = xen->info.max_vcpu_id + 1;
 
    /* determine if target is hvm or pv */
    if ( xen->info.hvm ) {
        vmi->vm_type = HVM;
    } else if ( VMI_FAILURE == xen_discover_pv_type(vmi) ) {
        errprint("Failed to determine PV type for Xen.\n");
        goto _bail;
    }
 
    if ( vmi->vm_type == HVM )
        dbprint(VMI_DEBUG_XEN, "**set vm_type HVM\n");
    if ( vmi->vm_type == PV32 )
        dbprint(VMI_DEBUG_XEN, "**set vm_type PV32\n");
    if ( vmi->vm_type == PV64 )
        dbprint(VMI_DEBUG_XEN, "**set vm_type PV64\n");
 
    if ( xen->major_version == 4 && xen->minor_version < 6 )
        xen->max_gpfn = (uint64_t)xen->libxcw.xc_domain_maximum_gpfn(xen->xchandle, xen->domainid);
    else if (xen->libxcw.xc_domain_maximum_gpfn2(xen->xchandle, xen->domainid, (xen_pfn_t*)&xen->max_gpfn)) {
        errprint("Failed to get max gpfn for Xen.\n");
        ret = VMI_FAILURE;
        goto _bail;
    }
 
    if (xen->max_gpfn <= 0) {
        errprint("Failed to get max gpfn for Xen.\n");
        ret = VMI_FAILURE;
        goto _bail;
    }
 
    /* For Xen PV domains, where xc_domain_maximum_gpfn() returns a number
     * more like nr_pages, which is usually less than max_pages or the
     * calculated number of pages based on memkb, just fake it to be sane. */
    if ( vmi->vm_type >= PV32 && (xen->max_gpfn << XC_PAGE_SHIFT) < (xen->info.max_memkb * 1024)) {
        xen->max_gpfn = (xen->info.max_memkb * 1024) >> XC_PAGE_SHIFT;
    }
 
    ret = xen_setup_live_mode(vmi);
 
    if ( VMI_FAILURE == ret )
        goto _bail;
 
#if defined(I386) || defined(X86_64)
    if ( vmi->vm_type == HVM && (vmi->init_flags & VMI_INIT_EVENTS) )
#elif defined(ARM32) || defined(ARM64)
    if ( vmi->init_flags & VMI_INIT_EVENTS )
#endif
    {
        ret = xen_init_events(vmi, init_flags, init_data);
 
        if ( VMI_FAILURE == ret )
            goto _bail;
    }
 
    xen_init_altp2m(vmi);
 
_bail:
    return ret;
}

🌱 Back to Garden