From 19f75d5eeb6bedd49597034832284146c7591a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Fri, 21 Jun 2013 12:22:18 +0200 Subject: [PATCH] qemu: add hv_vapic and hv_spinlocks support XML: results in the following QEMU command line: qemu -cpu ,hv_vapic,hv_spinlocks=0x1000 https://bugzilla.redhat.com/show_bug.cgi?id=784836 --- src/qemu/qemu_command.c | 46 +++++++++++++++++-- .../qemuxml2argvdata/qemuxml2argv-hyperv.args | 2 +- .../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 52a698efd4..4d7000480f 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 fac4d5fed8..df6b20719d 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 0d5d0c717c..bb36fc0af5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml @@ -12,6 +12,8 @@ + + -- GitLab