[libvirt] [PATCH v5 1/2] conf: add vapic and spinlocks to hyperv features

Ján Tomko jtomko at redhat.com
Fri Jun 21 10:41:53 UTC 2013


Add new CPU features for HyperV:
vapic for virtual APIC support
spinlocks for setting spinlock support

<features>
  <hyperv>
    <vapic state='on'/>
    <spinlocks state='on' retries='4096'/>
  </hyperv>
</features>

https://bugzilla.redhat.com/show_bug.cgi?id=784836
---
 docs/formatdomain.html.in     | 17 +++++++++++-
 docs/schemas/domaincommon.rng | 13 +++++++++
 src/conf/domain_conf.c        | 64 +++++++++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h        |  3 ++
 src/qemu/qemu_command.c       | 10 +++++++
 5 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084..77126a5 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1147,6 +1147,8 @@
     <privnet/>
     <hyperv>
       <relaxed state='on'/>
+      <vapic state='on'/>
+      <spinlocks state='on' retries='4096'</spinlocks>
     </hyperv>
 
   </features>
@@ -1197,14 +1199,27 @@
           <th>Feature</th>
           <th>Description</th>
           <th>Value</th>
+          <th>Since</th>
         </tr>
         <tr>
           <td>relaxed</td>
           <td>Relax contstraints on timers</td>
           <td> on, off</td>
+          <td><span class="since">1.0.0 (QEMU only)</span></td>
+        </tr>
+        <tr>
+          <td>vapic</td>
+          <td>Enable virtual APIC</td>
+          <td>on, off</td>
+          <td><span class="since">1.1.0 (QEMU only)</span></td>
+        </tr>
+        <tr>
+          <td>spinlocks</td>
+          <td>Enable spinlock support</td>
+          <td>on, off; retries - at least 4095</td>
+          <td><span class="since">1.1.0 (QEMU only)</span></td>
         </tr>
       </table>
-      <span class="since">Since 1.0.0 (QEMU only)</span>
       </dd>
     </dl>
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1eb2f68..cf82878 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4015,6 +4015,19 @@
             <ref name="hypervtristate"/>
           </element>
         </optional>
+        <optional>
+          <element name="vapic">
+            <ref name="hypervtristate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="spinlocks">
+            <ref name="hypervtristate"/>
+            <attribute name="retries">
+              <data type="integer"/>
+            </attribute>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9297937..e41dfa2 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -149,7 +149,9 @@ VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
               "off")
 
 VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
-              "relaxed")
+              "relaxed",
+              "vapic",
+              "spinlocks")
 
 VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
               "destroy",
@@ -11084,6 +11086,7 @@ virDomainDefParseXML(xmlDocPtr xml,
 
             switch ((enum virDomainHyperv) feature) {
                 case VIR_DOMAIN_HYPERV_RELAXED:
+                case VIR_DOMAIN_HYPERV_VAPIC:
                     if (!(tmp = virXPathString("string(./@state)", ctxt))) {
                         virReportError(VIR_ERR_XML_ERROR,
                                        _("missing 'state' attribute for "
@@ -11104,6 +11107,48 @@ virDomainDefParseXML(xmlDocPtr xml,
                     def->hyperv_features[feature] = value;
                     break;
 
+                case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                    if (!(tmp = virXPathString("string(./@state)", ctxt))) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("missing 'state' attribute for "
+                                         "HyperV Enlightenment feature '%s'"),
+                                       nodes[i]->name);
+                        goto error;
+                    }
+
+                    if ((value = virDomainFeatureStateTypeFromString(tmp)) < 0) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("invalid value of state argument "
+                                         "for HyperV Enlightenment feature '%s'"),
+                                       nodes[i]->name);
+                        goto error;
+                    }
+
+                    VIR_FREE(tmp);
+                    if (!(tmp = virXPathString("string(./@retries)", ctxt))) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("missing HyperV spinlock retry count"));
+                        goto error;
+                    }
+
+                    if (virStrToLong_ui(tmp, NULL, 0,
+                                        &def->hyperv_spinlocks) < 0) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("Cannot parse HyperV spinlock retry "
+                                         "count"));
+                        goto error;
+                    }
+
+                    if (def->hyperv_spinlocks < 0xFFF) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("HyperV spinlock retry count must be "
+                                         "at least 4095"));
+                        goto error;
+                    }
+                    VIR_FREE(tmp);
+                    def->hyperv_features[feature] = value;
+                    break;
+
                 case VIR_DOMAIN_HYPERV_LAST:
                     break;
             }
@@ -16224,10 +16269,25 @@ virDomainDefFormatInternal(virDomainDefPtr def,
             for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
                 switch ((enum virDomainHyperv) i) {
                 case VIR_DOMAIN_HYPERV_RELAXED:
+                case VIR_DOMAIN_HYPERV_VAPIC:
                     if (def->hyperv_features[i])
                         virBufferAsprintf(buf, "      <%s state='%s'/>\n",
                                           virDomainHypervTypeToString(i),
-                                          virDomainFeatureStateTypeToString(def->hyperv_features[i]));
+                                          virDomainFeatureStateTypeToString(
+                                              def->hyperv_features[i]));
+                    break;
+
+                case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                    if (def->hyperv_features[i] == 0)
+                        break;
+
+                    virBufferAsprintf(buf, "      <spinlocks state='%s'",
+                                      virDomainFeatureStateTypeToString(
+                                          def->hyperv_features[i]));
+                    if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
+                        virBufferAsprintf(buf, " retries='%d'",
+                                          def->hyperv_spinlocks);
+                    virBufferAddLit(buf, "/>\n");
                     break;
 
                 case VIR_DOMAIN_HYPERV_LAST:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5b159ac..3817e37 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1584,6 +1584,8 @@ enum virDomainFeatureState {
 
 enum virDomainHyperv {
     VIR_DOMAIN_HYPERV_RELAXED = 0,
+    VIR_DOMAIN_HYPERV_VAPIC,
+    VIR_DOMAIN_HYPERV_SPINLOCKS,
 
     VIR_DOMAIN_HYPERV_LAST
 };
@@ -1926,6 +1928,7 @@ struct _virDomainDef {
     int apic_eoi;
     /* These options are of type virDomainFeatureState */
     int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+    unsigned int hyperv_spinlocks;
 
     virDomainClockDef clock;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 486682e..52a698e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5791,6 +5791,11 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
                                       virDomainHypervTypeToString(i));
                 break;
 
+            case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                /* implemented in the next commit */
+                break;
+
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
             }
@@ -9726,6 +9731,11 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
                 dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
                 break;
 
+            case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                /* implemented in the next commit */
+                break;
+
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
             }
-- 
1.8.1.5




More information about the libvir-list mailing list