[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH v3 2/2] qemu: add hv_vapic and hv_spinlocks support



On 06/05/13 17:50, Ján Tomko wrote:
Add new CPU flags for HyperV:
hv_vapic for virtual APIC support
hv_spinlocks for spinlock support

XML:
<features>
   <hyperv>
     <vapic state='on'/>
     <spinlocks>0xFFFF</spinlocks>

Is the Microsoft documentation for this feature use hex values?

   </hyperv>
</features>

results in the following QEMU command line:
qemu -cpu <cpu_model>,hv_vapic,hv_spinlocks=0xffff

https://bugzilla.redhat.com/show_bug.cgi?id=784836
---
  docs/formatdomain.html.in                       | 17 ++++++++-
  docs/schemas/domaincommon.rng                   | 12 +++++++
  src/conf/domain_conf.c                          | 40 ++++++++++++++++++++-
  src/conf/domain_conf.h                          |  3 ++
  src/qemu/qemu_command.c                         | 48 ++++++++++++++++++++++++-
  tests/qemuxml2argvdata/qemuxml2argv-hyperv.args |  2 +-
  tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml  |  2 ++
  7 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084..983e070 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1147,6 +1147,8 @@
      &lt;privnet/&gt;
      &lt;hyperv&gt;
        &lt;relaxed state='on'/&gt;
+      &lt;vapic state='on'/&gt;
+      &lt;spinlocks&gt;0xFFFF&lt;/spinlocks&gt;
      &lt;/hyperv&gt;

    &lt;/features&gt;
@@ -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.0.6 (QEMU only)</span></td>
+        </tr>
+        <tr>
+          <td>spinlocks</td>
+          <td>Enable spinlock support</td>
+          <td>hexadecimal number of retries, at least 0xFFF</td>
+          <td><span class="since">1.0.6 (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 3cace35..ff14f34 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4017,6 +4017,18 @@
              <ref name="hypervtristate"/>
            </element>
          </optional>
+        <optional>
+          <element name="vapic">
+            <ref name="hypervtristate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="spinlocks">
+            <data type="string">
+              <param name="pattern">0x[0-9a-fA-F]{0,8}</param>
+            </data>
+          </element>
+        </optional>
        </interleave>
      </element>
    </define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a16ebd1..3d231a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -148,7 +148,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",
@@ -11061,6 +11063,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 "
@@ -11081,6 +11084,32 @@ virDomainDefParseXML(xmlDocPtr xml,
                      def->hyperv_features[feature] = value;
                      break;

+                case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                    if (!(tmp = virXPathString("string(.)", ctxt))) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("missing HyperV spinlock retry count"));
+                        goto error;
+                    }
+
+                    if (virStrToLong_ui(tmp, NULL, 0,
+                                        &def->hyperv_spinlocks) < 0) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("Cannot parse HyperV spinlock retry "
+                                         "count"));

Missing formatting literal "%s" (breaks syntax-check)

+                        goto error;
+                    }
+
+                    if (def->hyperv_spinlocks < 0xFFF) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("HyperV spinlock retry count must be "
+                                         "at least 0xFFF"));

Missing formatting literal "%s" (breaks syntax-check)

+                        goto error;
+                    }
+                    VIR_FREE(tmp);
+                    def->hyperv_features[VIR_DOMAIN_HYPERV_SPINLOCKS] =
+                        VIR_DOMAIN_FEATURE_STATE_ON;
+                    break;
+
                  case VIR_DOMAIN_HYPERV_LAST:
                      break;
              }
@@ -16175,12 +16204,21 @@ 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]));
                      break;

+                case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                    if (def->hyperv_features[i])
+                        virBufferAsprintf(buf, "      <%s>0x%x</%s>\n",
+                                          virDomainHypervTypeToString(i),

The spinlocks case statement doesn't seem to be universal. You can avoid a function call by directly using the XML field name instead of doing virDomainHypervTypeToString().

+                                          def->hyperv_spinlocks,
+                                          virDomainHypervTypeToString(i));

Twice.

+                    break;
+
                  case VIR_DOMAIN_HYPERV_LAST:
                      break;
                  }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3a71d6c..cce1189 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1583,6 +1583,8 @@ enum virDomainFeatureState {

  enum virDomainHyperv {
      VIR_DOMAIN_HYPERV_RELAXED = 0,
+    VIR_DOMAIN_HYPERV_VAPIC,
+    VIR_DOMAIN_HYPERV_SPINLOCKS,

      VIR_DOMAIN_HYPERV_LAST
  };
@@ -1920,6 +1922,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 5513e28..b0119d8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5782,11 +5782,18 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
          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] == VIR_DOMAIN_FEATURE_STATE_ON)
                      virBufferAsprintf(&buf, ",hv_%s",
                                        virDomainHypervTypeToString(i));
                  break;

+            case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
+                    virBufferAsprintf(&buf,",hv_spinlocks=0x%x",
+                                      def->hyperv_spinlocks);
+                break;
+
              case VIR_DOMAIN_HYPERV_LAST:
                  break;
              }
@@ -9623,6 +9630,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
  {
      virCPUDefPtr cpu = NULL;
      char **tokens;
+    char **hv_tokens = NULL;
      char *model = NULL;
      int ret = -1;
      int i;
@@ -9702,9 +9710,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
                      goto cleanup;
              }
          } else if (STRPREFIX(tokens[i], "hv_")) {
-            const char *feature = tokens[i] + 3; /* "hv_" */
+            const char *token = tokens[i] + 3; /* "hv_" */
+            const char *feature, *value;
              int f;

+            if (*token == '\0')
+                goto syntax;
+
+            if (!(hv_tokens = virStringSplit(token, "=", 2)))
+                goto cleanup;
+
+            feature = hv_tokens[0];
+            value = hv_tokens[1];
+
              if (*feature == '\0')
                  goto syntax;

@@ -9719,12 +9737,39 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,

              switch ((enum virDomainHyperv) f) {
              case VIR_DOMAIN_HYPERV_RELAXED:
+            case VIR_DOMAIN_HYPERV_VAPIC:
+                if (value) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("HyperV feature '%s' should not "
+                                     "have a value"), feature);
+                    goto cleanup;
+                }
                  dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
                  break;

+            case VIR_DOMAIN_HYPERV_SPINLOCKS:
+                dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
+                if (!hv_tokens[1]) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,

Missing formatting literal "%s" (breaks syntax-check)

+                                   _("missing HyperV spinlock retry count"));
+                    goto cleanup;
+                }
+
+                if (virStrToLong_ui(value, NULL, 0, &dom->hyperv_spinlocks) < 0) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,

Missing formatting literal "%s" (breaks syntax-check)

+                                   _("cannot parse HyperV spinlock retry count"));
+                    goto cleanup;
+                }
+
+                if (dom->hyperv_spinlocks < 0xFFF)
+                    dom->hyperv_spinlocks = 0xFFF;
+                break;
+
              case VIR_DOMAIN_HYPERV_LAST:
                  break;
              }
+            virStringFreeList(hv_tokens);
+            hv_tokens = NULL;
          }
      }

@@ -9752,6 +9797,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
  cleanup:
      VIR_FREE(model);
      virStringFreeList(tokens);
+    virStringFreeList(hv_tokens);
      return ret;

  syntax:
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
index fac4d5f..df6b207 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
@@ -1,4 +1,4 @@
  LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
--cpu qemu32,hv_relaxed -m 214 -smp 6 -nographic -monitor \
+-cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff -m 214 -smp 6 -nographic -monitor \
  unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial none \
  -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
index 0d5d0c7..9601645 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
@@ -12,6 +12,8 @@
      <acpi/>
      <hyperv>
        <relaxed state='on'/>
+      <vapic state='on'/>
+      <spinlocks>0x2fff</spinlocks>
      </hyperv>
    </features>
    <clock offset='utc'/>


Peter


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]