diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084f42..77126a56fe 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 @@
Feature |
Description |
Value |
+ Since |
relaxed |
Relax contstraints on timers |
on, off |
+ 1.0.0 (QEMU only) |
+
+
+ vapic |
+ Enable virtual APIC |
+ on, off |
+ 1.1.0 (QEMU only) |
+
+
+ spinlocks |
+ Enable spinlock support |
+ on, off; retries - at least 4095 |
+ 1.1.0 (QEMU only) |
- Since 1.0.0 (QEMU only)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1eb2f68206..cf82878e21 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4015,6 +4015,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 92979372fb..e41dfa2e66 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, " 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 5b159aca78..3817e37f6b 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 486682e77c..52a698efd4 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;
}