mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Add new 'kvm' domain feature and ability to hide KVM signature
QEMU 2.1 added support for the kvm=off option to the -cpu command,
allowing the KVM hypervisor signature to be hidden from the guest.
This enables disabling of some paravirualization features in the
guest as well as allowing certain drivers which test for the
hypervisor to load. Domain XML syntax is as follows:
<domain type='kvm>
...
<features>
...
<kvm>
<hidden state='on'/>
</kvm>
</features>
...
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
committed by
Ján Tomko
parent
4dfc34c301
commit
d071164272
@@ -142,6 +142,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
|
||||
"viridian",
|
||||
"privnet",
|
||||
"hyperv",
|
||||
"kvm",
|
||||
"pvspinlock",
|
||||
"capabilities")
|
||||
|
||||
@@ -155,6 +156,9 @@ VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
|
||||
"vapic",
|
||||
"spinlocks")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
|
||||
"hidden")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST,
|
||||
"audit_control",
|
||||
"audit_write",
|
||||
@@ -12203,6 +12207,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
case VIR_DOMAIN_FEATURE_VIRIDIAN:
|
||||
case VIR_DOMAIN_FEATURE_PRIVNET:
|
||||
case VIR_DOMAIN_FEATURE_HYPERV:
|
||||
case VIR_DOMAIN_FEATURE_KVM:
|
||||
def->features[val] = VIR_TRISTATE_SWITCH_ON;
|
||||
break;
|
||||
|
||||
@@ -12330,6 +12335,54 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
ctxt->node = node;
|
||||
}
|
||||
|
||||
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
|
||||
int feature;
|
||||
int value;
|
||||
node = ctxt->node;
|
||||
if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
feature = virDomainKVMTypeFromString((const char *)nodes[i]->name);
|
||||
if (feature < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("unsupported KVM feature: %s"),
|
||||
nodes[i]->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctxt->node = nodes[i];
|
||||
|
||||
switch ((virDomainKVM) feature) {
|
||||
case VIR_DOMAIN_KVM_HIDDEN:
|
||||
if (!(tmp = virXPathString("string(./@state)", ctxt))) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("missing 'state' attribute for "
|
||||
"KVM feature '%s'"),
|
||||
nodes[i]->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("invalid value of state argument "
|
||||
"for KVM feature '%s'"),
|
||||
nodes[i]->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
VIR_FREE(tmp);
|
||||
def->kvm_features[feature] = value;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_KVM_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
ctxt->node = node;
|
||||
}
|
||||
|
||||
if ((n = virXPathNodeSet("./features/capabilities/*", ctxt, &nodes)) < 0)
|
||||
goto error;
|
||||
|
||||
@@ -14338,6 +14391,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
|
||||
}
|
||||
}
|
||||
|
||||
/* kvm */
|
||||
if (src->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
|
||||
for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
|
||||
switch ((virDomainKVM) i) {
|
||||
case VIR_DOMAIN_KVM_HIDDEN:
|
||||
if (src->kvm_features[i] != dst->kvm_features[i]) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("State of KVM feature '%s' differs: "
|
||||
"source: '%s', destination: '%s'"),
|
||||
virDomainKVMTypeToString(i),
|
||||
virTristateSwitchTypeToString(src->kvm_features[i]),
|
||||
virTristateSwitchTypeToString(dst->kvm_features[i]));
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_KVM_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18172,6 +18248,30 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||
virBufferAddLit(buf, "</hyperv>\n");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_KVM:
|
||||
if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
|
||||
break;
|
||||
|
||||
virBufferAddLit(buf, "<kvm>\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
for (j = 0; j < VIR_DOMAIN_KVM_LAST; j++) {
|
||||
switch ((virDomainKVM) j) {
|
||||
case VIR_DOMAIN_KVM_HIDDEN:
|
||||
if (def->kvm_features[j])
|
||||
virBufferAsprintf(buf, "<%s state='%s'/>\n",
|
||||
virDomainKVMTypeToString(j),
|
||||
virTristateSwitchTypeToString(
|
||||
def->kvm_features[j]));
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_KVM_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</kvm>\n");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_FEATURE_CAPABILITIES:
|
||||
if (def->features[i] == VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT &&
|
||||
!virDomainDefHasCapabilitiesFeatures(def))
|
||||
|
||||
@@ -1515,6 +1515,7 @@ typedef enum {
|
||||
VIR_DOMAIN_FEATURE_VIRIDIAN,
|
||||
VIR_DOMAIN_FEATURE_PRIVNET,
|
||||
VIR_DOMAIN_FEATURE_HYPERV,
|
||||
VIR_DOMAIN_FEATURE_KVM,
|
||||
VIR_DOMAIN_FEATURE_PVSPINLOCK,
|
||||
VIR_DOMAIN_FEATURE_CAPABILITIES,
|
||||
|
||||
@@ -1529,6 +1530,12 @@ typedef enum {
|
||||
VIR_DOMAIN_HYPERV_LAST
|
||||
} virDomainHyperv;
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_KVM_HIDDEN = 0,
|
||||
|
||||
VIR_DOMAIN_KVM_LAST
|
||||
} virDomainKVM;
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT = 0,
|
||||
VIR_DOMAIN_CAPABILITIES_POLICY_ALLOW,
|
||||
@@ -1945,6 +1952,7 @@ struct _virDomainDef {
|
||||
int features[VIR_DOMAIN_FEATURE_LAST];
|
||||
int apic_eoi;
|
||||
int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
|
||||
int kvm_features[VIR_DOMAIN_KVM_LAST];
|
||||
unsigned int hyperv_spinlocks;
|
||||
|
||||
/* These options are of type virTristateSwitch: ON = keep, OFF = drop */
|
||||
@@ -2628,6 +2636,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
|
||||
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
|
||||
VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy)
|
||||
VIR_ENUM_DECL(virDomainHyperv)
|
||||
VIR_ENUM_DECL(virDomainKVM)
|
||||
VIR_ENUM_DECL(virDomainRNGModel)
|
||||
VIR_ENUM_DECL(virDomainRNGBackend)
|
||||
VIR_ENUM_DECL(virDomainTPMModel)
|
||||
|
||||
@@ -6230,6 +6230,25 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
|
||||
}
|
||||
}
|
||||
|
||||
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
|
||||
if (!have_cpu) {
|
||||
virBufferAdd(&buf, default_model, -1);
|
||||
have_cpu = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
|
||||
switch ((virDomainKVM) i) {
|
||||
case VIR_DOMAIN_KVM_HIDDEN:
|
||||
if (def->kvm_features[i] == VIR_TRISTATE_SWITCH_ON)
|
||||
virBufferAddLit(&buf, ",kvm=off");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_KVM_LAST:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (virBufferCheckError(&buf) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@@ -10712,6 +10731,9 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
|
||||
}
|
||||
virStringFreeList(hv_tokens);
|
||||
hv_tokens = NULL;
|
||||
} else if (STREQ(tokens[i], "kvm=off")) {
|
||||
dom->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
|
||||
dom->kvm_features[VIR_DOMAIN_KVM_HIDDEN] = VIR_TRISTATE_SWITCH_ON;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user