From: Marek Marczykowski-Górecki Date: Mon, 26 Nov 2018 19:34:37 +0000 (+0100) Subject: libxl: add support for PVH X-Git-Tag: v4.10.0-rc1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aca7ff5f705e0fd2f52417455922e1d7bfacb3c3;p=thirdparty%2Flibvirt.git libxl: add support for PVH Since this is something between PV and HVM, it makes sense to put the setting in place where domain type is specified. To enable it, use xenpvh. It is also included in capabilities.xml, for every supported HVM guest type - it doesn't seems to be any other requirement (besides new enough Xen). Signed-off-by: Marek Marczykowski-Górecki Reviewed-by: Jim Fehlig --- diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in index 0d9c53def9..86534b2ed2 100644 --- a/docs/formatcaps.html.in +++ b/docs/formatcaps.html.in @@ -74,11 +74,14 @@ is able to run. Possible values are:
xen
-
for XEN
+
for XEN PV
linux
legacy alias for xen
+
xenpvh
+
for XEN PVH
+
hvm
Unmodified operating system
@@ -104,8 +107,8 @@
machine
Machine type, for use in machine attribute of os/type element in domain XML. For example Xen - supports xenfv for HVM or xenpv for - PV.
+ supports xenfv for HVM, xenpv for + PV, or xenpvh for PVH.
domain
The type attribute of this element specifies the type of hypervisor required to run the domain. Use in type diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 5ee727eefa..9b5ffa3842 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -341,12 +341,14 @@ xenpv xenfv + xenpvh xen linux + xenpvh diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4 index 479d9116a4..2cd97cc68f 100644 --- a/m4/virt-driver-libxl.m4 +++ b/m4/virt-driver-libxl.m4 @@ -75,6 +75,9 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_LIBXL], [ ]) fi + dnl Check if Xen has support for PVH + AC_CHECK_DECL(LIBXL_DOMAIN_TYPE_PVH, [AC_DEFINE([HAVE_XEN_PVH], [1], [Define to 1 if Xen has PVH support.])], [], [#include ]) + AC_SUBST([LIBXL_CFLAGS]) AC_SUBST([LIBXL_LIBS]) ]) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 13874837c2..10bf933bcc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -126,7 +126,8 @@ VIR_ENUM_IMPL(virDomainOS, VIR_DOMAIN_OSTYPE_LAST, "xen", "linux", "exe", - "uml") + "uml", + "xenpvh") VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST, "fd", @@ -12932,7 +12933,8 @@ virDomainInputDefParseXML(virDomainXMLOptionPtr xmlopt, bus); goto error; } - } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN) { + } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN || + dom->os.type == VIR_DOMAIN_OSTYPE_XENPVH) { if (def->bus != VIR_DOMAIN_INPUT_BUS_XEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unsupported input bus %s"), @@ -12981,7 +12983,8 @@ virDomainInputDefParseXML(virDomainXMLOptionPtr xmlopt, } else { def->bus = VIR_DOMAIN_INPUT_BUS_USB; } - } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN) { + } else if (dom->os.type == VIR_DOMAIN_OSTYPE_XEN || + dom->os.type == VIR_DOMAIN_OSTYPE_XENPVH) { def->bus = VIR_DOMAIN_INPUT_BUS_XEN; } else { if ((dom->virtType == VIR_DOMAIN_VIRT_VZ || @@ -18770,6 +18773,7 @@ virDomainDefParseBootOptions(virDomainDefPtr def, } if (def->os.type == VIR_DOMAIN_OSTYPE_XEN || + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH || def->os.type == VIR_DOMAIN_OSTYPE_HVM || def->os.type == VIR_DOMAIN_OSTYPE_UML) { xmlNodePtr loader_node; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 467785cd83..cb56b6fbb3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -255,6 +255,7 @@ typedef enum { VIR_DOMAIN_OSTYPE_LINUX, VIR_DOMAIN_OSTYPE_EXE, VIR_DOMAIN_OSTYPE_UML, + VIR_DOMAIN_OSTYPE_XENPVH, VIR_DOMAIN_OSTYPE_LAST } virDomainOSType; diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c index 18596c7c72..58ec13fbe5 100644 --- a/src/libxl/libxl_capabilities.c +++ b/src/libxl/libxl_capabilities.c @@ -57,6 +57,7 @@ struct guest_arch { virArch arch; int bits; int hvm; + int pvh; int pae; int nonpae; int ia64_be; @@ -491,20 +492,44 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps) guest_archs[i].nonpae = nonpae; if (ia64_be) guest_archs[i].ia64_be = ia64_be; + + /* + * Xen 4.10 introduced support for the PVH guest type, which + * requires hardware virtualization support similar to the + * HVM guest type. Add a PVH guest type for each new HVM + * guest type. + */ +#ifdef HAVE_XEN_PVH + if (hvm && i == nr_guest_archs-1) { + /* Ensure we have not exhausted the guest_archs array */ + if (nr_guest_archs >= ARRAY_CARDINALITY(guest_archs)) + continue; + i = nr_guest_archs; + nr_guest_archs++; + + guest_archs[i].arch = arch; + guest_archs[i].hvm = 0; + guest_archs[i].pvh = 1; + } +#endif } } regfree(®ex); for (i = 0; i < nr_guest_archs; ++i) { virCapsGuestPtr guest; - char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"}; + char const *const xen_machines[] = { + guest_archs[i].hvm ? "xenfv" : + (guest_archs[i].pvh ? "xenpvh" : "xenpv")}; virCapsGuestMachinePtr *machines; if ((machines = virCapabilitiesAllocMachines(xen_machines, 1)) == NULL) return -1; if ((guest = virCapabilitiesAddGuest(caps, - guest_archs[i].hvm ? VIR_DOMAIN_OSTYPE_HVM : VIR_DOMAIN_OSTYPE_XEN, + guest_archs[i].hvm ? VIR_DOMAIN_OSTYPE_HVM : + (guest_archs[i].pvh ? VIR_DOMAIN_OSTYPE_XENPVH : + VIR_DOMAIN_OSTYPE_XEN), guest_archs[i].arch, LIBXL_EXECBIN_DIR "/qemu-system-i386", (guest_archs[i].hvm ? @@ -557,7 +582,9 @@ libxlCapsInitGuests(libxl_ctx *ctx, virCapsPtr caps) 1, 0) == NULL) return -1; + } + if (guest_archs[i].hvm || guest_archs[i].pvh) { if (virCapabilitiesAddGuestFeature(guest, "hap", 1, @@ -580,7 +607,7 @@ libxlMakeDomainOSCaps(const char *machine, os->supported = true; - if (STREQ(machine, "xenpv")) + if (STREQ(machine, "xenpv") || STREQ(machine, "xenpvh")) return 0; capsLoader->supported = true; @@ -734,9 +761,12 @@ libxlMakeDomainCapabilities(virDomainCapsPtr domCaps, if (libxlMakeDomainOSCaps(domCaps->machine, os, firmwares, nfirmwares) < 0 || libxlMakeDomainDeviceDiskCaps(disk) < 0 || libxlMakeDomainDeviceGraphicsCaps(graphics) < 0 || - libxlMakeDomainDeviceVideoCaps(video) < 0 || + libxlMakeDomainDeviceVideoCaps(video) < 0) + return -1; + if (STRNEQ(domCaps->machine, "xenpvh") && libxlMakeDomainDeviceHostdevCaps(hostdev) < 0) return -1; + return 0; } diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index f3da0edc72..ea880329ed 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -133,8 +133,19 @@ libxlMakeDomCreateInfo(libxl_ctx *ctx, libxl_domain_create_info_init(c_info); - if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { + if (def->os.type == VIR_DOMAIN_OSTYPE_HVM || + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) { +#ifdef HAVE_XEN_PVH + c_info->type = def->os.type == VIR_DOMAIN_OSTYPE_HVM ? + LIBXL_DOMAIN_TYPE_HVM : LIBXL_DOMAIN_TYPE_PVH; +#else + if (def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("PVH guest os type not supported")); + return -1; + } c_info->type = LIBXL_DOMAIN_TYPE_HVM; +#endif switch ((virTristateSwitch) def->features[VIR_DOMAIN_FEATURE_HAP]) { case VIR_TRISTATE_SWITCH_OFF: libxl_defbool_set(&c_info->hap, false); @@ -276,16 +287,26 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, virDomainClockDef clock = def->clock; libxl_ctx *ctx = cfg->ctx; libxl_domain_build_info *b_info = &d_config->b_info; - int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM; + bool hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM; + bool pvh = def->os.type == VIR_DOMAIN_OSTYPE_XENPVH; size_t i; size_t nusbdevice = 0; libxl_domain_build_info_init(b_info); - if (hvm) + if (hvm) { libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM); - else + } else if (pvh) { +#ifdef HAVE_XEN_PVH + libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PVH); +#else + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("PVH guest os type not supported")); + return -1; +#endif + } else { libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV); + } b_info->max_vcpus = virDomainDefGetVcpusMax(def); if (libxl_cpu_bitmap_alloc(ctx, &b_info->avail_vcpus, b_info->max_vcpus)) @@ -375,7 +396,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, def->mem.cur_balloon = VIR_ROUND_UP(def->mem.cur_balloon, 1024); b_info->max_memkb = virDomainDefGetMemoryInitial(def); b_info->target_memkb = def->mem.cur_balloon; - if (hvm) { + if (hvm || pvh) { if (caps && def->cpu && def->cpu->mode == (VIR_CPU_MODE_HOST_PASSTHROUGH)) { bool hasHwVirt = false; @@ -646,6 +667,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, VIR_DISPOSE_N(b_info->u.hvm.usbdevice_list, nusbdevice); return -1; } +#endif + } else if (pvh) { + if (VIR_STRDUP(b_info->cmdline, def->os.cmdline) < 0) + return -1; + if (VIR_STRDUP(b_info->kernel, def->os.kernel) < 0) + return -1; + if (VIR_STRDUP(b_info->ramdisk, def->os.initrd) < 0) + return -1; +#ifdef LIBXL_HAVE_BUILDINFO_BOOTLOADER + if (VIR_STRDUP(b_info->bootloader, def->os.bootloader) < 0) + return -1; + if (def->os.bootloaderArgs) { + if (!(b_info->bootloader_args = + virStringSplit(def->os.bootloaderArgs, " \t\n", 0))) + return -1; + } #endif } else { /* @@ -1226,11 +1263,12 @@ libxlMakeNic(virDomainDefPtr def, * hvm guest"). */ if (l_nic->model) { - if (def->os.type == VIR_DOMAIN_OSTYPE_XEN && + if ((def->os.type == VIR_DOMAIN_OSTYPE_XEN || + def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) && STRNEQ(l_nic->model, "netfront")) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only model 'netfront' is supported for " - "Xen PV domains")); + "Xen PV(H) domains")); return -1; } if (VIR_STRDUP(x_nic->model, l_nic->model) < 0) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index efd47a3912..5aa68a7c43 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -6398,9 +6398,11 @@ libxlConnectGetDomainCapabilities(virConnectPtr conn, emulatorbin = "/usr/bin/qemu-system-x86_64"; if (machine) { - if (STRNEQ(machine, "xenpv") && STRNEQ(machine, "xenfv")) { + if (STRNEQ(machine, "xenpv") && + STRNEQ(machine, "xenpvh") && + STRNEQ(machine, "xenfv")) { virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Xen only supports 'xenpv' and 'xenfv' machines")); + _("Xen only supports 'xenpv', 'xenpvh' and 'xenfv' machines")); goto cleanup; } } else {