]> xenbits.xensource.com Git - libvirt.git/commitdiff
Introduce SMM feature
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 13 Jul 2016 12:09:20 +0000 (14:09 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 4 Aug 2016 15:14:20 +0000 (17:14 +0200)
Since its release of 2.4.0 qemu is able to enable System
Management Module in the firmware, or disable it. We should
expose this capability in the XML. Unfortunately, there's no good
way to determine whether the binary we are talking to supports
it. I mean, if qemu's run with real machine type, the smm
attribute can be seen in 'qom-list /machine' output. But it's not
there when qemu's run with -M none. Therefore we're stuck with
version based check.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
16 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_command.c
tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml
tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml
tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml
tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml
tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml
tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml
tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c

index fa88839ec59a102bb3926fe4f799efd5eb8f47cc..dabe604ec213ca6f0ff8f479b616b7dbbd795eb6 100644 (file)
           values are <code>2</code>, <code>3</code> and <code>host</code>.
           <span class="since">Since 1.2.16</span>
       </dd>
+      <dt><code>smm</code></dt>
+      <dd>Enable System Management Mode. Possible values are
+          <code>on</code> and <code>off</code>. The default is left
+          for hypervisor to decide.
+          <span class="since">Since 2.1.0</span>
+      </dd>
     </dl>
 
     <h3><a name="elementsTime">Time keeping</a></h3>
index cb9f1349f3c9326b9adb21b911c3ddf30547980c..5233766239e866969ea418fa989df3a4ee35d385 100644 (file)
               </optional>
             </element>
           </optional>
+          <optional>
+            <element name="smm">
+              <optional>
+                <attribute name="state">
+                  <ref name="virOnOff"/>
+                </attribute>
+              </optional>
+            </element>
+          </optional>
         </interleave>
       </element>
     </optional>
index e58046be89c516a89847e870c6bd532b48d14e89..3d3e74ca2b093d716e7a25f8ae6cbf65c43a9488 100644 (file)
@@ -137,7 +137,8 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
               "capabilities",
               "pmu",
               "vmport",
-              "gic")
+              "gic",
+              "smm")
 
 VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
               "default",
@@ -16348,6 +16349,7 @@ virDomainDefParseXML(xmlDocPtr xml,
         case VIR_DOMAIN_FEATURE_PMU:
         case VIR_DOMAIN_FEATURE_PVSPINLOCK:
         case VIR_DOMAIN_FEATURE_VMPORT:
+        case VIR_DOMAIN_FEATURE_SMM:
             node = ctxt->node;
             ctxt->node = nodes[i];
             if ((tmp = virXPathString("string(./@state)", ctxt))) {
@@ -23331,6 +23333,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
             case VIR_DOMAIN_FEATURE_PMU:
             case VIR_DOMAIN_FEATURE_PVSPINLOCK:
             case VIR_DOMAIN_FEATURE_VMPORT:
+            case VIR_DOMAIN_FEATURE_SMM:
                 switch ((virTristateSwitch) def->features[i]) {
                 case VIR_TRISTATE_SWITCH_LAST:
                 case VIR_TRISTATE_SWITCH_ABSENT:
index b2e905dd94b739d5bb17a027eee817ec02f69910..cea7d1d7d63a80ac5ddfaa236197a124aa5905a5 100644 (file)
@@ -1602,6 +1602,7 @@ typedef enum {
     VIR_DOMAIN_FEATURE_PMU,
     VIR_DOMAIN_FEATURE_VMPORT,
     VIR_DOMAIN_FEATURE_GIC,
+    VIR_DOMAIN_FEATURE_SMM,
 
     VIR_DOMAIN_FEATURE_LAST
 } virDomainFeature;
index 002fbe3a72f117a41592611f7c897da2f74bee2b..3eb26c5030173c36c80740c47006b5feb0d9f347 100644 (file)
@@ -339,6 +339,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "tls-creds-x509", /* 230 */
               "display",
               "intel-iommu",
+              "smm",
     );
 
 
@@ -3502,6 +3503,10 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
     if (qemuCaps->version >= 2004000)
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE);
 
+    /* smm option is supported from v2.4.0 */
+    if (qemuCaps->version >= 2004000)
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT);
+
     /* Since 2.4.50 ARM virt machine supports gic-version option */
     if (qemuCaps->version >= 2004050)
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACH_VIRT_GIC_VERSION);
@@ -4020,6 +4025,17 @@ virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
 }
 
 
+bool
+virQEMUCapsSupportsSMM(virQEMUCapsPtr qemuCaps,
+                       const virDomainDef *def)
+{
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT))
+        return false;
+
+    return qemuDomainMachineIsQ35(def);
+}
+
+
 bool
 virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps,
                               const char *canonical_machine)
index 72e763abec32a79fdf26dbbc67742adb760eb171..3a1aa52d3c4b0418426503d995746396193a7037 100644 (file)
@@ -372,6 +372,7 @@ typedef enum {
     QEMU_CAPS_OBJECT_TLS_CREDS_X509, /* -object tls-creds-x509 */
     QEMU_CAPS_DISPLAY, /* -display */
     QEMU_CAPS_DEVICE_INTEL_IOMMU, /* -device intel-iommu */
+    QEMU_CAPS_MACHINE_SMM_OPT, /* -machine xxx,smm=on/off/auto */
 
     QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
@@ -408,6 +409,9 @@ bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
 bool virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
                                const virDomainDef *def);
 
+bool virQEMUCapsSupportsSMM(virQEMUCapsPtr qemuCaps,
+                            const virDomainDef *def);
+
 char *virQEMUCapsFlagsString(virQEMUCapsPtr qemuCaps);
 
 const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps);
index 6f909172b9a1e75e27ef0352a3e45fd0aea8d114..159d78a1bc7161832366359c7353f4a61dace943 100644 (file)
@@ -6970,6 +6970,7 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
         }
     } else {
         virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT];
+        virTristateSwitch smm = def->features[VIR_DOMAIN_FEATURE_SMM];
 
         virCommandAddArg(cmd, "-machine");
         virBufferAdd(&buf, def->os.machine, -1);
@@ -6999,6 +7000,17 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
                               virTristateSwitchTypeToString(vmport));
         }
 
+        if (smm) {
+            if (!virQEMUCapsSupportsSMM(qemuCaps, def)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("smm is not available with this QEMU binary"));
+                goto cleanup;
+            }
+
+            virBufferAsprintf(&buf, ",smm=%s",
+                              virTristateSwitchTypeToString(smm));
+        }
+
         if (def->mem.dump_core) {
             if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
index 80085d562327b5828f8e0e5e38282e7695323a26..339ee1fe145e3286979f2e154e2b69a1357b44c9 100644 (file)
   <flag name='drive-detect-zeroes'/>
   <flag name='display'/>
   <flag name='intel-iommu'/>
+  <flag name='smm'/>
   <version>2004000</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
index fad3291b89eb0547d2983467c1710786f599bc65..c1a68d085a77701dec7734cdcf8f21fdfb491b98 100644 (file)
   <flag name='tls-creds-x509'/>
   <flag name='display'/>
   <flag name='intel-iommu'/>
+  <flag name='smm'/>
   <version>2005000</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
index 4ed88bc97bf08e76463454420e8166c47adb8846..85d7d3fbf9edb88778bcc4e42b4e2d364fe3b333 100644 (file)
   <flag name='drive-detect-zeroes'/>
   <flag name='tls-creds-x509'/>
   <flag name='display'/>
+  <flag name='smm'/>
   <version>2005094</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
index 024596d3049a16fe997092c5f978e4114ae3ea7a..deb12577e34133429fd02779311188dbcacb40cb 100644 (file)
   <flag name='drive-detect-zeroes'/>
   <flag name='tls-creds-x509'/>
   <flag name='display'/>
+  <flag name='smm'/>
   <version>2005094</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
index e66433c2c5e753ac366843b016419c5d02cc159c..2b7ea0e8cc8c42ea259ca8c49d777df9119521b4 100644 (file)
   <flag name='drive-detect-zeroes'/>
   <flag name='tls-creds-x509'/>
   <flag name='display'/>
+  <flag name='smm'/>
   <version>2005094</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
index 653ec7511a499019e6d294046b3e4deffa486993..495c1140b177426e3fd64287790dec3b9a43c4da 100644 (file)
   <flag name='tls-creds-x509'/>
   <flag name='display'/>
   <flag name='intel-iommu'/>
+  <flag name='smm'/>
   <version>2006000</version>
   <kvmVersion>0</kvmVersion>
   <package></package>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args b/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.args
new file mode 100644 (file)
index 0000000..e49d7e9
--- /dev/null
@@ -0,0 +1,25 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-machine q35,accel=tcg,smm=on \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
+-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
+-device virtio-scsi-pci,id=scsi0,bus=pci.2,addr=0x1 \
+-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-scsi0-0-0-0 \
+-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
+drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x2
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-smm-opt.xml
new file mode 100644 (file)
index 0000000..b964b5e
--- /dev/null
@@ -0,0 +1,28 @@
+<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'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='q35'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <smm state='on'/>
+  </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>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 751d6925330e93d18f9641d245da40e67d09584a..bdf15d4042ba42a468180c4e9dac6fc87e014710 100644 (file)
@@ -618,6 +618,13 @@ mymain(void)
             QEMU_CAPS_DUMP_GUEST_CORE);
     DO_TEST_FAILURE("machine-core-on", NONE);
     DO_TEST_FAILURE("machine-core-on", QEMU_CAPS_MACHINE_OPT);
+    DO_TEST("machine-smm-opt",
+            QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+            QEMU_CAPS_DEVICE_PCI_BRIDGE,
+            QEMU_CAPS_ICH9_AHCI,
+            QEMU_CAPS_MACHINE_OPT,
+            QEMU_CAPS_MACHINE_SMM_OPT,
+            QEMU_CAPS_VIRTIO_SCSI);
     DO_TEST("machine-usb-opt", QEMU_CAPS_MACHINE_OPT,
             QEMU_CAPS_MACHINE_USB_OPT);
     DO_TEST("machine-vmport-opt", QEMU_CAPS_MACHINE_OPT,