[libvirt] [PATCH 5/7] conf: Parse and format HPT maxpagesize

Andrea Bolognani abologna at redhat.com
Mon Jun 25 17:11:59 UTC 2018


Signed-off-by: Andrea Bolognani <abologna at redhat.com>
---
 docs/formatdomain.html.in                     | 11 ++++--
 docs/schemas/domaincommon.rng                 | 21 +++++++----
 src/conf/domain_conf.c                        | 36 ++++++++++++++++---
 src/conf/domain_conf.h                        |  1 +
 tests/qemuxml2argvdata/pseries-features.xml   |  4 ++-
 tests/qemuxml2argvtest.c                      |  1 +
 tests/qemuxml2xmloutdata/pseries-features.xml |  4 ++-
 tests/qemuxml2xmltest.c                       |  1 +
 8 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 89672a0486..1cf92cd755 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1922,7 +1922,9 @@
   <pvspinlock state='on'/>
   <gic version='2'/>
   <ioapic driver='qemu'/>
-  <hpt resizing='required'/>
+  <hpt resizing='required'>
+    <maxpagesize unit='MiB'>16</maxpagesize>
+  </hpt>
   <vmcoreinfo state='on'/>
   <smm state='on'>
     <tseg unit='MiB'>48</tseg>
@@ -2149,7 +2151,12 @@
           support; and <code>required</code>, which prevents the guest from
           starting unless both the guest and the host support HPT resizing. If
           the attribute is not defined, the hypervisor default will be used.
-          <span class="since">Since 3.10.0</span> (QEMU/KVM only)
+          <span class="since">Since 3.10.0</span> (QEMU/KVM only).
+
+          <p>The optional <code>maxpagesize</code> subelement can be used to
+          limit the usable page size for HPT guests. Common values are 64 KiB,
+          16 MiB and 16 GiB; when not specified, the hypervisor default will
+          be used. <span class="since">Since 4.5.0</span> (QEMU/KVM only).</p>
       </dd>
       <dt><code>vmcoreinfo</code></dt>
       <dd>Enable QEMU vmcoreinfo device to let the guest kernel save debug
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4a454dddb4..0a661cf1e7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5121,13 +5121,20 @@
 
   <define name="hpt">
     <element name="hpt">
-      <attribute name="resizing">
-        <choice>
-          <value>enabled</value>
-          <value>disabled</value>
-          <value>required</value>
-        </choice>
-      </attribute>
+      <optional>
+        <attribute name="resizing">
+          <choice>
+            <value>enabled</value>
+            <value>disabled</value>
+            <value>required</value>
+          </choice>
+        </attribute>
+      </optional>
+      <optional>
+        <element name="maxpagesize">
+          <ref name='scaledInteger'/>
+        </element>
+      </optional>
     </element>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3f7b0d1bfe..d8cb7f37f3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19807,8 +19807,24 @@ virDomainDefParseXML(xmlDocPtr xml,
                 VIR_FREE(tmp);
             }
 
-            if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE)
+            if (virDomainParseScaledValue("./features/hpt/maxpagesize",
+                                          NULL,
+                                          ctxt,
+                                          &def->hpt_maxpagesize,
+                                          1024,
+                                          ULLONG_MAX,
+                                          false) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               "%s",
+                               _("Unable to parse HPT maxpagesize setting"));
+                goto error;
+            }
+            def->hpt_maxpagesize = VIR_DIV_UP(def->hpt_maxpagesize, 1024);
+
+            if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE ||
+                def->hpt_maxpagesize > 0) {
                 def->features[val] = VIR_TRISTATE_SWITCH_ON;
+            }
             break;
 
         /* coverity[dead_error_begin] */
@@ -21987,15 +22003,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
 
         case VIR_DOMAIN_FEATURE_HPT:
             if (src->features[i] != dst->features[i] ||
-                src->hpt_resizing != dst->hpt_resizing) {
+                src->hpt_resizing != dst->hpt_resizing ||
+                src->hpt_maxpagesize != dst->hpt_maxpagesize) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                _("State of feature '%s' differs: "
-                                 "source: '%s,%s=%s', destination: '%s,%s=%s'"),
+                                 "source: '%s,%s=%s,%s=%llu', destination: '%s,%s=%s,%s=%llu'"),
                                featureName,
                                virTristateSwitchTypeToString(src->features[i]),
                                "resizing", virDomainHPTResizingTypeToString(src->hpt_resizing),
+                               "maxpagesize", src->hpt_maxpagesize,
                                virTristateSwitchTypeToString(dst->features[i]),
-                               "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing));
+                               "resizing", virDomainHPTResizingTypeToString(dst->hpt_resizing),
+                               "maxpagesize", dst->hpt_maxpagesize);
                 return false;
             }
             break;
@@ -27778,15 +27797,22 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                     break;
 
                 virBufferFreeAndReset(&attributeBuf);
+                virBufferFreeAndReset(&childrenBuf);
 
                 if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
                     virBufferAsprintf(&attributeBuf,
                                       " resizing='%s'",
                                       virDomainHPTResizingTypeToString(def->hpt_resizing));
                 }
+                if (def->hpt_maxpagesize > 0) {
+                    virBufferSetChildIndent(&childrenBuf, buf);
+                    virBufferAsprintf(&childrenBuf,
+                                      "<maxpagesize unit='KiB'>%llu</maxpagesize>\n",
+                                      def->hpt_maxpagesize);
+                }
 
                 if (virXMLFormatElement(buf, "hpt",
-                                        &attributeBuf, NULL) < 0) {
+                                        &attributeBuf, &childrenBuf) < 0) {
                     goto error;
                 }
                 break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 39fa2bc35a..0924fc4f3c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2439,6 +2439,7 @@ struct _virDomainDef {
     unsigned int hyperv_spinlocks;
     virGICVersion gic_version;
     virDomainHPTResizing hpt_resizing;
+    unsigned long long hpt_maxpagesize; /* Stored in KiB */
     char *hyperv_vendor_id;
     int apic_eoi;
 
diff --git a/tests/qemuxml2argvdata/pseries-features.xml b/tests/qemuxml2argvdata/pseries-features.xml
index 5ef1a744c8..30cee5b81c 100644
--- a/tests/qemuxml2argvdata/pseries-features.xml
+++ b/tests/qemuxml2argvdata/pseries-features.xml
@@ -7,7 +7,9 @@
     <type arch='ppc64' machine='pseries'>hvm</type>
   </os>
   <features>
-    <hpt resizing='required'/>
+    <hpt resizing='required'>
+      <maxpagesize unit='GiB'>1</maxpagesize>
+    </hpt>
   </features>
   <devices>
     <emulator>/usr/bin/qemu-system-ppc64</emulator>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 582a9de7bb..ac9593acbe 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1849,6 +1849,7 @@ mymain(void)
 
     DO_TEST("pseries-features",
             QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
     DO_TEST_FAILURE("pseries-features",
                     QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE);
diff --git a/tests/qemuxml2xmloutdata/pseries-features.xml b/tests/qemuxml2xmloutdata/pseries-features.xml
index e8ed842fb6..f36705f011 100644
--- a/tests/qemuxml2xmloutdata/pseries-features.xml
+++ b/tests/qemuxml2xmloutdata/pseries-features.xml
@@ -9,7 +9,9 @@
     <boot dev='hd'/>
   </os>
   <features>
-    <hpt resizing='required'/>
+    <hpt resizing='required'>
+      <maxpagesize unit='KiB'>1048576</maxpagesize>
+    </hpt>
   </features>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 4449954ad4..eac6d5b073 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -619,6 +619,7 @@ mymain(void)
 
     DO_TEST("pseries-features",
             QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     DO_TEST("pseries-serial-native",
-- 
2.17.1




More information about the libvir-list mailing list