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

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


XML:
<features>
  <hyperv>
    <vapic state='on'/>
    <spinlocks state='on' retries='4096'/>
  </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
---
 src/qemu/qemu_command.c                         | 46 ++++++++++++++++++++++---
 tests/qemuxml2argvdata/qemuxml2argv-hyperv.args |  2 +-
 tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml  |  2 ++
 3 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 52a698e..4d70004 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5786,14 +5786,16 @@ 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_VAPIC:
             case VIR_DOMAIN_HYPERV_SPINLOCKS:
-                /* implemented in the next commit */
+                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:
@@ -9632,6 +9634,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
 {
     virCPUDefPtr cpu = NULL;
     char **tokens;
+    char **hv_tokens = NULL;
     char *model = NULL;
     int ret = -1;
     int i;
@@ -9711,9 +9714,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;
 
@@ -9728,17 +9741,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_VAPIC:
             case VIR_DOMAIN_HYPERV_SPINLOCKS:
-                /* implemented in the next commit */
+                dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
+                if (!value) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("missing HyperV spinlock retry count"));
+                    goto cleanup;
+                }
+
+                if (virStrToLong_ui(value, NULL, 0, &dom->hyperv_spinlocks) < 0) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("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;
         }
     }
 
@@ -9766,6 +9801,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..bb36fc0 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 state='on' retries='12287'/>
     </hyperv>
   </features>
   <clock offset='utc'/>
-- 
1.8.1.5




More information about the libvir-list mailing list