Introduce the 'msrs' feature element that controls Model Specific Registers related behaviour. At this moment it allows only single tunable attribute "unknown": <msrs unknown='ignore|fault'/> Which tells hypervisor to ignore accesses to unimplemented Model Specific Registers. The only user of that for now is going to be the bhyve driver. Signed-off-by: Roman Bogorodskiy <bogorodskiy@xxxxxxxxx> --- docs/formatdomain.html.in | 1 + docs/schemas/domaincommon.rng | 14 +++++++++++++ src/conf/domain_conf.c | 38 +++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 16 +++++++++++++++ src/qemu/qemu_domain.c | 1 + 5 files changed, 70 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 2ae5006849..5b03812b16 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2010,6 +2010,7 @@ <tlbflush state='on'/> <ipi state='on'/> <evmcs state='on'/> + <msrs unknown='ignore'/> </hyperv> <kvm> <hidden state='on'/> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ba80440c72..5345e54342 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4997,6 +4997,9 @@ <ref name="featurestate"/> </element> </optional> + <optional> + <ref name="msrs"/> + </optional> </interleave> </element> </optional> @@ -5245,6 +5248,17 @@ </element> </define> + <define name="msrs"> + <element name="msrs"> + <attribute name="unknown"> + <choice> + <value>ignore</value> + <value>fault</value> + </choice> + </attribute> + </element> + </define> + <define name="address"> <element name="address"> <choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6772c327ed..a3c43037d7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -157,6 +157,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "vmcoreinfo", "htm", "nested-hv", + "msrs", ); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, @@ -186,6 +187,11 @@ VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST, "hidden", ); +VIR_ENUM_IMPL(virDomainMsrsUnknown, VIR_DOMAIN_MSRS_UNKNOWN_LAST, + "ignore", + "fault", +); + VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST, "audit_control", "audit_write", @@ -20330,6 +20336,7 @@ virDomainDefParseXML(xmlDocPtr xml, case VIR_DOMAIN_FEATURE_PRIVNET: case VIR_DOMAIN_FEATURE_HYPERV: case VIR_DOMAIN_FEATURE_KVM: + case VIR_DOMAIN_FEATURE_MSRS: def->features[val] = VIR_TRISTATE_SWITCH_ON; break; @@ -20618,6 +20625,26 @@ virDomainDefParseXML(xmlDocPtr xml, def->tseg_specified = rv; } + if (def->features[VIR_DOMAIN_FEATURE_MSRS] == VIR_TRISTATE_SWITCH_ON) { + if ((node = virXPathNode("./features/msrs", ctxt)) == NULL) + goto error; + + if (!(tmp = virXMLPropString(node, "unknown"))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing 'unknown' attribute for feature '%s'"), + virDomainFeatureTypeToString(VIR_DOMAIN_FEATURE_MSRS)); + goto error; + } + + if ((def->msrs_features[VIR_DOMAIN_MSRS_UNKNOWN] = virDomainMsrsUnknownTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown 'unknown' value '%s'"), + tmp); + goto error; + } + VIR_FREE(tmp); + } + if ((n = virXPathNodeSet("./features/capabilities/*", ctxt, &nodes)) < 0) goto error; @@ -22678,6 +22705,9 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } break; + case VIR_DOMAIN_FEATURE_MSRS: + break; + case VIR_DOMAIN_FEATURE_LAST: break; } @@ -28735,6 +28765,14 @@ virDomainDefFormatInternal(virDomainDefPtr def, } break; + case VIR_DOMAIN_FEATURE_MSRS: + if (def->features[i] != VIR_TRISTATE_SWITCH_ON) + break; + + virBufferAsprintf(buf, "<msrs unknown='%s'/>\n", + virDomainMsrsUnknownTypeToString(def->msrs_features[VIR_DOMAIN_MSRS_UNKNOWN])); + break; + /* coverity[dead_error_begin] */ case VIR_DOMAIN_FEATURE_LAST: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2bc3f879f7..21357cc7d2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1782,6 +1782,7 @@ typedef enum { VIR_DOMAIN_FEATURE_VMCOREINFO, VIR_DOMAIN_FEATURE_HTM, VIR_DOMAIN_FEATURE_NESTED_HV, + VIR_DOMAIN_FEATURE_MSRS, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; @@ -1813,6 +1814,19 @@ typedef enum { VIR_DOMAIN_KVM_LAST } virDomainKVM; +typedef enum { + VIR_DOMAIN_MSRS_UNKNOWN = 0, + + VIR_DOMAIN_MSRS_LAST +} virDomainMsrs; + +typedef enum { + VIR_DOMAIN_MSRS_UNKNOWN_IGNORE = 0, + VIR_DOMAIN_MSRS_UNKNOWN_FAULT, + + VIR_DOMAIN_MSRS_UNKNOWN_LAST +} virDomainMsrsUnknown; + typedef enum { VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT = 0, VIR_DOMAIN_CAPABILITIES_POLICY_ALLOW, @@ -2466,6 +2480,7 @@ struct _virDomainDef { int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST]; int hyperv_features[VIR_DOMAIN_HYPERV_LAST]; int kvm_features[VIR_DOMAIN_KVM_LAST]; + int msrs_features[VIR_DOMAIN_MSRS_LAST]; unsigned int hyperv_spinlocks; virGICVersion gic_version; virDomainHPTResizing hpt_resizing; @@ -3468,6 +3483,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode); VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy); VIR_ENUM_DECL(virDomainHyperv); VIR_ENUM_DECL(virDomainKVM); +VIR_ENUM_DECL(virDomainMsrsUnknown); VIR_ENUM_DECL(virDomainRNGModel); VIR_ENUM_DECL(virDomainRNGBackend); VIR_ENUM_DECL(virDomainTPMModel); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 801d25a44b..d96bf24ae1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4033,6 +4033,7 @@ qemuDomainDefValidateFeatures(const virDomainDef *def, case VIR_DOMAIN_FEATURE_PMU: case VIR_DOMAIN_FEATURE_VMPORT: case VIR_DOMAIN_FEATURE_VMCOREINFO: + case VIR_DOMAIN_FEATURE_MSRS: case VIR_DOMAIN_FEATURE_LAST: break; } -- 2.20.1