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

📄 xc_ia64_linux_restore.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * xc_ia64_linux_restore.c * * Restore the state of a Linux session. * * Copyright (c) 2003, K A Fraser. *  Rewritten for ia64 by Tristan Gingold <tristan.gingold@bull.net> * * Copyright (c) 2007 Isaku Yamahata <yamahata@valinux.co.jp> *   Use foreign p2m exposure. *   VTi domain support */#include <stdlib.h>#include <unistd.h>#include "xg_private.h"#include "xc_ia64_save_restore.h"#include "xc_ia64.h"#include "xc_efi.h"#include "xen/hvm/params.h"#define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10))/* 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;static intpopulate_page_if_necessary(int xc_handle, uint32_t dom, unsigned long gmfn,                           struct xen_ia64_p2m_table *p2m_table){    if (xc_ia64_p2m_present(p2m_table, gmfn))        return 0;    return xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0, 0, &gmfn);}static intread_page(int xc_handle, int io_fd, uint32_t dom, unsigned long pfn){    void *mem;    mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                               PROT_READ|PROT_WRITE, pfn);    if (mem == NULL) {        ERROR("cannot map page");        return -1;    }    if (read_exact(io_fd, mem, PAGE_SIZE)) {        ERROR("Error when reading from state file (5)");        munmap(mem, PAGE_SIZE);        return -1;    }    munmap(mem, PAGE_SIZE);    return 0;}/* * Get the list of PFNs that are not in the psuedo-phys map. * Although we allocate pages on demand, balloon driver may  * decreased simaltenously. So we have to free the freed * pages here. */static intxc_ia64_recv_unallocated_list(int xc_handle, int io_fd, uint32_t dom,                              struct xen_ia64_p2m_table *p2m_table){    int rc = -1;    unsigned int i;    unsigned int count;    unsigned long *pfntab = NULL;    unsigned int nr_frees;    if (read_exact(io_fd, &count, sizeof(count))) {        ERROR("Error when reading pfn count");        goto out;    }    pfntab = malloc(sizeof(unsigned long) * count);    if (pfntab == NULL) {        ERROR("Out of memory");        goto out;    }    if (read_exact(io_fd, pfntab, sizeof(unsigned long)*count)) {        ERROR("Error when reading pfntab");        goto out;    }    nr_frees = 0;    for (i = 0; i < count; i++) {        if (xc_ia64_p2m_allocated(p2m_table, pfntab[i])) {            pfntab[nr_frees] = pfntab[i];            nr_frees++;        }    }    if (nr_frees > 0) {        if (xc_domain_memory_decrease_reservation(xc_handle, dom, nr_frees,                                                  0, pfntab) < 0) {            PERROR("Could not decrease reservation");            goto out;        } else            DPRINTF("Decreased reservation by %d / %d pages\n",                    nr_frees, count);    }    rc = 0;     out:    if (pfntab != NULL)        free(pfntab);    return rc;}static intxc_ia64_recv_vcpu_context(int xc_handle, int io_fd, uint32_t dom,                          uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any){    vcpu_guest_context_t *ctxt = &ctxt_any->c;    if (read_exact(io_fd, ctxt, sizeof(*ctxt))) {        ERROR("Error when reading ctxt");        return -1;    }    fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]);    /* Initialize and set registers.  */    ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online;    if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt_any) != 0) {        ERROR("Couldn't set vcpu context");        return -1;    }    /* Just a check.  */    ctxt->flags = 0;    if (xc_vcpu_getcontext(xc_handle, dom, vcpu, ctxt_any)) {        ERROR("Could not get vcpu context");        return -1;    }    return 0;}/* Read shared info.  */static intxc_ia64_recv_shared_info(int xc_handle, int io_fd, uint32_t dom,                         unsigned long shared_info_frame,                         unsigned long *start_info_pfn){    unsigned int i;    /* The new domain's shared-info frame. */    shared_info_t *shared_info;        /* Read shared info.  */    shared_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                       PROT_READ|PROT_WRITE,                                       shared_info_frame);    if (shared_info == NULL) {        ERROR("cannot map page");        return -1;    }    if (read_exact(io_fd, shared_info, PAGE_SIZE)) {        ERROR("Error when reading shared_info page");        munmap(shared_info, PAGE_SIZE);        return -1;    }    /* clear any pending events and the selector */    memset(&(shared_info->evtchn_pending[0]), 0,           sizeof (shared_info->evtchn_pending));    for (i = 0; i < MAX_VIRT_CPUS; i++)        shared_info->vcpu_info[i].evtchn_pending_sel = 0;    if (start_info_pfn != NULL)        *start_info_pfn = shared_info->arch.start_info_pfn;    munmap (shared_info, PAGE_SIZE);    return 0;}static intxc_ia64_recv_vcpumap(const xc_dominfo_t *info, int io_fd, uint64_t **vcpumapp){    uint64_t max_virt_cpus;    unsigned long vcpumap_size;    uint64_t *vcpumap = NULL;    *vcpumapp = NULL;        if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {        ERROR("error reading max_virt_cpus");        return -1;    }    if (max_virt_cpus < info->max_vcpu_id) {        ERROR("too large max_virt_cpus %i < %i\n",              max_virt_cpus, info->max_vcpu_id);        return -1;    }    vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) /        sizeof(vcpumap[0]);    vcpumap = malloc(vcpumap_size);    if (vcpumap == NULL) {        ERROR("memory alloc for vcpumap");        return -1;    }    memset(vcpumap, 0, vcpumap_size);    if (read_exact(io_fd, vcpumap, vcpumap_size)) {        ERROR("read vcpumap");        free(vcpumap);        return -1;    }    *vcpumapp = vcpumap;    return 0;}static intxc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, int32_t dom,                             uint32_t vcpu){    int rc = -1;    /* A copy of the CPU context of the guest. */    vcpu_guest_context_any_t ctxt_any;    vcpu_guest_context_t *ctxt = &ctxt_any.c;    if (lock_pages(&ctxt_any, sizeof(ctxt_any))) {        /* needed for build domctl, but might as well do early */        ERROR("Unable to lock_pages ctxt");        return -1;    }    if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, vcpu, &ctxt_any))        goto out;    /* Then get privreg page.  */    if (read_page(xc_handle, io_fd, dom, ctxt->privregs_pfn) < 0) {        ERROR("Could not read vcpu privregs");        goto out;    }    rc = 0; out:    unlock_pages(&ctxt, sizeof(ctxt));    return rc;}static intxc_ia64_pv_recv_shared_info(int xc_handle, int io_fd, int32_t dom,                             unsigned long shared_info_frame,                            struct xen_ia64_p2m_table *p2m_table,                            unsigned int store_evtchn,                            unsigned long *store_mfn,                            unsigned int console_evtchn,                            unsigned long *console_mfn){    unsigned long gmfn;    /* A temporary mapping of the guest's start_info page. */    start_info_t *start_info;        /* Read shared info.  */    if (xc_ia64_recv_shared_info(xc_handle, io_fd, dom,                                 shared_info_frame, &gmfn))        return -1;    /* Uncanonicalise the suspend-record frame number and poke resume rec. */    if (populate_page_if_necessary(xc_handle, dom, gmfn, p2m_table)) {        ERROR("cannot populate page 0x%lx", gmfn);        return -1;    }    start_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,                                      PROT_READ | PROT_WRITE, gmfn);    if (start_info == NULL) {        ERROR("cannot map start_info page");        return -1;    }    start_info->nr_pages = p2m_size;    start_info->shared_info = shared_info_frame << PAGE_SHIFT;    start_info->flags = 0;    *store_mfn = start_info->store_mfn;    start_info->store_evtchn = store_evtchn;    *console_mfn = start_info->console.domU.mfn;    start_info->console.domU.evtchn = console_evtchn;    munmap(start_info, PAGE_SIZE);    return 0;}static intxc_ia64_pv_recv_context_ver_one_or_two(int xc_handle, int io_fd, uint32_t dom,                                       unsigned long shared_info_frame,                                       struct xen_ia64_p2m_table *p2m_table,                                       unsigned int store_evtchn,                                       unsigned long *store_mfn,                                       unsigned int console_evtchn,                                       unsigned long *console_mfn){    int rc;    /* vcpu 0 context */    rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, 0);    if (rc)        return rc;    /* shared_info */    rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame,                                     p2m_table, store_evtchn, store_mfn,                                     console_evtchn, console_mfn);    return rc;}static intxc_ia64_pv_recv_context_ver_three(int xc_handle, int io_fd, uint32_t dom,                                  unsigned long shared_info_frame,                                  struct xen_ia64_p2m_table *p2m_table,                                  unsigned int store_evtchn,                                  unsigned long *store_mfn,                                  unsigned int console_evtchn,                                  unsigned long *console_mfn){    int rc = -1;    xc_dominfo_t info;    unsigned int i;        /* vcpu map */    uint64_t *vcpumap = NULL;        if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) {        ERROR("Could not get domain info");        return -1;    }    rc = xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap);    if (rc != 0)        goto out;    /* vcpu context */    for (i = 0; i <= info.max_vcpu_id; i++) {        if (!__test_bit(i, vcpumap))            continue;        rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, i);        if (rc != 0)            goto out;    }        /* shared_info */    rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame,                                     p2m_table, store_evtchn, store_mfn,                                     console_evtchn, console_mfn); out:    if (vcpumap != NULL)        free(vcpumap);    return rc;}static intxc_ia64_pv_recv_context(unsigned long format_version,

⌨️ 快捷键说明

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