]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: add support for Direct Mode for Hyper-V Synthetic timers
authorVitaly Kuznetsov <vkuznets@redhat.com>
Fri, 9 Aug 2019 14:31:39 +0000 (16:31 +0200)
committerJán Tomko <jtomko@redhat.com>
Mon, 19 Aug 2019 09:38:28 +0000 (11:38 +0200)
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>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/cpu/cpu_x86.c
src/cpu/cpu_x86_data.h

index a18119f9a08e1b15d0547d56d5094f80cd31cce5..fcb7c59c00d8aa815ff30a7a931bfb32f89d5858 100644 (file)
     &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;
         </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>
index 08853f9d9e9216a0082cbccd170dded49839b357..c48f8c4f56f44149cf5f2d7219837fe2b5c81a08 100644 (file)
         </optional>
         <optional>
           <element name="stimer">
-            <ref name="featurestate"/>
+            <ref name="stimer"/>
           </element>
         </optional>
         <optional>
     </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">
index 8642927d6bf3c931f887ba1398efd7aa2c0444ce..617ccac4a538f8ebefa346b858ce73688292aede 100644 (file)
@@ -20394,6 +20394,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;
@@ -22619,6 +22652,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++) {
@@ -28079,7 +28123,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:
@@ -28098,6 +28141,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");
index f7423b1b6f89d69b1e909e21af0655616d86fb4c..cbe7b611702edc1d240102d976d430122d38bac6 100644 (file)
@@ -2401,6 +2401,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 */
index d2d9537c3261de7df8cb2eb4620c9c1877853c25..32b9836dd5e4fe55fa26b8fe3dd47878fa962846 100644 (file)
@@ -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;
index cc0c93dff012b3c2135780bbe4affea7c6da2afd..cebf3b6669e05f61b4dfc8697cbb6befc40d031d 100644 (file)
@@ -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 }