[libvirt] [PATCH v4 2/4] conf: add support for Direct Mode for Hyper-V Synthetic timers

Vitaly Kuznetsov posted 4 patches 6 weeks ago

[libvirt] [PATCH v4 2/4] conf: add support for Direct Mode for Hyper-V Synthetic timers

Posted by Vitaly Kuznetsov 6 weeks ago
Support 'Direct Mode' for Hyper-V Synthetic Timers in domain config.
Make it 'stimer' enlightenment option as it is not a separate thing.

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 docs/formatdomain.html.in     | 10 +++---
 docs/schemas/domaincommon.rng | 16 ++++++++-
 src/conf/domain_conf.c        | 62 ++++++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h        |  1 +
 src/cpu/cpu_x86.c             |  3 ++
 src/cpu/cpu_x86_data.h        |  2 ++
 6 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f5c882141a..de577e5755 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2033,7 +2033,9 @@
     &lt;vpindex state='on'/&gt;
     &lt;runtime state='on'/&gt;
     &lt;synic state='on'/&gt;
-    &lt;stimer state='on'/&gt;
+    &lt;stimer state='on'&gt;
+      &lt;direct state='on'/&gt;
+    &lt;/stimer&gt;
     &lt;reset state='on'/&gt;
     &lt;vendor_id state='on' value='KVM Hv'/&gt;
     &lt;frequencies state='on'/&gt;
@@ -2148,9 +2150,9 @@
         </tr>
         <tr>
           <td>stimer</td>
-          <td>Enable SynIC timers</td>
-          <td>on, off</td>
-          <td><span class="since">1.3.3 (QEMU 2.6)</span></td>
+          <td>Enable SynIC timers, optionally with Direct Mode support</td>
+          <td>on, off; direct - on,off</td>
+          <td><span class="since">1.3.3 (QEMU 2.6), direct mode 5.7.0 (QEMU 4.1)</span></td>
         </tr>
         <tr>
           <td>reset</td>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a0771da45b..6707dcc634 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5907,7 +5907,7 @@
         </optional>
         <optional>
           <element name="stimer">
-            <ref name="featurestate"/>
+            <ref name="stimer"/>
           </element>
         </optional>
         <optional>
@@ -5956,6 +5956,20 @@
     </element>
   </define>
 
+  <!-- Hyper-V stimer features -->
+  <define name="stimer">
+    <interleave>
+      <optional>
+        <ref name="featurestate"/>
+      </optional>
+      <optional>
+        <element name="direct">
+          <ref name="featurestate"/>
+        </element>
+      </optional>
+    </interleave>
+  </define>
+
   <!-- Optional KVM features -->
   <define name="kvm">
     <element name="kvm">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0456369d55..f56e850ade 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20388,6 +20388,39 @@ virDomainDefParseXML(xmlDocPtr xml,
         ctxt->node = node;
     }
 
+    if (def->features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+        int value;
+        if ((n = virXPathNodeSet("./features/hyperv/stimer/*", ctxt, &nodes)) < 0)
+            goto error;
+
+        for (i = 0; i < n; i++) {
+            if (STRNEQ((const char *)nodes[i]->name, "direct")) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("unsupported Hyper-V stimer feature: %s"),
+                               nodes[i]->name);
+                goto error;
+            }
+
+            if (!(tmp = virXMLPropString(nodes[i], "state"))) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("missing 'state' attribute for "
+                                 "Hyper-V stimer '%s' feature"), "direct");
+                        goto error;
+            }
+
+            if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("invalid value of state argument "
+                                 "for Hyper-V stimer '%s' feature"), "direct");
+                goto error;
+            }
+
+            VIR_FREE(tmp);
+            def->hyperv_stimer_direct = value;
+        }
+        VIR_FREE(nodes);
+    }
+
     if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
         int feature;
         int value;
@@ -22612,6 +22645,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
         }
     }
 
+    if (src->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+        if (src->hyperv_stimer_direct != dst->hyperv_stimer_direct) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("State of HyperV stimer direct feature differs: "
+                             "source: '%s', destination: '%s'"),
+                           virTristateSwitchTypeToString(src->hyperv_stimer_direct),
+                           virTristateSwitchTypeToString(dst->hyperv_stimer_direct));
+            return false;
+        }
+    }
+
     /* kvm */
     if (src->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
         for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
@@ -28071,7 +28115,6 @@ virDomainDefFormatFeatures(virBufferPtr buf,
                 case VIR_DOMAIN_HYPERV_VPINDEX:
                 case VIR_DOMAIN_HYPERV_RUNTIME:
                 case VIR_DOMAIN_HYPERV_SYNIC:
-                case VIR_DOMAIN_HYPERV_STIMER:
                 case VIR_DOMAIN_HYPERV_RESET:
                 case VIR_DOMAIN_HYPERV_FREQUENCIES:
                 case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
@@ -28090,6 +28133,23 @@ virDomainDefFormatFeatures(virBufferPtr buf,
                                       def->hyperv_spinlocks);
                     break;
 
+                case VIR_DOMAIN_HYPERV_STIMER:
+                    if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) {
+                        virBufferAddLit(&childBuf, "/>\n");
+                        break;
+                    }
+                    if (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+                        virBufferAddLit(&childBuf, ">\n");
+                        virBufferAdjustIndent(&childBuf, 2);
+                        virBufferAddLit(&childBuf, "<direct state='on'/>\n");
+                        virBufferAdjustIndent(&childBuf, -2);
+                        virBufferAddLit(&childBuf, "</stimer>\n");
+                    } else {
+                        virBufferAddLit(&childBuf, "/>\n");
+                    }
+
+                    break;
+
                 case VIR_DOMAIN_HYPERV_VENDOR_ID:
                     if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) {
                         virBufferAddLit(&childBuf, "/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 57ca2a8ad1..8434f1fd0b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2400,6 +2400,7 @@ struct _virDomainDef {
     int kvm_features[VIR_DOMAIN_KVM_LAST];
     int msrs_features[VIR_DOMAIN_MSRS_LAST];
     unsigned int hyperv_spinlocks;
+    int hyperv_stimer_direct;
     virGICVersion gic_version;
     virDomainHPTResizing hpt_resizing;
     unsigned long long hpt_maxpagesize; /* Stored in KiB */
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index d2d9537c32..32b9836dd5 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -100,6 +100,8 @@ KVM_FEATURE_DEF(VIR_CPU_x86_HV_IPI,
                 0x40000004, 0x00000400, 0x0);
 KVM_FEATURE_DEF(VIR_CPU_x86_HV_EVMCS,
                 0x40000004, 0x00004000, 0x0);
+KVM_FEATURE_DEF(VIR_CPU_x86_HV_STIMER_DIRECT,
+                0x40000003, 0x0, 0x00080000);
 
 static virCPUx86Feature x86_kvm_features[] =
 {
@@ -116,6 +118,7 @@ static virCPUx86Feature x86_kvm_features[] =
     KVM_FEATURE(VIR_CPU_x86_HV_TLBFLUSH),
     KVM_FEATURE(VIR_CPU_x86_HV_IPI),
     KVM_FEATURE(VIR_CPU_x86_HV_EVMCS),
+    KVM_FEATURE(VIR_CPU_x86_HV_STIMER_DIRECT),
 };
 
 typedef struct _virCPUx86Model virCPUx86Model;
diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h
index cc0c93dff0..cebf3b6669 100644
--- a/src/cpu/cpu_x86_data.h
+++ b/src/cpu/cpu_x86_data.h
@@ -64,6 +64,8 @@ struct _virCPUx86MSR {
 #define VIR_CPU_x86_HV_IPI       "hv-ipi"
 #define VIR_CPU_x86_HV_EVMCS     "hv-evmcs"
 
+/* Hyper-V Synthetic Timer option */
+#define VIR_CPU_x86_HV_STIMER_DIRECT "hv-stimer-direct"
 
 #define VIR_CPU_X86_DATA_INIT { 0 }
 
-- 
2.20.1

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