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;
+ ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online;
- if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt) != 0) {
+ if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt_any) != 0) {
ERROR("Couldn't set vcpu context");
return -1;
}
}
static int
-xc_ia64_pv_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)
+xc_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 int
+xc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, int32_t dom,
+ uint32_t vcpu)
{
int rc = -1;
- unsigned long gmfn;
/* A copy of the CPU context of the guest. */
- vcpu_guest_context_t ctxt;
-
- if (lock_pages(&ctxt, sizeof(ctxt))) {
+ vcpu_guest_context_any_t ctxt_any;
+ vcpu_guest_context_t *ctxt = &ctxt_any.c;
+
- /* A temporary mapping of the guest's start_info page. */
- start_info_t *start_info;
-
+ 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))
- if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, 0, &ctxt_any))
++ if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, vcpu, &ctxt_any))
goto out;
/* Then get privreg page. */
if (!__test_bit(i, vcpumap))
continue;
- if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, i, &ctxt))
+ 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.
+ /* system context of vcpu is recieved as hvm context. */
}
/* Set HVM-specific parameters */
}
static int
-xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom,
- shared_info_t *live_shinfo)
+xc_ia64_send_vcpumap(int xc_handle, int io_fd, uint32_t dom,
+ const xc_dominfo_t *info, uint64_t max_virt_cpus,
+ uint64_t **vcpumapp)
{
- /* A copy of the CPU context of the guest. */
- vcpu_guest_context_any_t ctxt_any;
- vcpu_guest_context_t *ctxt = &ctxt_any.c;
- char *mem;
+ int rc = -1;
+ unsigned int i;
+ unsigned long vcpumap_size;
+ uint64_t *vcpumap = NULL;
- if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, 0, &ctxt_any))
- 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");
+ goto out;
+ }
+ memset(vcpumap, 0, vcpumap_size);
- mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ|PROT_WRITE, ctxt->privregs_pfn);
- if (mem == NULL) {
- ERROR("cannot map privreg page");
- return -1;
+ for (i = 0; i <= info->max_vcpu_id; i++) {
+ xc_vcpuinfo_t vinfo;
+ if ((xc_vcpu_getinfo(xc_handle, dom, i, &vinfo) == 0) && vinfo.online)
+ __set_bit(i, vcpumap);
}
- if (write_exact(io_fd, mem, PAGE_SIZE)) {
- ERROR("Error when writing privreg to state file (5)");
- munmap(mem, PAGE_SIZE);
- return -1;
+
+ if (write_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) {
+ ERROR("write max_virt_cpus");
+ goto out;
}
- munmap(mem, PAGE_SIZE);
- if (xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo))
- return -1;
+ if (write_exact(io_fd, vcpumap, vcpumap_size)) {
+ ERROR("write vcpumap");
+ goto out;
+ }
- return 0;
+ rc = 0;
+
+ out:
+ if (rc != 0 && vcpumap != NULL) {
+ free(vcpumap);
+ vcpumap = NULL;
+ }
+ *vcpumapp = vcpumap;
+ return rc;
+}
+
+
+static int
+xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom,
+ const xc_dominfo_t *info, shared_info_t *live_shinfo)
+{
+ int rc = -1;
+ unsigned int i;
+
+ /* vcpu map */
+ uint64_t *vcpumap = NULL;
+ if (xc_ia64_send_vcpumap(xc_handle, io_fd, dom, info, MAX_VIRT_CPUS,
+ &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_t ctxt;
++ vcpu_guest_context_any_t ctxt_any;
++ vcpu_guest_context_t *ctxt = &ctxt_any.c;
++
+ char *mem;
+
+ if (!__test_bit(i, vcpumap))
+ continue;
+
- if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt))
++ if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any))
+ goto out;
+
+ mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
- PROT_READ|PROT_WRITE, ctxt.privregs_pfn);
++ PROT_READ|PROT_WRITE, ctxt->privregs_pfn);
+ if (mem == NULL) {
+ ERROR("cannot map privreg page");
+ goto out;
+ }
+ if (write_exact(io_fd, mem, PAGE_SIZE)) {
+ ERROR("Error when writing privreg to state file (5)");
+ munmap(mem, PAGE_SIZE);
+ goto out;
+ }
+ munmap(mem, PAGE_SIZE);
+ }
+
+ rc = xc_ia64_send_shared_info(xc_handle, io_fd, live_shinfo);
+
+ out:
+ if (vcpumap != NULL)
+ free(vcpumap);
+ return rc;
}
static int
if (!__test_bit(i, vcpumap))
continue;
- if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt))
+ if (xc_ia64_send_vcpu_context(xc_handle, io_fd, dom, i, &ctxt_any))
goto out;
- // system context of vcpu is sent as hvm context.
+ /* system context of vcpu is sent as hvm context. */
}
/* Save magic-page locations. */