[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v1 11/13] xen/libxl: allow creating HVM guests without a device model
Intorduce a new device model version (NONE) that can be used to specify that no device model should be used. Propagate this to Xen by creating a new XEN_DOMCTL_CDF_noemu flag that disables some of the emulation done inside of Xen. Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> Cc: Wei Liu <wei.liu2@xxxxxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Cc: Elena Ufimtseva <elena.ufimtseva@xxxxxxxxxx> --- IMHO the XEN_DOMCTL_CDF_noemu flag should be expanded into multiple smaller flags that can be used to disable specific emulated devices, like the vlapic, vioapic, vhpet... Also hvm_mmio_handlers should become domain specific in order to populate it with the usable handlers only. --- tools/libxl/libxl.c | 7 +++---- tools/libxl/libxl_create.c | 16 ++++++++++++++++ tools/libxl/libxl_dom.c | 6 ++++++ tools/libxl/libxl_types.idl | 1 + tools/libxl/xl_cmdimpl.c | 2 ++ xen/arch/x86/domain.c | 2 +- xen/arch/x86/hvm/hvm.c | 14 +++++++++----- xen/arch/x86/hvm/intercept.c | 6 ++++++ xen/common/domctl.c | 5 ++++- xen/include/asm-x86/hvm/domain.h | 1 + xen/include/asm-x86/hvm/hvm.h | 2 +- xen/include/public/domctl.h | 3 +++ xen/include/xen/sched.h | 4 ++++ 13 files changed, 57 insertions(+), 12 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index d86ea62..7c83486 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1587,11 +1587,10 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis) switch (libxl__domain_type(gc, domid)) { case LIBXL_DOMAIN_TYPE_HVM: - if (!libxl_get_stubdom_id(CTX, domid)) - dm_present = 1; - else + if (libxl_get_stubdom_id(CTX, domid)) { dm_present = 0; - break; + break; + } case LIBXL_DOMAIN_TYPE_PV: pid = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/image/device-model-pid", domid)); dm_present = (pid != NULL); diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 86384d2..06cf02c 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -164,6 +164,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, b_info->u.hvm.bios = LIBXL_BIOS_TYPE_ROMBIOS; break; case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: b_info->u.hvm.bios = LIBXL_BIOS_TYPE_SEABIOS; break; + case LIBXL_DEVICE_MODEL_VERSION_NONE: + break; default:return ERROR_INVAL; } @@ -177,6 +179,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, if (b_info->u.hvm.bios == LIBXL_BIOS_TYPE_ROMBIOS) return ERROR_INVAL; break; + case LIBXL_DEVICE_MODEL_VERSION_NONE: + break; default:abort(); } @@ -278,6 +282,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, break; } break; + case LIBXL_DEVICE_MODEL_VERSION_NONE: + b_info->video_memkb = 0; + break; case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: default: switch (b_info->u.hvm.vga.kind) { @@ -535,6 +542,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config, /* convenience aliases */ libxl_domain_create_info *info = &d_config->c_info; + libxl_domain_build_info *b_info = &d_config->b_info; assert(!libxl_domid_valid_guest(*domid)); @@ -549,6 +557,8 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config, flags |= XEN_DOMCTL_CDF_hvm_guest; flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0; flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off; + if (b_info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) + flags |= XEN_DOMCTL_CDF_noemu; } else if (libxl_defbool_val(info->pvh)) { flags |= XEN_DOMCTL_CDF_pvh_guest; if (!libxl_defbool_val(info->hap)) { @@ -1293,6 +1303,12 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev, libxl__device_console_add(gc, domid, &console, state, &device); libxl__device_console_dispose(&console); + if (d_config->b_info.device_model_version == + LIBXL_DEVICE_MODEL_VERSION_NONE) { + domcreate_devmodel_started(egc, &dcs->dmss.dm, 0); + return; + } + libxl_device_vkb_init(&vkb); libxl__device_vkb_add(gc, domid, &vkb); libxl_device_vkb_dispose(&vkb); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 8ee14b9..d948546 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -866,6 +866,12 @@ static int libxl__domain_firmware(libxl__gc *gc, case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: firmware = "hvmloader"; break; + case LIBXL_DEVICE_MODEL_VERSION_NONE: + if (info->kernel == NULL) { + LOG(ERROR, "no device model requested without a kernel"); + return ERROR_FAIL; + } + break; default: LOG(ERROR, "invalid device model version %d", info->device_model_version); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 23f27d4..0b75834 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -83,6 +83,7 @@ libxl_device_model_version = Enumeration("device_model_version", [ (0, "UNKNOWN"), (1, "QEMU_XEN_TRADITIONAL"), # Historical qemu-xen device model (qemu-dm) (2, "QEMU_XEN"), # Upstream based qemu-xen device model + (3, "NONE"), # No device model ]) libxl_console_type = Enumeration("console_type", [ diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index c858068..3d9b3d4 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -2067,6 +2067,8 @@ skip_vfb: } else if (!strcmp(buf, "qemu-xen")) { b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN; + } else if (!strcmp(buf, "none")) { + b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_NONE; } else { fprintf(stderr, "Unknown device_model_version \"%s\" specified\n", buf); diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 0363650..bad0872 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -610,7 +610,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, if ( has_hvm_container_domain(d) ) { - if ( (rc = hvm_domain_initialise(d)) != 0 ) + if ( (rc = hvm_domain_initialise(d, domcr_flags)) != 0 ) { iommu_domain_destroy(d); goto fail; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index d5e5242..7694c9e 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -343,7 +343,7 @@ u64 hvm_get_guest_tsc_adjust(struct vcpu *v) void hvm_migrate_timers(struct vcpu *v) { /* PVH doesn't use rtc and emulated timers, it uses pvclock mechanism. */ - if ( is_pvh_vcpu(v) ) + if ( is_pvh_vcpu(v) || v->domain->arch.hvm_domain.no_emu ) return; rtc_migrate_timers(v); @@ -1423,7 +1423,7 @@ static int hvm_set_dm_domain(struct domain *d, domid_t domid) return rc; } -int hvm_domain_initialise(struct domain *d) +int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags) { int rc; @@ -1485,9 +1485,10 @@ int hvm_domain_initialise(struct domain *d) else d->arch.hvm_domain.io_bitmap = hvm_io_bitmap; - if ( is_pvh_domain(d) ) + if ( is_pvh_domain(d) || domcr_flags & DOMCRF_noemu ) { register_portio_handler(d, 0, 0x10003, handle_pvh_io); + d->arch.hvm_domain.no_emu = TRUE; return 0; } @@ -1531,7 +1532,7 @@ int hvm_domain_initialise(struct domain *d) void hvm_domain_relinquish_resources(struct domain *d) { - if ( is_pvh_domain(d) ) + if ( is_pvh_domain(d) || d->arch.hvm_domain.no_emu ) return; if ( hvm_funcs.nhvm_domain_relinquish_resources ) @@ -1557,7 +1558,7 @@ void hvm_domain_destroy(struct domain *d) hvm_destroy_cacheattr_region_list(d); - if ( is_pvh_domain(d) ) + if ( is_pvh_domain(d) || d->arch.hvm_domain.no_emu ) return; hvm_funcs.domain_destroy(d); @@ -2327,6 +2328,9 @@ int hvm_vcpu_initialise(struct vcpu *v) return 0; } + if ( d->arch.hvm_domain.no_emu ) + return 0; + rc = setup_compat_arg_xlat(v); /* teardown: free_compat_arg_xlat() */ if ( rc != 0 ) goto fail4; diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index d52a48c..b7bc3c7 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -168,6 +168,9 @@ bool_t hvm_mmio_internal(paddr_t gpa) struct vcpu *curr = current; unsigned int i; + if ( curr->domain->arch.hvm_domain.no_emu ) + return 0; + for ( i = 0; i < HVM_MMIO_HANDLER_NR; ++i ) if ( hvm_mmio_handlers[i]->check_handler(curr, gpa) ) return 1; @@ -180,6 +183,9 @@ int hvm_mmio_intercept(ioreq_t *p) struct vcpu *v = current; int i; + if ( v->domain->arch.hvm_domain.no_emu ) + return X86EMUL_UNHANDLEABLE; + for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ ) { hvm_mmio_check_t check_handler = diff --git a/xen/common/domctl.c b/xen/common/domctl.c index ce517a7..1ce7ae0 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -550,7 +550,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) | XEN_DOMCTL_CDF_pvh_guest | XEN_DOMCTL_CDF_hap | XEN_DOMCTL_CDF_s3_integrity - | XEN_DOMCTL_CDF_oos_off)) ) + | XEN_DOMCTL_CDF_oos_off + | XEN_DOMCTL_CDF_noemu)) ) break; dom = op->domain; @@ -592,6 +593,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) domcr_flags |= DOMCRF_s3_integrity; if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_oos_off ) domcr_flags |= DOMCRF_oos_off; + if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_noemu ) + domcr_flags |= DOMCRF_noemu; d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref, &op->u.createdomain.config); diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index ad68fcf..948ced8 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -135,6 +135,7 @@ struct hvm_domain { bool_t mem_sharing_enabled; bool_t qemu_mapcache_invalidate; bool_t is_s3_suspended; + bool_t no_emu; /* * TSC value that VCPUs use to calculate their tsc_offset value. diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 77eeac5..68c987a 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -217,7 +217,7 @@ extern s8 hvm_port80_allowed; extern const struct hvm_function_table *start_svm(void); extern const struct hvm_function_table *start_vmx(void); -int hvm_domain_initialise(struct domain *d); +int hvm_domain_initialise(struct domain *d, unsigned int domcr_flags); void hvm_domain_relinquish_resources(struct domain *d); void hvm_domain_destroy(struct domain *d); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index bc45ea5..4e9d7e7 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -63,6 +63,9 @@ struct xen_domctl_createdomain { /* Is this a PVH guest (as opposed to an HVM or PV guest)? */ #define _XEN_DOMCTL_CDF_pvh_guest 4 #define XEN_DOMCTL_CDF_pvh_guest (1U<<_XEN_DOMCTL_CDF_pvh_guest) + /* Disable emulated devices */ +#define _XEN_DOMCTL_CDF_noemu 5 +#define XEN_DOMCTL_CDF_noemu (1U<<_XEN_DOMCTL_CDF_noemu) uint32_t flags; struct xen_arch_domainconfig config; }; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 604d047..0aaff1e 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -552,6 +552,10 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags, /* DOMCRF_pvh: Create PV domain in HVM container. */ #define _DOMCRF_pvh 5 #define DOMCRF_pvh (1U<<_DOMCRF_pvh) +/* DOMCRF_noemu: Create a HVM domain without emulated devices. */ +/* XXX: Should be split into smaller flags that disable specific devices? */ +#define _DOMCRF_noemu 6 +#define DOMCRF_noemu (1U<<_DOMCRF_noemu) /* * rcu_lock_domain_by_id() is more efficient than get_domain_by_id(). -- 1.9.5 (Apple Git-50.3) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |