int libxl__arch_domain_map_irq(libxl__gc *gc, uint32_t domid, int irq) { int ret; ret = xc_physdev_map_pirq(CTX->xch, domid, irq, &irq); if (ret) return ret; ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1); return ret; }
static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, int ret) { libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); STATE_AO_GC(dcs->ao); int i; /* convenience aliases */ const uint32_t domid = dcs->guest_domid; libxl_domain_config *const d_config = dcs->guest_config; libxl__domain_build_state *const state = &dcs->build_state; if (ret) { LOG(ERROR, "unable to add disk devices"); goto error_out; } for (i = 0; i < d_config->b_info.num_ioports; i++) { libxl_ioport_range *io = &d_config->b_info.ioports[i]; LOG(DEBUG, "dom%d ioports %"PRIx32"-%"PRIx32, domid, io->first, io->first + io->number - 1); ret = xc_domain_ioport_permission(CTX->xch, domid, io->first, io->number, 1); if (ret < 0) { LOGE(ERROR, "failed give dom%d access to ioports %"PRIx32"-%"PRIx32, domid, io->first, io->first + io->number - 1); ret = ERROR_FAIL; } } for (i = 0; i < d_config->b_info.num_irqs; i++) { int irq = d_config->b_info.irqs[i]; LOG(DEBUG, "dom%d irq %d", domid, irq); ret = irq >= 0 ? xc_physdev_map_pirq(CTX->xch, domid, irq, &irq) : -EOVERFLOW; if (!ret) ret = xc_domain_irq_permission(CTX->xch, domid, irq, 1); if (ret < 0) { LOGE(ERROR, "failed give dom%d access to irq %d", domid, irq); ret = ERROR_FAIL; } } for (i = 0; i < d_config->b_info.num_iomem; i++) { libxl_iomem_range *io = &d_config->b_info.iomem[i]; LOG(DEBUG, "dom%d iomem %"PRIx64"-%"PRIx64, domid, io->start, io->start + io->number - 1); ret = xc_domain_iomem_permission(CTX->xch, domid, io->start, io->number, 1); if (ret < 0) { LOGE(ERROR, "failed give dom%d access to iomem range %"PRIx64"-%"PRIx64, domid, io->start, io->start + io->number - 1); ret = ERROR_FAIL; } } switch (d_config->c_info.type) { case LIBXL_DOMAIN_TYPE_HVM: { libxl__device_console console; libxl_device_vkb vkb; ret = init_console_info(&console, 0); if ( ret ) goto error_out; console.backend_domid = state->console_domid; libxl__device_console_add(gc, domid, &console, state); libxl__device_console_dispose(&console); libxl_device_vkb_init(&vkb); libxl__device_vkb_add(gc, domid, &vkb); libxl_device_vkb_dispose(&vkb); dcs->dmss.dm.guest_domid = domid; if (libxl_defbool_val(d_config->b_info.device_model_stubdomain)) libxl__spawn_stub_dm(egc, &dcs->dmss); else libxl__spawn_local_dm(egc, &dcs->dmss.dm); return; } case LIBXL_DOMAIN_TYPE_PV: { int need_qemu = 0; libxl__device_console console; for (i = 0; i < d_config->num_vfbs; i++) { libxl__device_vfb_add(gc, domid, &d_config->vfbs[i]); libxl__device_vkb_add(gc, domid, &d_config->vkbs[i]); } ret = init_console_info(&console, 0); if ( ret ) goto error_out; need_qemu = libxl__need_xenpv_qemu(gc, 1, &console, d_config->num_vfbs, d_config->vfbs, d_config->num_disks, &d_config->disks[0]); console.backend_domid = state->console_domid; libxl__device_console_add(gc, domid, &console, state); libxl__device_console_dispose(&console); if (need_qemu) { dcs->dmss.dm.guest_domid = domid; libxl__spawn_local_dm(egc, &dcs->dmss.dm); return; } else { assert(!dcs->dmss.dm.guest_domid); domcreate_devmodel_started(egc, &dcs->dmss.dm, 0); return; } } default: ret = ERROR_INVAL; goto error_out; } abort(); /* not reached */ error_out: assert(ret); domcreate_complete(egc, dcs, ret); }