Support 'Direct Mode' for Hyper-V Synthetic Timers in domain config.
Make it 'stimer' enlightenment option as it is not a separate thing.
Reviewed-by: Ján Tomko <jtomko(a)redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets(a)redhat.com>
---
docs/formatdomain.html.in | 10 +++---
docs/schemas/domaincommon.rng | 16 ++++++++-
src/conf/domain_conf.c | 62 ++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 1 +
src/cpu/cpu_x86.c | 3 ++
src/cpu/cpu_x86_data.h | 2 ++
6 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f5c882141a..de577e5755 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2033,7 +2033,9 @@
<vpindex state='on'/>
<runtime state='on'/>
<synic state='on'/>
- <stimer state='on'/>
+ <stimer state='on'>
+ <direct state='on'/>
+ </stimer>
<reset state='on'/>
<vendor_id state='on' value='KVM Hv'/>
<frequencies state='on'/>
@@ -2148,9 +2150,9 @@
</tr>
<tr>
<td>stimer</td>
- <td>Enable SynIC timers</td>
- <td>on, off</td>
- <td><span class="since">1.3.3 (QEMU
2.6)</span></td>
+ <td>Enable SynIC timers, optionally with Direct Mode support</td>
+ <td>on, off; direct - on,off</td>
+ <td><span class="since">1.3.3 (QEMU 2.6), direct mode
5.7.0 (QEMU 4.1)</span></td>
</tr>
<tr>
<td>reset</td>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a0771da45b..6707dcc634 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5907,7 +5907,7 @@
</optional>
<optional>
<element name="stimer">
- <ref name="featurestate"/>
+ <ref name="stimer"/>
</element>
</optional>
<optional>
@@ -5956,6 +5956,20 @@
</element>
</define>
+ <!-- Hyper-V stimer features -->
+ <define name="stimer">
+ <interleave>
+ <optional>
+ <ref name="featurestate"/>
+ </optional>
+ <optional>
+ <element name="direct">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ </interleave>
+ </define>
+
<!-- Optional KVM features -->
<define name="kvm">
<element name="kvm">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0456369d55..f56e850ade 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20388,6 +20388,39 @@ virDomainDefParseXML(xmlDocPtr xml,
ctxt->node = node;
}
+ if (def->features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ int value;
+ if ((n = virXPathNodeSet("./features/hyperv/stimer/*", ctxt,
&nodes)) < 0)
+ goto error;
+
+ for (i = 0; i < n; i++) {
+ if (STRNEQ((const char *)nodes[i]->name, "direct")) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported Hyper-V stimer feature: %s"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ if (!(tmp = virXMLPropString(nodes[i], "state"))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("missing 'state' attribute for "
+ "Hyper-V stimer '%s' feature"),
"direct");
+ goto error;
+ }
+
+ if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid value of state argument "
+ "for Hyper-V stimer '%s' feature"),
"direct");
+ goto error;
+ }
+
+ VIR_FREE(tmp);
+ def->hyperv_stimer_direct = value;
+ }
+ VIR_FREE(nodes);
+ }
+
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
int feature;
int value;
@@ -22612,6 +22645,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
}
}
+ if (src->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) {
+ if (src->hyperv_stimer_direct != dst->hyperv_stimer_direct) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("State of HyperV stimer direct feature differs: "
+ "source: '%s', destination:
'%s'"),
+ virTristateSwitchTypeToString(src->hyperv_stimer_direct),
+ virTristateSwitchTypeToString(dst->hyperv_stimer_direct));
+ return false;
+ }
+ }
+
/* kvm */
if (src->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
@@ -28071,7 +28115,6 @@ virDomainDefFormatFeatures(virBufferPtr buf,
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:
case VIR_DOMAIN_HYPERV_FREQUENCIES:
case VIR_DOMAIN_HYPERV_REENLIGHTENMENT:
@@ -28090,6 +28133,23 @@ virDomainDefFormatFeatures(virBufferPtr buf,
def->hyperv_spinlocks);
break;
+ case VIR_DOMAIN_HYPERV_STIMER:
+ if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) {
+ virBufferAddLit(&childBuf, "/>\n");
+ break;
+ }
+ if (def->hyperv_stimer_direct == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAddLit(&childBuf, ">\n");
+ virBufferAdjustIndent(&childBuf, 2);
+ virBufferAddLit(&childBuf, "<direct
state='on'/>\n");
+ virBufferAdjustIndent(&childBuf, -2);
+ virBufferAddLit(&childBuf, "</stimer>\n");
+ } else {
+ virBufferAddLit(&childBuf, "/>\n");
+ }
+
+ break;
+
case VIR_DOMAIN_HYPERV_VENDOR_ID:
if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) {
virBufferAddLit(&childBuf, "/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 57ca2a8ad1..8434f1fd0b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2400,6 +2400,7 @@ struct _virDomainDef {
int kvm_features[VIR_DOMAIN_KVM_LAST];
int msrs_features[VIR_DOMAIN_MSRS_LAST];
unsigned int hyperv_spinlocks;
+ int hyperv_stimer_direct;
virGICVersion gic_version;
virDomainHPTResizing hpt_resizing;
unsigned long long hpt_maxpagesize; /* Stored in KiB */
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index d2d9537c32..32b9836dd5 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -100,6 +100,8 @@ KVM_FEATURE_DEF(VIR_CPU_x86_HV_IPI,
0x40000004, 0x00000400, 0x0);
KVM_FEATURE_DEF(VIR_CPU_x86_HV_EVMCS,
0x40000004, 0x00004000, 0x0);
+KVM_FEATURE_DEF(VIR_CPU_x86_HV_STIMER_DIRECT,
+ 0x40000003, 0x0, 0x00080000);
static virCPUx86Feature x86_kvm_features[] =
{
@@ -116,6 +118,7 @@ static virCPUx86Feature x86_kvm_features[] =
KVM_FEATURE(VIR_CPU_x86_HV_TLBFLUSH),
KVM_FEATURE(VIR_CPU_x86_HV_IPI),
KVM_FEATURE(VIR_CPU_x86_HV_EVMCS),
+ KVM_FEATURE(VIR_CPU_x86_HV_STIMER_DIRECT),
};
typedef struct _virCPUx86Model virCPUx86Model;
diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h
index cc0c93dff0..cebf3b6669 100644
--- a/src/cpu/cpu_x86_data.h
+++ b/src/cpu/cpu_x86_data.h
@@ -64,6 +64,8 @@ struct _virCPUx86MSR {
#define VIR_CPU_x86_HV_IPI "hv-ipi"
#define VIR_CPU_x86_HV_EVMCS "hv-evmcs"
+/* Hyper-V Synthetic Timer option */
+#define VIR_CPU_x86_HV_STIMER_DIRECT "hv-stimer-direct"
#define VIR_CPU_X86_DATA_INIT { 0 }
--
2.20.1