Support 'Direct Mode' for Hyper-V Synthetic Timers in domain config. Make it 'stimer' enlightenment option as it is not a separate thing. Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> --- docs/formatdomain.html.in | 10 ++- docs/schemas/domaincommon.rng | 16 +++- src/conf/domain_conf.c | 138 +++++++++++++++++++++++++++++++--- src/conf/domain_conf.h | 8 ++ src/cpu/cpu_x86.c | 51 +++++++------ src/cpu/cpu_x86_data.h | 2 + src/libvirt_private.syms | 2 + 7 files changed, 187 insertions(+), 40 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 1aaddb6d9b..a0723edad1 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.6.0 (QEMU 4.1)</span></td> </tr> <tr> <td>reset</td> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 763480440c..8cf1995748 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -5896,7 +5896,7 @@ </optional> <optional> <element name="stimer"> - <ref name="featurestate"/> + <ref name="stimer"/> </element> </optional> <optional> @@ -5945,6 +5945,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 0574c69a46..779b4ed880 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -197,6 +197,11 @@ VIR_ENUM_IMPL(virDomainHyperv, "evmcs", ); +VIR_ENUM_IMPL(virDomainHypervStimer, + VIR_DOMAIN_HYPERV_STIMER_LAST, + "direct", +); + VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST, "hidden", @@ -20359,6 +20364,51 @@ virDomainDefParseXML(xmlDocPtr xml, ctxt->node = node; } + if (def->features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) { + int feature; + int value; + if ((n = virXPathNodeSet("./features/hyperv/stimer/*", ctxt, &nodes)) < 0) + goto error; + + for (i = 0; i < n; i++) { + feature = virDomainHypervStimerTypeFromString((const char *)nodes[i]->name); + if (feature < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported Hyper-V stimer feature: %s"), + nodes[i]->name); + goto error; + } + + switch ((virDomainHypervStimer) feature) { + case VIR_DOMAIN_HYPERV_STIMER_DIRECT: + if (!(tmp = virXMLPropString(nodes[i], "state"))) { + virReportError(VIR_ERR_XML_ERROR, + _("missing 'state' attribute for " + "Hyper-V stimer feature '%s'"), + nodes[i]->name); + goto error; + } + + if ((value = virTristateSwitchTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid value of state argument " + "for Hyper-V stimer feature '%s'"), + nodes[i]->name); + goto error; + } + + VIR_FREE(tmp); + def->hyperv_stimer_features[feature] = value; + break; + + /* coverity[dead_error_begin] */ + case VIR_DOMAIN_HYPERV_STIMER_LAST: + break; + } + } + VIR_FREE(nodes); + } + if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { int feature; int value; @@ -22583,6 +22633,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } } + if (src->hyperv_features[VIR_DOMAIN_HYPERV_STIMER] == VIR_TRISTATE_SWITCH_ON) { + for (i = 0; i < VIR_DOMAIN_HYPERV_STIMER_LAST; i++) { + switch ((virDomainHypervStimer) i) { + case VIR_DOMAIN_HYPERV_STIMER_DIRECT: + if (src->hyperv_stimer_features[i] != dst->hyperv_stimer_features[i]) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("State of HyperV stimer feature '%s' differs: " + "source: '%s', destination: '%s'"), + virDomainHypervStimerTypeToString(i), + virTristateSwitchTypeToString(src->hyperv_stimer_features[i]), + virTristateSwitchTypeToString(dst->hyperv_stimer_features[i])); + return false; + } + + break; + + /* coverity[dead_error_begin] */ + case VIR_DOMAIN_HYPERV_STIMER_LAST: + break; + } + } + } + /* kvm */ if (src->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) { @@ -28017,6 +28090,8 @@ virDomainDefFormatFeatures(virBufferPtr buf, virBufferAddLit(&childBuf, "<hyperv>\n"); virBufferAdjustIndent(&childBuf, 2); for (j = 0; j < VIR_DOMAIN_HYPERV_LAST; j++) { + size_t k; + if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ABSENT) continue; @@ -28031,35 +28106,76 @@ 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: case VIR_DOMAIN_HYPERV_TLBFLUSH: case VIR_DOMAIN_HYPERV_IPI: case VIR_DOMAIN_HYPERV_EVMCS: + virBufferAddLit(&childBuf, "/>\n"); break; - case VIR_DOMAIN_HYPERV_SPINLOCKS: - if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) + case VIR_DOMAIN_HYPERV_STIMER: + if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) { + virBufferAddLit(&childBuf, "/>\n"); + break; + } + + for (k = 0; k < VIR_DOMAIN_HYPERV_STIMER_LAST; k++) { + if (def->hyperv_stimer_features[k]) + break; + } + + /* Omit long <stimer></stimer> form when no features are enabled */ + if (k == VIR_DOMAIN_HYPERV_STIMER_LAST) { + virBufferAddLit(&childBuf, "/>\n"); break; - virBufferAsprintf(&childBuf, " retries='%d'", - def->hyperv_spinlocks); + } + + virBufferAddLit(&childBuf, ">\n"); + virBufferAdjustIndent(&childBuf, 2); + + for (k = 0; k < VIR_DOMAIN_HYPERV_STIMER_LAST; k++) { + switch ((virDomainHypervStimer) k) { + case VIR_DOMAIN_HYPERV_STIMER_DIRECT: + if (def->hyperv_stimer_features[k]) + virBufferAsprintf(&childBuf, "<%s state='%s'/>\n", + virDomainHypervStimerTypeToString(k), + virTristateSwitchTypeToString( + def->hyperv_stimer_features[k])); + break; + + /* coverity[dead_error_begin] */ + case VIR_DOMAIN_HYPERV_STIMER_LAST: + break; + } + } + + virBufferAdjustIndent(&childBuf, -2); + virBufferAddLit(&childBuf, "</stimer>\n"); + + break; + + case VIR_DOMAIN_HYPERV_SPINLOCKS: + if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&childBuf, " retries='%d'", + def->hyperv_spinlocks); + } + virBufferAddLit(&childBuf, "/>\n"); break; case VIR_DOMAIN_HYPERV_VENDOR_ID: - if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON) - break; - virBufferEscapeString(&childBuf, " value='%s'", - def->hyperv_vendor_id); + if (def->hyperv_features[j] == VIR_TRISTATE_SWITCH_ON) { + virBufferEscapeString(&childBuf, " value='%s'", + def->hyperv_vendor_id); + } + virBufferAddLit(&childBuf, "/>\n"); break; /* coverity[dead_error_begin] */ case VIR_DOMAIN_HYPERV_LAST: break; } - - virBufferAddLit(&childBuf, "/>\n"); } virBufferAdjustIndent(&childBuf, -2); virBufferAddLit(&childBuf, "</hyperv>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 48b0af4b04..fc12887fc3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1762,6 +1762,12 @@ typedef enum { VIR_DOMAIN_HYPERV_LAST } virDomainHyperv; +typedef enum { + VIR_DOMAIN_HYPERV_STIMER_DIRECT = 0, + + VIR_DOMAIN_HYPERV_STIMER_LAST +} virDomainHypervStimer; + typedef enum { VIR_DOMAIN_KVM_HIDDEN = 0, @@ -2400,6 +2406,7 @@ struct _virDomainDef { int kvm_features[VIR_DOMAIN_KVM_LAST]; int msrs_features[VIR_DOMAIN_MSRS_LAST]; unsigned int hyperv_spinlocks; + int hyperv_stimer_features[VIR_DOMAIN_HYPERV_STIMER_LAST]; virGICVersion gic_version; virDomainHPTResizing hpt_resizing; unsigned long long hpt_maxpagesize; /* Stored in KiB */ @@ -3420,6 +3427,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode); VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode); VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy); VIR_ENUM_DECL(virDomainHyperv); +VIR_ENUM_DECL(virDomainHypervStimer); VIR_ENUM_DECL(virDomainKVM); VIR_ENUM_DECL(virDomainMsrsUnknown); VIR_ENUM_DECL(virDomainRNGModel); diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 55b55da784..4fb9e6a4df 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -59,9 +59,9 @@ struct _virCPUx86Feature { { .type = VIR_CPU_X86_DATA_CPUID, \ .data = { .cpuid = {__VA_ARGS__} } } -#define KVM_FEATURE_DEF(Name, Eax_in, Eax) \ +#define KVM_FEATURE_DEF(Name, Eax_in, Eax, Edx) \ static virCPUx86DataItem Name ## _data[] = { \ - CPUID(.eax_in = Eax_in, .eax = Eax), \ + CPUID(.eax_in = Eax_in, .eax = Eax, .edx = Edx), \ } #define KVM_FEATURE(Name) \ @@ -74,49 +74,51 @@ struct _virCPUx86Feature { } KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE, - 0x40000001, 0x00000001); + 0x40000001, 0x00000001, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_NOP_IO_DELAY, - 0x40000001, 0x00000002); + 0x40000001, 0x00000002, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_MMU_OP, - 0x40000001, 0x00000004); + 0x40000001, 0x00000004, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE2, - 0x40000001, 0x00000008); + 0x40000001, 0x00000008, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_ASYNC_PF, - 0x40000001, 0x00000010); + 0x40000001, 0x00000010, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_STEAL_TIME, - 0x40000001, 0x00000020); + 0x40000001, 0x00000020, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_EOI, - 0x40000001, 0x00000040); + 0x40000001, 0x00000040, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_UNHALT, - 0x40000001, 0x00000080); + 0x40000001, 0x00000080, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT, - 0x40000001, 0x01000000); + 0x40000001, 0x01000000, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RUNTIME, - 0x40000003, 0x00000001); + 0x40000003, 0x00000001, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SYNIC, - 0x40000003, 0x00000004); + 0x40000003, 0x00000004, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_STIMER, - 0x40000003, 0x00000008); + 0x40000003, 0x00000008, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RELAXED, - 0x40000003, 0x00000020); + 0x40000003, 0x00000020, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SPINLOCKS, - 0x40000003, 0x00000022); + 0x40000003, 0x00000022, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VAPIC, - 0x40000003, 0x00000030); + 0x40000003, 0x00000030, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VPINDEX, - 0x40000003, 0x00000040); + 0x40000003, 0x00000040, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RESET, - 0x40000003, 0x00000080); + 0x40000003, 0x00000080, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_FREQUENCIES, - 0x40000003, 0x00000800); + 0x40000003, 0x00000800, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_REENLIGHTENMENT, - 0x40000003, 0x00002000); + 0x40000003, 0x00002000, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_TLBFLUSH, - 0x40000004, 0x00000004); + 0x40000004, 0x00000004, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_IPI, - 0x40000004, 0x00000400); + 0x40000004, 0x00000400, 0x0); KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_EVMCS, - 0x40000004, 0x00004000); + 0x40000004, 0x00004000, 0x0); +KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_STIMER_DIRECT, + 0x40000003, 0x0, 0x00080000); static virCPUx86Feature x86_kvm_features[] = { @@ -142,6 +144,7 @@ static virCPUx86Feature x86_kvm_features[] = KVM_FEATURE(VIR_CPU_x86_KVM_HV_TLBFLUSH), KVM_FEATURE(VIR_CPU_x86_KVM_HV_IPI), KVM_FEATURE(VIR_CPU_x86_KVM_HV_EVMCS), + KVM_FEATURE(VIR_CPU_x86_KVM_HV_STIMER_DIRECT), }; typedef struct _virCPUx86Model virCPUx86Model; diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h index f3f4d7ab9c..198f19e037 100644 --- a/src/cpu/cpu_x86_data.h +++ b/src/cpu/cpu_x86_data.h @@ -72,6 +72,8 @@ struct _virCPUx86MSR { #define VIR_CPU_x86_KVM_HV_IPI "__kvm_hv_ipi" #define VIR_CPU_x86_KVM_HV_EVMCS "__kvm_hv_evmcs" +/* Hyper-V Synthetic Timer (virDomainHypervStimer) features */ +#define VIR_CPU_x86_KVM_HV_STIMER_DIRECT "__kvm_hv_stimer_direct" #define VIR_CPU_X86_DATA_INIT { 0 } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index dff97bd82a..ef8e6cd183 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -418,6 +418,8 @@ virDomainHostdevSubsysTypeToString; virDomainHPTResizingTypeToString; virDomainHubTypeFromString; virDomainHubTypeToString; +virDomainHypervStimerTypeFromString; +virDomainHypervStimerTypeToString; virDomainHypervTypeFromString; virDomainHypervTypeToString; virDomainInputBusTypeToString; -- 2.20.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list