From: Alex Williamson Date: Thu, 21 Aug 2014 17:04:45 +0000 (-0600) Subject: Add new 'kvm' domain feature and ability to hide KVM signature X-Git-Tag: v1.2.8-rc1~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d071164272c5750a952f179d32d285e333ee267a;p=thirdparty%2Flibvirt.git 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: ... Signed-off-by: Alex Williamson --- diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 59127bb085..de4e4ebfb6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1250,6 +1250,9 @@ <vapic state='on'/> <spinlocks state='on' retries='4096'/> </hyperv> + <kvm> + <hidden state='on'/> + </kvm> <pvspinlock/> </features> @@ -1328,7 +1331,23 @@ can be explicitly disabled by using state='off' attribute. - +
kvm
+
Various features to change the behavior of the KVM hypervisor. + + + + + + + + + + + + + +
FeatureDescriptionValueSince
hiddenHide the KVM hypervisor from standard MSR based discoveryon, off2.1.0 (QEMU only)
+

Time keeping

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9a89dd80fb..3170db25c3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3831,7 +3831,7 @@ @@ -3872,6 +3872,9 @@ + + + @@ -4477,6 +4480,19 @@ + + + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 22a7f7eac0..dd512cafbf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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, "\n"); break; + case VIR_DOMAIN_FEATURE_KVM: + if (def->features[i] != VIR_TRISTATE_SWITCH_ON) + break; + + virBufferAddLit(buf, "\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, "\n"); + break; + case VIR_DOMAIN_FEATURE_CAPABILITIES: if (def->features[i] == VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT && !virDomainDefHasCapabilitiesFeatures(def)) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 36ccf106e0..aead903095 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -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) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6dac9d3045..35ff8f2f03 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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; } } diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index 6bad7d6d19..9c00cd94db 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -284,6 +284,8 @@ mymain(void) DO_TEST("hyperv"); + DO_TEST("kvm-features"); + DO_TEST("pseries-nvram"); DO_TEST("pseries-disk"); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args new file mode 100644 index 0000000000..363fd2aa57 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu \ +-S -M pc -cpu qemu32 -m 214 -smp 6 -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-boot n -usb -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml new file mode 100644 index 0000000000..64b8cd89f1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml @@ -0,0 +1,27 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 6 + + hvm + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args new file mode 100644 index 0000000000..b223951f32 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc \ +-cpu qemu32,kvm=off -m 214 -smp 6 -nographic -monitor \ +unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial none \ +-parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml new file mode 100644 index 0000000000..3f2817e8ad --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml @@ -0,0 +1,27 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 6 + + hvm + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 74072723d3..1a8201aaf3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -672,6 +672,9 @@ mymain(void) DO_TEST("hyperv", NONE); DO_TEST("hyperv-off", NONE); + DO_TEST("kvm-features", NONE); + DO_TEST("kvm-features-off", NONE); + DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); DO_TEST("hugepages-pages", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 79cf59fc2b..b2d2eed344 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -198,6 +198,9 @@ mymain(void) DO_TEST("hyperv"); DO_TEST("hyperv-off"); + DO_TEST("kvm-features"); + DO_TEST("kvm-features-off"); + DO_TEST("hugepages"); DO_TEST("hugepages-pages"); DO_TEST("hugepages-pages2");