<vapic state='on'/>
<spinlocks state='on' retries='4096'/>
</hyperv>
+ <kvm>
+ <hidden state='on'/>
+ </kvm>
<pvspinlock/>
</features>
can be explicitly disabled by using <code>state='off'</code>
attribute.
</dd>
-
+ <dt><code>kvm</code></dt>
+ <dd>Various features to change the behavior of the KVM hypervisor.
+ <table class="top_table">
+ <tr>
+ <th>Feature</th>
+ <th>Description</th>
+ <th>Value</th>
+ <th>Since</th>
+ </tr>
+ <tr>
+ <td>hidden</td>
+ <td>Hide the KVM hypervisor from standard MSR based discovery</td>
+ <td>on, off</td>
+ <td><span class="since">2.1.0 (QEMU only)</span></td>
+ </tr>
+ </table>
+ </dd>
</dl>
<h3><a name="elementsTime">Time keeping</a></h3>
</define>
<!--
A set of optional features: PAE, APIC, ACPI,
- HyperV Enlightenment, paravirtual spinlocks and HAP support
+ HyperV Enlightenment, KVM features, paravirtual spinlocks and HAP support
-->
<define name="features">
<optional>
<empty/>
</element>
</optional>
+ <optional>
+ <ref name="kvm"/>
+ </optional>
<optional>
<element name="privnet">
<empty/>
</element>
</define>
+ <!-- Optional KVM features -->
+ <define name="kvm">
+ <element name="kvm">
+ <interleave>
+ <optional>
+ <element name="hidden">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<!-- Optional capabilities features -->
<define name="capabilities">
<element name="capabilities">
"viridian",
"privnet",
"hyperv",
+ "kvm",
"pvspinlock",
"capabilities")
"vapic",
"spinlocks")
+VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
+ "hidden")
+
VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST,
"audit_control",
"audit_write",
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;
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;
}
}
+ /* 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;
}
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))
VIR_DOMAIN_FEATURE_VIRIDIAN,
VIR_DOMAIN_FEATURE_PRIVNET,
VIR_DOMAIN_FEATURE_HYPERV,
+ VIR_DOMAIN_FEATURE_KVM,
VIR_DOMAIN_FEATURE_PVSPINLOCK,
VIR_DOMAIN_FEATURE_CAPABILITIES,
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,
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 */
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)
}
}
+ 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;
}
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;
}
}
DO_TEST("hyperv");
+ DO_TEST("kvm-features");
+
DO_TEST("pseries-nvram");
DO_TEST("pseries-disk");
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <kvm>
+ <hidden state='off'/>
+ </kvm>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+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
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <kvm>
+ <hidden state='on'/>
+ </kvm>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
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);
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");