📄 xc_ia64_linux_restore.c
字号:
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; switch (format_version) { case XC_IA64_SR_FORMAT_VER_ONE: case XC_IA64_SR_FORMAT_VER_TWO: rc = xc_ia64_pv_recv_context_ver_one_or_two(xc_handle, io_fd, dom, shared_info_frame, p2m_table, store_evtchn, store_mfn, console_evtchn, console_mfn); break; case XC_IA64_SR_FORMAT_VER_THREE: rc = xc_ia64_pv_recv_context_ver_three(xc_handle, io_fd, dom, shared_info_frame, p2m_table, store_evtchn, store_mfn, console_evtchn, console_mfn); break; default: ERROR("Unsupported format version"); rc = -1; break; } return rc;}static intxc_ia64_hvm_recv_context(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; /* cpumap */ uint64_t *vcpumap = NULL; /* HVM: magic frames for ioreqs and xenstore comms */ const int hvm_params[] = { HVM_PARAM_STORE_PFN, HVM_PARAM_IOREQ_PFN, HVM_PARAM_BUFIOREQ_PFN, HVM_PARAM_BUFPIOREQ_PFN, }; const int NR_PARAMS = sizeof(hvm_params) / sizeof(hvm_params[0]); /* ioreq_pfn, bufioreq_pfn, store_pfn */ uint64_t magic_pfns[NR_PARAMS]; /* HVM: a buffer for holding HVM contxt */ uint64_t rec_size = 0; uint8_t *hvm_buf = NULL; /* Read shared info. */ if (xc_ia64_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame, NULL)) goto out; /* vcpu map */ if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) { ERROR("Could not get domain info"); goto out; } if (xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap)) goto out; /* vcpu context */ for (i = 0; i <= info.max_vcpu_id; i++) { /* A copy of the CPU context of the guest. */ vcpu_guest_context_any_t ctxt_any; if (!__test_bit(i, vcpumap)) continue; if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any)) goto out; /* system context of vcpu is recieved as hvm context. */ } /* Set HVM-specific parameters */ if (read_exact(io_fd, magic_pfns, sizeof(magic_pfns))) { ERROR("error reading magic page addresses"); goto out; } /* These comms pages need to be zeroed at the start of day */ for (i = 0; i < NR_PARAMS; i++) { rc = xc_clear_domain_page(xc_handle, dom, magic_pfns[i]); if (rc != 0) { ERROR("error zeroing magic pages: %i", rc); goto out; } rc = xc_set_hvm_param(xc_handle, dom, hvm_params[i], magic_pfns[i]); if (rc != 0) { ERROR("error setting HVM params: %i", rc); goto out; } } rc = xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn); if (rc != 0) { ERROR("error setting HVM params: %i", rc); goto out; } rc = -1; *store_mfn = magic_pfns[0]; /* Read HVM context */ if (read_exact(io_fd, &rec_size, sizeof(rec_size))) { ERROR("error read hvm context size!\n"); goto out; } hvm_buf = malloc(rec_size); if (hvm_buf == NULL) { ERROR("memory alloc for hvm context buffer failed"); errno = ENOMEM; goto out; } if (read_exact(io_fd, hvm_buf, rec_size)) { ERROR("error loading the HVM context"); goto out; } rc = xc_domain_hvm_setcontext(xc_handle, dom, hvm_buf, rec_size); if (rc != 0) { ERROR("error setting the HVM context"); goto out; } rc = 0;out: if (vcpumap != NULL) free(vcpumap); if (hvm_buf != NULL) free(hvm_buf); return rc;}/* * hvm domain requires IO pages allocated when XEN_DOMCTL_arch_setup */static intxc_ia64_hvm_domain_setup(int xc_handle, uint32_t dom){ int rc; xen_pfn_t pfn_list[] = { IO_PAGE_START >> PAGE_SHIFT, BUFFER_IO_PAGE_START >> PAGE_SHIFT, BUFFER_PIO_PAGE_START >> PAGE_SHIFT, }; unsigned long nr_pages = sizeof(pfn_list) / sizeof(pfn_list[0]); rc = xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages, 0, 0, &pfn_list[0]); if (rc != 0) PERROR("Could not allocate IO page or buffer io page.\n"); return rc;}intxc_domain_restore(int xc_handle, int io_fd, uint32_t dom, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn, unsigned int hvm, unsigned int pae){ DECLARE_DOMCTL; int rc = 1; unsigned long ver; /* The new domain's shared-info frame number. */ unsigned long shared_info_frame; struct xen_ia64_p2m_table p2m_table; xc_ia64_p2m_init(&p2m_table); /* For info only */ nr_pfns = 0; if ( read_exact(io_fd, &p2m_size, sizeof(unsigned long)) ) { ERROR("read: p2m_size"); goto out; } DPRINTF("xc_linux_restore start: p2m_size = %lx\n", p2m_size); if (read_exact(io_fd, &ver, sizeof(unsigned long))) { ERROR("Error when reading version"); goto out; } if (ver != XC_IA64_SR_FORMAT_VER_ONE && ver != XC_IA64_SR_FORMAT_VER_TWO && ver != XC_IA64_SR_FORMAT_VER_THREE) { ERROR("version of save doesn't match"); goto out; } if (read_exact(io_fd, &domctl.u.arch_setup, sizeof(domctl.u.arch_setup))) { ERROR("read: domain setup"); goto out; } if (hvm && xc_ia64_hvm_domain_setup(xc_handle, dom) != 0) goto out; /* Build firmware (will be overwritten). */ domctl.domain = (domid_t)dom; domctl.u.arch_setup.flags &= ~XEN_DOMAINSETUP_query; domctl.u.arch_setup.bp = 0; /* indicate domain restore */ domctl.cmd = XEN_DOMCTL_arch_setup; if (xc_domctl(xc_handle, &domctl)) goto out; /* Get the domain's shared-info frame. */ domctl.cmd = XEN_DOMCTL_getdomaininfo; domctl.domain = (domid_t)dom; if (xc_domctl(xc_handle, &domctl) < 0) { ERROR("Could not get information on new domain"); goto out; } shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; if (ver == XC_IA64_SR_FORMAT_VER_THREE || ver == XC_IA64_SR_FORMAT_VER_TWO) { unsigned int memmap_info_num_pages; unsigned long memmap_size; xen_ia64_memmap_info_t *memmap_info; if (read_exact(io_fd, &memmap_info_num_pages, sizeof(memmap_info_num_pages))) { ERROR("read: memmap_info_num_pages"); goto out; } memmap_size = memmap_info_num_pages * PAGE_SIZE; memmap_info = malloc(memmap_size); if (memmap_info == NULL) { ERROR("Could not allocate memory for memmap_info"); goto out; } if (read_exact(io_fd, memmap_info, memmap_size)) { ERROR("read: memmap_info"); goto out; } if (xc_ia64_p2m_map(&p2m_table, xc_handle, dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) { ERROR("p2m mapping"); goto out; } free(memmap_info); } else if (ver == XC_IA64_SR_FORMAT_VER_ONE) { xen_ia64_memmap_info_t *memmap_info; efi_memory_desc_t *memdesc; uint64_t buffer[(sizeof(*memmap_info) + sizeof(*memdesc) + sizeof(uint64_t) - 1) / sizeof(uint64_t)]; memset(buffer, 0, sizeof(buffer)); memmap_info = (xen_ia64_memmap_info_t *)buffer; memdesc = (efi_memory_desc_t*)&memmap_info->memdesc[0]; memmap_info->efi_memmap_size = sizeof(*memmap_info) + sizeof(*memdesc); memmap_info->efi_memdesc_size = sizeof(*memdesc); memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION; memdesc->type = EFI_MEMORY_DESCRIPTOR_VERSION; memdesc->phys_addr = 0; memdesc->virt_addr = 0; memdesc->num_pages = nr_pfns << (PAGE_SHIFT - EFI_PAGE_SHIFT); memdesc->attribute = EFI_MEMORY_WB; if (xc_ia64_p2m_map(&p2m_table, xc_handle, dom, memmap_info, IA64_DOM0VP_EFP_ALLOC_PTE)) { ERROR("p2m mapping"); goto out; } } else { ERROR("unknown version"); goto out; } DPRINTF("Reloading memory pages: 0%%\n"); while (1) { unsigned long gmfn; if (read_exact(io_fd, &gmfn, sizeof(unsigned long))) { ERROR("Error when reading batch size"); goto out; } if (gmfn == INVALID_MFN) break; if (populate_page_if_necessary(xc_handle, dom, gmfn, &p2m_table) < 0) { ERROR("can not populate page 0x%lx", gmfn); goto out; } if (read_page(xc_handle, io_fd, dom, gmfn) < 0) goto out; } DPRINTF("Received all pages\n"); if (xc_ia64_recv_unallocated_list(xc_handle, io_fd, dom, &p2m_table)) goto out; if (!hvm) rc = xc_ia64_pv_recv_context(ver, xc_handle, io_fd, dom, shared_info_frame, &p2m_table, store_evtchn, store_mfn, console_evtchn, console_mfn); else rc = xc_ia64_hvm_recv_context(xc_handle, io_fd, dom, shared_info_frame, &p2m_table, store_evtchn, store_mfn, console_evtchn, console_mfn); if (rc) goto out; /* * Safety checking of saved context: * 1. user_regs is fine, as Xen checks that on context switch. * 2. fpu_ctxt is fine, as it can't hurt Xen. * 3. trap_ctxt needs the code selectors checked. * 4. ldt base must be page-aligned, no more than 8192 ents, ... * 5. gdt already done, and further checking is done by Xen. * 6. check that kernel_ss is safe. * 7. pt_base is already done. * 8. debugregs are checked by Xen. * 9. callback code selectors need checking. */ DPRINTF("Domain ready to be built.\n"); rc = 0; out: xc_ia64_p2m_unmap(&p2m_table); if ((rc != 0) && (dom != 0)) xc_domain_destroy(xc_handle, dom); DPRINTF("Restore exit with rc=%d\n", rc); return rc;}/* * 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 + -