diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a18119f9a08e1b15d0547d56d5094f80cd31cce5..fcb7c59c00d8aa815ff30a7a931bfb32f89d5858 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'/> @@ -2149,9 +2151,9 @@ stimer - Enable SynIC timers - on, off - 1.3.3 (QEMU 2.6) + Enable SynIC timers, optionally with Direct Mode support + on, off; direct - on,off + 1.3.3 (QEMU 2.6), direct mode 5.7.0 (QEMU 4.1) reset diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 08853f9d9e9216a0082cbccd170dded49839b357..c48f8c4f56f44149cf5f2d7219837fe2b5c81a08 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5907,7 +5907,7 @@ - + @@ -5956,6 +5956,20 @@ + + + + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8642927d6bf3c931f887ba1398efd7aa2c0444ce..617ccac4a538f8ebefa346b858ce73688292aede 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -20394,6 +20394,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; @@ -22619,6 +22652,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++) { @@ -28079,7 +28123,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: @@ -28098,6 +28141,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, "\n"); + virBufferAdjustIndent(&childBuf, -2); + virBufferAddLit(&childBuf, "\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 f7423b1b6f89d69b1e909e21af0655616d86fb4c..cbe7b611702edc1d240102d976d430122d38bac6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2401,6 +2401,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 d2d9537c3261de7df8cb2eb4620c9c1877853c25..32b9836dd5e4fe55fa26b8fe3dd47878fa962846 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 cc0c93dff012b3c2135780bbe4affea7c6da2afd..cebf3b6669e05f61b4dfc8697cbb6befc40d031d 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 }