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