[libvirt] [PATCH v5 2/6] libxl: add support for PVH

Marek Marczykowski-Górecki posted 6 patches 7 years, 2 months ago
[libvirt] [PATCH v5 2/6] libxl: add support for PVH
Posted by Marek Marczykowski-Górecki 7 years, 2 months ago
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 <os><type machine="xenpvh">...</type></os>. 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 <marmarek@invisiblethingslab.com>
---
Changes in v2 proposed by Jim:
 - use new_arch_added var instead of i == nr_guest_archs for clarity
 - improve comment
 - adjust for now required Xen >= 4.6 (remove part for Xen < 4.5)

Changes in v3:
 - limit VIR_DOMAIN_OSTYPE_XEN -> VIR_DOMAIN_OSTYPE_LINUX conversion to
 Xen PV only
 - do not accept VIR_DOMAIN_OSTYPE_LINUX for PVH
 - fix reported capabilities for PVH - remove hostdev passthrough and
 video/graphics
 - use #ifdef LIBXL_DOMAIN_TYPE_PVH instead of hypervisor version to
 check for PVH support
 - compile fix for Xen < 4.9

Changes in v4:
 - revert to "i == nr_guest_archs-1" check
 - let configure check for LIBXL_DOMAIN_TYPE_PVH and use #ifdef
 HAVE_XEN_PVH then
 - fix comment about Xen version

Changes in v5:
 - use 'xenpvh' os type
---
 docs/formatcaps.html.in        |  9 ++++--
 docs/schemas/domaincommon.rng  |  2 +-
 m4/virt-driver-libxl.m4        |  3 ++-
 src/conf/domain_conf.c         | 10 ++++---
 src/conf/domain_conf.h         |  1 +-
 src/libxl/libxl_capabilities.c | 38 +++++++++++++++++++++++---
 src/libxl/libxl_conf.c         | 52 ++++++++++++++++++++++++++++++-----
 src/libxl/libxl_driver.c       |  6 ++--
 8 files changed, 102 insertions(+), 19 deletions(-)

diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in
index 0d9c53d..86534b2 100644
--- a/docs/formatcaps.html.in
+++ b/docs/formatcaps.html.in
@@ -74,11 +74,14 @@
         is able to run. Possible values are:
         <dl>
           <dt><code>xen</code></dt>
-          <dd>for XEN</dd>
+          <dd>for XEN PV</dd>
 
           <dt><code>linux</code></dt>
           <dd>legacy alias for <code>xen</code></dd>
 
+          <dt><code>xenpvh</code></dt>
+          <dd>for XEN PVH</dd>
+
           <dt><code>hvm</code></dt>
           <dd>Unmodified operating system</dd>
 
@@ -104,8 +107,8 @@
             <dt><code>machine</code></dt><dd>Machine type, for use in
               <a href="formatdomain.html#attributeOSTypeMachine">machine</a>
               attribute of os/type element in domain XML. For example Xen
-              supports <code>xenfv</code> for HVM or <code>xenpv</code> for
-              PV.</dd>
+              supports <code>xenfv</code> for HVM, <code>xenpv</code> for
+              PV, or <code>xenpvh</code> for PVH.</dd>
             <dt><code>domain</code></dt><dd>The <code>type</code> attribute of
               this element specifies the type of hypervisor required to run the
               domain. Use in <a href="formatdomain.html#attributeDomainType">type</a>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5ee727e..9b5ffa3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -341,12 +341,14 @@
           <choice>
             <value>xenpv</value>
             <value>xenfv</value>
+            <value>xenpvh</value>
           </choice>
         </attribute>
       </optional>
       <choice>
         <value>xen</value>
         <value>linux</value>
+        <value>xenpvh</value>
       </choice>
     </element>
   </define>
diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4
index 479d911..2cd97cc 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 <libxl.h>])
+
   AC_SUBST([LIBXL_CFLAGS])
   AC_SUBST([LIBXL_LIBS])
 ])
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1387483..10bf933 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 467785c..cb56b6f 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 18596c7..58ec13f 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(&regex);
 
     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 f3da0ed..ea88032 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;
@@ -647,6 +668,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
             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 {
         /*
          * For compatibility with the legacy xen toolstack, default to pygrub
@@ -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 efd47a3..5aa68a7 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 {
-- 
git-series 0.9.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v5 2/6] libxl: add support for PVH
Posted by Jim Fehlig 7 years, 2 months ago
On 11/26/18 12:34 PM, Marek Marczykowski-Górecki wrote:
> 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 <os><type machine="xenpvh">...</type></os>. It is

I replaced '...' with 'xenpvh' in my local branch before pushing.

Regards,
Jim

> 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 <marmarek@invisiblethingslab.com>
> ---
> Changes in v2 proposed by Jim:
>   - use new_arch_added var instead of i == nr_guest_archs for clarity
>   - improve comment
>   - adjust for now required Xen >= 4.6 (remove part for Xen < 4.5)
> 
> Changes in v3:
>   - limit VIR_DOMAIN_OSTYPE_XEN -> VIR_DOMAIN_OSTYPE_LINUX conversion to
>   Xen PV only
>   - do not accept VIR_DOMAIN_OSTYPE_LINUX for PVH
>   - fix reported capabilities for PVH - remove hostdev passthrough and
>   video/graphics
>   - use #ifdef LIBXL_DOMAIN_TYPE_PVH instead of hypervisor version to
>   check for PVH support
>   - compile fix for Xen < 4.9
> 
> Changes in v4:
>   - revert to "i == nr_guest_archs-1" check
>   - let configure check for LIBXL_DOMAIN_TYPE_PVH and use #ifdef
>   HAVE_XEN_PVH then
>   - fix comment about Xen version
> 
> Changes in v5:
>   - use 'xenpvh' os type
> ---
>   docs/formatcaps.html.in        |  9 ++++--
>   docs/schemas/domaincommon.rng  |  2 +-
>   m4/virt-driver-libxl.m4        |  3 ++-
>   src/conf/domain_conf.c         | 10 ++++---
>   src/conf/domain_conf.h         |  1 +-
>   src/libxl/libxl_capabilities.c | 38 +++++++++++++++++++++++---
>   src/libxl/libxl_conf.c         | 52 ++++++++++++++++++++++++++++++-----
>   src/libxl/libxl_driver.c       |  6 ++--
>   8 files changed, 102 insertions(+), 19 deletions(-)
> 
> diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in
> index 0d9c53d..86534b2 100644
> --- a/docs/formatcaps.html.in
> +++ b/docs/formatcaps.html.in
> @@ -74,11 +74,14 @@
>           is able to run. Possible values are:
>           <dl>
>             <dt><code>xen</code></dt>
> -          <dd>for XEN</dd>
> +          <dd>for XEN PV</dd>
>   
>             <dt><code>linux</code></dt>
>             <dd>legacy alias for <code>xen</code></dd>
>   
> +          <dt><code>xenpvh</code></dt>
> +          <dd>for XEN PVH</dd>
> +
>             <dt><code>hvm</code></dt>
>             <dd>Unmodified operating system</dd>
>   
> @@ -104,8 +107,8 @@
>               <dt><code>machine</code></dt><dd>Machine type, for use in
>                 <a href="formatdomain.html#attributeOSTypeMachine">machine</a>
>                 attribute of os/type element in domain XML. For example Xen
> -              supports <code>xenfv</code> for HVM or <code>xenpv</code> for
> -              PV.</dd>
> +              supports <code>xenfv</code> for HVM, <code>xenpv</code> for
> +              PV, or <code>xenpvh</code> for PVH.</dd>
>               <dt><code>domain</code></dt><dd>The <code>type</code> attribute of
>                 this element specifies the type of hypervisor required to run the
>                 domain. Use in <a href="formatdomain.html#attributeDomainType">type</a>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 5ee727e..9b5ffa3 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -341,12 +341,14 @@
>             <choice>
>               <value>xenpv</value>
>               <value>xenfv</value>
> +            <value>xenpvh</value>
>             </choice>
>           </attribute>
>         </optional>
>         <choice>
>           <value>xen</value>
>           <value>linux</value>
> +        <value>xenpvh</value>
>         </choice>
>       </element>
>     </define>
> diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4
> index 479d911..2cd97cc 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 <libxl.h>])
> +
>     AC_SUBST([LIBXL_CFLAGS])
>     AC_SUBST([LIBXL_LIBS])
>   ])
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 1387483..10bf933 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 467785c..cb56b6f 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 18596c7..58ec13f 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(&regex);
>   
>       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 f3da0ed..ea88032 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;
> @@ -647,6 +668,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
>               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 {
>           /*
>            * For compatibility with the legacy xen toolstack, default to pygrub
> @@ -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 efd47a3..5aa68a7 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 {
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list