/* * restore_ops function. Sets extra hvm parameters and seeds the grant table. */ static int x86_hvm_stream_complete(struct xc_sr_context *ctx) { xc_interface *xch = ctx->xch; int rc; rc = xc_hvm_param_set(xch, ctx->domid, HVM_PARAM_STORE_EVTCHN, ctx->restore.xenstore_evtchn); if ( rc ) { PERROR("Failed to set HVM_PARAM_STORE_EVTCHN"); return rc; } rc = xc_hvm_param_set(xch, ctx->domid, HVM_PARAM_CONSOLE_EVTCHN, ctx->restore.console_evtchn); if ( rc ) { PERROR("Failed to set HVM_PARAM_CONSOLE_EVTCHN"); return rc; } rc = xc_domain_hvm_setcontext(xch, ctx->domid, ctx->x86_hvm.restore.context, ctx->x86_hvm.restore.contextsz); if ( rc < 0 ) { PERROR("Unable to restore HVM context"); return rc; } rc = xc_dom_gnttab_hvm_seed(xch, ctx->domid, ctx->restore.console_gfn, ctx->restore.xenstore_gfn, ctx->restore.console_domid, ctx->restore.xenstore_domid); if ( rc ) { PERROR("Failed to seed grant table"); return rc; } #ifdef XG_LIBXL_HVM_COMPAT rc = handle_qemu(ctx); if ( rc ) { ERROR("Failed to dump qemu"); return rc; } #endif return rc; }
static int xc_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; }