⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xc_ia64_hvm_build.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                          unsigned long dom_memsize, /* in bytes */                          unsigned long *pfns_special_pages,                           unsigned long nr_special_pages,                          unsigned long memmap_info_pfn,                          unsigned long memmap_info_num_pages){    xen_ia64_memmap_info_t* memmap_info;    efi_memory_desc_t *md;    uint64_t nr_mds;        memmap_info = xc_map_foreign_range(xc_handle, dom,                                       PAGE_SIZE * memmap_info_num_pages,                                       PROT_READ | PROT_WRITE,                                       memmap_info_pfn);    if (memmap_info == NULL) {        PERROR("Could not map memmmap_info page.\n");        return -1;    }    memset(memmap_info, 0, PAGE_SIZE * memmap_info_num_pages);    /*     * [0, VGA_IO_START = 0xA0000)     * [VGA_IO_START + VGA_IO_SIZE = 0xC0000, MMIO_START = 3GB)     * [IO_PAGE_START (> 3GB), IO_PAGE_START + IO_PAGE_SIZE)     * [STORE_PAGE_START, STORE_PAGE_START + STORE_PAGE_SIZE)     * [BUFFER_IO_PAGE_START, BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE)     * [BUFFER_PIO_PAGE_START, BUFFER_PIO_PAGE_START + BUFFER_PIO_PAGE_SIZE)     * [memmap_info_pfn << PAGE_SHIFT,     *                          (memmap_info_pfn << PAGE_SHIFT) + PAGE_SIZE)     * [GFW_START=4GB - GFW_SIZE, GFW_START + GFW_SIZE = 4GB)     * [4GB, ...)     */     md = (efi_memory_desc_t*)&memmap_info->memdesc;    xc_ia64_setup_md(md, 0, min(VGA_IO_START, dom_memsize));    md++;    if (dom_memsize > (VGA_IO_START + VGA_IO_SIZE)) {        xc_ia64_setup_md(md, VGA_IO_START + VGA_IO_SIZE,                         min(MMIO_START, dom_memsize));        md++;    }    xc_ia64_setup_md(md, IO_PAGE_START, IO_PAGE_START + IO_PAGE_SIZE);    md++;    xc_ia64_setup_md(md, STORE_PAGE_START, STORE_PAGE_START + STORE_PAGE_SIZE);    md++;    xc_ia64_setup_md(md, BUFFER_IO_PAGE_START,                     BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE);    md++;    xc_ia64_setup_md(md, BUFFER_PIO_PAGE_START,                     BUFFER_PIO_PAGE_START + BUFFER_PIO_PAGE_SIZE);    md++;    xc_ia64_setup_md(md, memmap_info_pfn << PAGE_SHIFT,                     (memmap_info_pfn << PAGE_SHIFT) +                     PAGE_SIZE * memmap_info_num_pages);    md++;    xc_ia64_setup_md(md, GFW_START, GFW_START + GFW_SIZE);    md++;    if (dom_memsize > MMIO_START) {        xc_ia64_setup_md(md, 4 * MEM_G, dom_memsize + (1 * MEM_G));        md++;    }    nr_mds = md - (efi_memory_desc_t*)&memmap_info->memdesc;        assert(nr_mds <=           (PAGE_SIZE * memmap_info_num_pages -            offsetof(typeof(*memmap_info), memdesc))/sizeof(*md));    memmap_info->efi_memmap_size = nr_mds * sizeof(*md);    memmap_info->efi_memdesc_size = sizeof(*md);    memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;    munmap(memmap_info, PAGE_SIZE * memmap_info_num_pages);    return 0;}/* setup shared_info page */static intxc_ia64_setup_shared_info(int xc_handle, uint32_t dom,                          unsigned long shared_info_pfn,                          unsigned long memmap_info_pfn,                          unsigned long memmap_info_num_pages){    shared_info_t *shared_info;    shared_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                       PROT_READ | PROT_WRITE,                                       shared_info_pfn);    if (shared_info == NULL) {        PERROR("Could not map shared_info");        return -1;    }    memset(shared_info, 0, sizeof(*shared_info));    shared_info->arch.memmap_info_num_pages = memmap_info_num_pages;    shared_info->arch.memmap_info_pfn = memmap_info_pfn;    munmap(shared_info, PAGE_SIZE);    return 0;}/* * In this function, we will allocate memory and build P2M/M2P table for VTI * guest.  Frist, a pfn list will be initialized discontiguous, normal memory * begins with 0, GFW memory and other five pages at their place defined in * xen/include/public/arch-ia64.h xc_domain_memory_populate_physmap() called * five times, to set parameter 'extent_order' to different value, this is * convenient to allocate discontiguous memory with different size. */static intsetup_guest(int xc_handle, uint32_t dom, unsigned long memsize,            char *image, unsigned long image_size){    xen_pfn_t *pfn_list;    unsigned long dom_memsize = memsize << 20;    unsigned long nr_pages = memsize << (20 - PAGE_SHIFT);    unsigned long vcpus;    unsigned long nr_special_pages;    unsigned long memmap_info_pfn;    unsigned long memmap_info_num_pages;    unsigned long nvram_start = NVRAM_START, nvram_fd = 0;     int rc;    long i;    const struct hvm_special_page {        int             param;        xen_pfn_t       pfn;    } special_pages[] = {        // pfn-sorted array        { HVM_PARAM_IOREQ_PFN,          IO_PAGE_START         >> PAGE_SHIFT},        { HVM_PARAM_STORE_PFN,          STORE_PAGE_START      >> PAGE_SHIFT},        { HVM_PARAM_BUFIOREQ_PFN,       BUFFER_IO_PAGE_START  >> PAGE_SHIFT},         { HVM_PARAM_BUFPIOREQ_PFN,      BUFFER_PIO_PAGE_START >> PAGE_SHIFT},    };    DECLARE_DOMCTL;    if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) {        PERROR("Guest firmware size is incorrect [%ld]?", image_size);        return -1;    }    pfn_list = malloc(nr_pages * sizeof(xen_pfn_t));    if (pfn_list == NULL) {        PERROR("Could not allocate memory.\n");        return -1;    }    // Allocate pfn for normal memory    for (i = 0; i < dom_memsize >> PAGE_SHIFT; i++)        pfn_list[i] = i;    // If normal memory > 3G. Reserve 3G ~ 4G for MMIO, GFW and others.    for (i = (MMIO_START >> PAGE_SHIFT); i < (dom_memsize >> PAGE_SHIFT); i++)        pfn_list[i] += ((1 * MEM_G) >> PAGE_SHIFT);    // Allocate memory for VTI guest, up to VGA hole from 0xA0000-0xC0000.     rc = xc_domain_memory_populate_physmap(xc_handle, dom,                                           (nr_pages > VGA_START_PAGE) ?                                           VGA_START_PAGE : nr_pages,                                           0, 0, &pfn_list[0]);    // We're not likely to attempt to create a domain with less than    // 640k of memory, but test for completeness    if (rc == 0 && nr_pages > VGA_END_PAGE)        rc = xc_domain_memory_populate_physmap(xc_handle, dom,                                               nr_pages - VGA_END_PAGE,                                               0, 0, &pfn_list[VGA_END_PAGE]);    if (rc != 0) {        PERROR("Could not allocate normal memory for Vti guest.\n");        goto error_out;    }    // We allocate additional pfn for GFW and other five pages, so    // the pfn_list is not contiguous.  Due to this we must support    // old interface xc_ia64_get_pfn_list().    for (i = 0; i < GFW_PAGES; i++)         pfn_list[i] = (GFW_START >> PAGE_SHIFT) + i;    rc = xc_domain_memory_populate_physmap(xc_handle, dom, GFW_PAGES,                                           0, 0, &pfn_list[0]);    if (rc != 0) {        PERROR("Could not allocate GFW memory for Vti guest.\n");        goto error_out;    }    for (i = 0; i < sizeof(special_pages) / sizeof(special_pages[0]); i++)        pfn_list[i] = special_pages[i].pfn;    nr_special_pages = i;    memmap_info_pfn = pfn_list[nr_special_pages - 1] + 1;    memmap_info_num_pages = 1;    pfn_list[nr_special_pages] = memmap_info_pfn;    nr_special_pages++;    rc = xc_domain_memory_populate_physmap(xc_handle, dom, nr_special_pages,                                           0, 0, &pfn_list[0]);    if (rc != 0) {        PERROR("Could not allocate IO page or store page or buffer io page.\n");        goto error_out;    }    domctl.u.arch_setup.flags = XEN_DOMAINSETUP_hvm_guest;    domctl.u.arch_setup.bp = 0;    domctl.u.arch_setup.maxmem = GFW_START + GFW_SIZE;    if (dom_memsize > MMIO_START)        domctl.u.arch_setup.maxmem = dom_memsize + 1 * MEM_G;    domctl.cmd = XEN_DOMCTL_arch_setup;    domctl.domain = (domid_t)dom;    if (xc_domctl(xc_handle, &domctl))        goto error_out;    // Load guest firmware     if (xc_ia64_copy_to_domain_pages(xc_handle, dom, image,                            (GFW_START + GFW_SIZE - image_size) >> PAGE_SHIFT,                            image_size >> PAGE_SHIFT)) {        PERROR("Could not load guest firmware into domain");        goto error_out;    }    domctl.cmd = XEN_DOMCTL_getdomaininfo;    domctl.domain = (domid_t)dom;    if (xc_domctl(xc_handle, &domctl) < 0) {        PERROR("Could not get info on domain");        goto error_out;    }    if (xc_ia64_setup_memmap_info(xc_handle, dom, dom_memsize,                                  pfn_list, nr_special_pages,                                  memmap_info_pfn, memmap_info_num_pages)) {        PERROR("Could not build memmap info\n");        goto error_out;    }    if (xc_ia64_setup_shared_info(xc_handle, dom,                                  domctl.u.getdomaininfo.shared_info_frame,                                  memmap_info_pfn, memmap_info_num_pages)) {        PERROR("Could not setup shared_info\n");        goto error_out;    }    xc_get_hvm_param(xc_handle, dom, HVM_PARAM_NVRAM_FD, &nvram_fd);    if ( !IS_VALID_NVRAM_FD(nvram_fd) )        nvram_start = 0;    else if ( copy_from_nvram_to_GFW(xc_handle, dom, (int)nvram_fd ) == -1 ) {        nvram_start = 0;        close(nvram_fd);    }    vcpus = domctl.u.getdomaininfo.max_vcpu_id + 1;    // Hand-off state passed to guest firmware     if (xc_ia64_build_hob(xc_handle, dom, dom_memsize, vcpus, nvram_start) < 0) {        PERROR("Could not build hob\n");        goto error_out;    }    // zero clear all special pages    for (i = 0; i < sizeof(special_pages) / sizeof(special_pages[0]); i++) {        xc_set_hvm_param(xc_handle, dom,                         special_pages[i].param, special_pages[i].pfn);        if (xc_clear_domain_page(xc_handle, dom, special_pages[i].pfn))            goto error_out;    }    free(pfn_list);    return 0;error_out:    return -1;}intxc_hvm_build(int xc_handle, uint32_t domid, int memsize, const char *image_name){    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;    char *image = NULL;    unsigned long image_size;    unsigned long nr_pages;    nr_pages = xc_get_max_pages(xc_handle, domid);    if (nr_pages < 0) {        PERROR("Could not find total pages for domain");        goto error_out;    }    image = xc_read_image(image_name, &image_size);    if (image == NULL) {        PERROR("Could not read guest firmware image %s", image_name);        goto error_out;    }    image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK;    if (setup_guest(xc_handle, domid, (unsigned long)memsize, image,                    image_size) < 0) {        ERROR("Error constructing guest OS");        goto error_out;    }    free(image);    memset(ctxt, 0, sizeof(*ctxt));    ctxt->regs.ip = 0x80000000ffffffb0UL;    ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();    ctxt->regs.cr.isr = 1UL << 63;    ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_BN;    ctxt->regs.cr.dcr = 0;    ctxt->regs.cr.pta = 15 << 2;    return xc_vcpu_setcontext(xc_handle, domid, 0, ctxt);error_out:    free(image);    return -1;}/* * From asm/pgtable.h */#define _PAGE_P_BIT     0#define _PAGE_A_BIT     5#define _PAGE_D_BIT     6#define _PAGE_P         (1 << _PAGE_P_BIT)      /* page present bit */#define _PAGE_A         (1 << _PAGE_A_BIT)      /* page accessed bit */#define _PAGE_D         (1 << _PAGE_D_BIT)      /* page dirty bit */#define _PAGE_MA_WB     (0x0 <<  2)     /* write back memory attribute */#define _PAGE_MA_UC     (0x4 <<  2)     /* uncacheable memory attribute */#define _PAGE_AR_RW     (2 <<  9)       /* read & write */intxc_ia64_set_os_type(int xc_handle, char *guest_os_type, uint32_t dom){    DECLARE_DOMCTL;    domctl.cmd = XEN_DOMCTL_set_opt_feature;    domctl.domain = (domid_t)dom;    if (!guest_os_type || !strlen(guest_os_type) ||        !strcmp("default", guest_os_type)) {        /* Nothing */        return 0;    } else if (!strcmp("windows", guest_os_type)) {        DPRINTF("Enabling Windows guest OS optimizations\n");        /* Windows identity maps regions 4 & 5 */        domctl.u.set_opt_feature.optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG4;        domctl.u.set_opt_feature.optf.on = XEN_IA64_OPTF_ON;        domctl.u.set_opt_feature.optf.pgprot = (_PAGE_P | _PAGE_A | _PAGE_D |                                                _PAGE_MA_WB | _PAGE_AR_RW);        domctl.u.set_opt_feature.optf.key = 0;        if (xc_domctl(xc_handle, &domctl))            PERROR("Failed to set region 4 identity mapping for Windows "                   "guest OS type.\n");        domctl.u.set_opt_feature.optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG5;        domctl.u.set_opt_feature.optf.on = XEN_IA64_OPTF_ON;        domctl.u.set_opt_feature.optf.pgprot = (_PAGE_P | _PAGE_A | _PAGE_D |                                                _PAGE_MA_UC | _PAGE_AR_RW);        domctl.u.set_opt_feature.optf.key = 0;        if (xc_domctl(xc_handle, &domctl))            PERROR("Failed to set region 5 identity mapping for Windows "                   "guest OS type.\n");        return 0;    } else if (!strcmp("linux", guest_os_type)) {        DPRINTF("Enabling Linux guest OS optimizations\n");        /* Linux identity maps regions 7 */        domctl.u.set_opt_feature.optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7;        domctl.u.set_opt_feature.optf.on = XEN_IA64_OPTF_ON;        domctl.u.set_opt_feature.optf.pgprot = (_PAGE_P | _PAGE_A | _PAGE_D |                                                _PAGE_MA_WB | _PAGE_AR_RW);        domctl.u.set_opt_feature.optf.key = 0;        if (xc_domctl(xc_handle, &domctl))            PERROR("Failed to set region 7 identity mapping for Linux "                   "guest OS type.\n");        return 0;    }    DPRINTF("Unknown guest_os_type (%s), using defaults\n", guest_os_type);    return 0;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -