diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 71ffe75045..630c682a6f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1460,6 +1460,11 @@
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='4096'/>
+ <vpindex state='on'/>
+ <runtime state='on'/>
+ <synic state='on'/>
+ <reset state='on'/>
+ <vendor_id state='on' value='KVM Hv'/>
</hyperv>
<kvm>
<hidden state='on'/>
@@ -1537,6 +1542,42 @@
on, off; retries - at least 4095 |
1.1.0 (QEMU only) |
+
+ vpindex |
+ Virtual processor index |
+ on, off |
+ 1.3.3 (QEMU 2.5) |
+
+
+ runtime |
+ Processor time spent on running guest code and on behalf of guest code |
+ on, off |
+ 1.3.3 (QEMU 2.5) |
+
+
+ synic |
+ Enable Synthetic Interrupt Controller (SyNIC) |
+ on, off |
+ 1.3.3 (QEMU 2.5) |
+
+
+ stimer |
+ Enable SyNIC timers |
+ on, off |
+ 1.3.3 (QEMU 2.5) |
+
+
+ reset |
+ Enable hypervisor reset |
+ on, off |
+ 1.3.3 (QEMU 2.5) |
+
+
+ vendor_id |
+ Set hypervisor vendor id |
+ on, off; value - string, up to 12 characters |
+ 1.3.3 (QEMU 2.5) |
+
pvspinlock
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index da6de40f87..46137ec4ca 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4902,6 +4902,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [^,]{0,12}
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 797570a42f..771ab4568e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -145,7 +145,13 @@ VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
"relaxed",
"vapic",
- "spinlocks")
+ "spinlocks",
+ "vpindex",
+ "runtime",
+ "synic",
+ "stimer",
+ "reset",
+ "vendor_id")
VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
"hidden")
@@ -2599,6 +2605,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->emulator);
VIR_FREE(def->description);
VIR_FREE(def->title);
+ VIR_FREE(def->hyperv_vendor_id);
virBlkioDeviceArrayClear(def->blkio.devices,
def->blkio.ndevices);
@@ -15605,6 +15612,11 @@ virDomainDefParseXML(xmlDocPtr xml,
switch ((virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
@@ -15626,6 +15638,33 @@ virDomainDefParseXML(xmlDocPtr xml,
}
break;
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (value != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ if (!(def->hyperv_vendor_id = virXPathString("string(./@value)",
+ ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing 'value' attribute for "
+ "HyperV feature 'vendor_id'"));
+ goto error;
+ }
+
+ if (strlen(def->hyperv_vendor_id) > VIR_DOMAIN_HYPERV_VENDOR_ID_MAX) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("HyperV vendor_id value must not be more "
+ "than %d characters."),
+ VIR_DOMAIN_HYPERV_VENDOR_ID_MAX);
+ goto error;
+ }
+
+ /* ensure that the string can be passed to qemu */
+ if (strchr(def->hyperv_vendor_id, ',')) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("HyperV vendor_id value is invalid"));
+ goto error;
+ }
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST:
break;
@@ -17628,6 +17667,11 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
if (src->hyperv_features[i] != dst->hyperv_features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment "
@@ -17653,6 +17697,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
}
break;
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (STRNEQ_NULLABLE(src->hyperv_vendor_id, dst->hyperv_vendor_id)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("HyperV vendor_id differs: "
+ "source: '%s', destination: '%s'"),
+ src->hyperv_vendor_id,
+ dst->hyperv_vendor_id);
+ return false;
+ }
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST:
break;
@@ -22342,6 +22397,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
switch ((virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
break;
case VIR_DOMAIN_HYPERV_SPINLOCKS:
@@ -22351,6 +22411,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->hyperv_spinlocks);
break;
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+ break;
+ virBufferEscapeString(buf, " value='%s'",
+ def->hyperv_vendor_id);
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST:
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 83bdd67dec..639fac5376 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1701,10 +1701,18 @@ typedef enum {
VIR_DOMAIN_FEATURE_LAST
} virDomainFeature;
+# define VIR_DOMAIN_HYPERV_VENDOR_ID_MAX 12
+
typedef enum {
VIR_DOMAIN_HYPERV_RELAXED = 0,
VIR_DOMAIN_HYPERV_VAPIC,
VIR_DOMAIN_HYPERV_SPINLOCKS,
+ VIR_DOMAIN_HYPERV_VPINDEX,
+ VIR_DOMAIN_HYPERV_RUNTIME,
+ VIR_DOMAIN_HYPERV_SYNIC,
+ VIR_DOMAIN_HYPERV_STIMER,
+ VIR_DOMAIN_HYPERV_RESET,
+ VIR_DOMAIN_HYPERV_VENDOR_ID,
VIR_DOMAIN_HYPERV_LAST
} virDomainHyperv;
@@ -2240,6 +2248,7 @@ struct _virDomainDef {
int kvm_features[VIR_DOMAIN_KVM_LAST];
unsigned int hyperv_spinlocks;
virGICVersion gic_version;
+ char *hyperv_vendor_id;
/* These options are of type virTristateSwitch: ON = keep, OFF = drop */
int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST];
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0331789b6b..45c5398ad8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6505,6 +6505,11 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(&buf, ",hv_%s",
virDomainHypervTypeToString(i));
@@ -6516,6 +6521,12 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
def->hyperv_spinlocks);
break;
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAsprintf(&buf, ",hv_vendor_id=%s",
+ def->hyperv_vendor_id);
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST:
break;
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index 60e3d69162..8b294a7df0 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -1539,6 +1539,11 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
switch ((virDomainHyperv) f) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
+ case VIR_DOMAIN_HYPERV_RESET:
if (value) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV feature '%s' should not "
@@ -1566,6 +1571,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
dom->hyperv_spinlocks = 0xFFF;
break;
+ case VIR_DOMAIN_HYPERV_VENDOR_ID:
+ dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
+ if (!value) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("missing HyperV vendor_id value"));
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP(dom->hyperv_vendor_id, value) < 0)
+ goto cleanup;
+
+ break;
+
case VIR_DOMAIN_HYPERV_LAST:
break;
}
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
index 1067f64e80..fe084636fd 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
@@ -14,6 +14,12 @@
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
index 141844a4b7..32846a2707 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
@@ -8,7 +8,8 @@ QEMU_AUDIO_DRV=none \
-name QEMUGuest1 \
-S \
-M pc \
--cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff \
+-cpu 'qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff,hv_vpindex,hv_runtime,\
+hv_synic,hv_stimer,hv_reset,hv_vendor_id=KVM Hv' \
-m 214 \
-smp 6 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
index 2b8f332a6b..a47013bc24 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
@@ -14,6 +14,12 @@
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv-off.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv-off.xml
index b09c447869..6163a5d6d9 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv-off.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv-off.xml
@@ -14,6 +14,12 @@
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv.xml
index a79115ceb9..c11c27393b 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv.xml
@@ -14,6 +14,12 @@
+
+
+
+
+
+