[PATCH 01/12] conf: Add support for external swtpm TPM emulator to domain XML

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds support for an external swtpm TPM emulator. The XML for
this type of TPM looks as follows:

 <tpm model='tpm-tis'>
   <backend type='emulator'/>
 </tpm>

The XML will currently only define a TPM 1.2.

Extend the documentation.

Add a test case testing the XML parser and formatter.

Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx>
Reviewed-by: John Ferlan <jferlan@xxxxxxxxxx>
---
 docs/formatdomain.html.in                 | 30 +++++++++++++++++++++++++++
 docs/schemas/domaincommon.rng             |  5 +++++
 src/conf/domain_audit.c                   |  2 ++
 src/conf/domain_conf.c                    | 28 +++++++++++++++++++------
 src/conf/domain_conf.h                    |  6 ++++++
 src/qemu/qemu_cgroup.c                    |  1 +
 src/qemu/qemu_command.c                   |  1 +
 src/qemu/qemu_domain.c                    |  1 +
 src/security/security_dac.c               |  2 ++
 src/security/security_selinux.c           |  2 ++
 tests/qemuxml2argvdata/tpm-emulator.xml   | 30 +++++++++++++++++++++++++++
 tests/qemuxml2xmloutdata/tpm-emulator.xml | 34 +++++++++++++++++++++++++++++++
 tests/qemuxml2xmltest.c                   |  1 +
 13 files changed, 137 insertions(+), 6 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/tpm-emulator.xml
 create mode 100644 tests/qemuxml2xmloutdata/tpm-emulator.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0d0fd3b9f3..08a57bd751 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -7704,6 +7704,26 @@ qemu-kvm -net nic,model=? /dev/null
   &lt;/tpm&gt;
 &lt;/devices&gt;
 ...
+</pre>
+
+    <p>
+      The emulator device type gives access to a TPM emulator providing
+      TPM functionlity for each VM. QEMU talks to it over a Unix socket. With
+      the emulator device type each guest gets its own private TPM.
+      <span class="since">'emulator' since 4.4.0</span>
+    </p>
+    <p>
+     Example: usage of the TPM Emulator
+    </p>
+<pre>
+  ...
+  &lt;devices&gt;
+    &lt;tpm model='tpm-tis'&gt;
+      &lt;backend type='emulator'&gt;
+      &lt;/backend&gt;
+    &lt;/tpm&gt;
+  &lt;/devices&gt;
+  ...
 </pre>
     <dl>
       <dt><code>model</code></dt>
@@ -7738,6 +7758,16 @@ qemu-kvm -net nic,model=? /dev/null
             </p>
           </dd>
         </dl>
+        <dl>
+          <dt><code>emulator</code></dt>
+          <dd>
+            <p>
+              For this backend type the 'swtpm' TPM Emulator must be installed on the
+              host. Libvirt will automatically start an independent TPM emulator
+              for each QEMU guest requesting access to it.
+            </p>
+          </dd>
+        </dl>
       </dd>
     </dl>
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 71ac3d079c..3582cb5019 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4124,6 +4124,11 @@
           </attribute>
           <ref name="tpm-passthrough-device"/>
         </group>
+        <group>
+          <attribute name="type">
+             <value>emulator</value>
+          </attribute>
+        </group>
       </choice>
     </element>
   </define>
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 82868bca76..25cccddb56 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -586,6 +586,8 @@ virDomainAuditTPM(virDomainObjPtr vm, virDomainTPMDefPtr tpm,
                   "virt=%s resrc=dev reason=%s %s uuid=%s %s",
                   virt, reason, vmname, uuidstr, device);
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+        break;
     case VIR_DOMAIN_TPM_TYPE_LAST:
     default:
         break;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3689ac0a82..15dd490d17 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -864,7 +864,8 @@ VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST,
               "tpm-crb")
 
 VIR_ENUM_IMPL(virDomainTPMBackend, VIR_DOMAIN_TPM_TYPE_LAST,
-              "passthrough")
+              "passthrough",
+              "emulator")
 
 VIR_ENUM_IMPL(virDomainIOMMUModel, VIR_DOMAIN_IOMMU_MODEL_LAST,
               "intel")
@@ -2601,6 +2602,11 @@ void virDomainTPMDefFree(virDomainTPMDefPtr def)
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
         VIR_FREE(def->data.passthrough.source.data.file.path);
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+        virDomainChrSourceDefClear(&def->data.emulator.source);
+        VIR_FREE(def->data.emulator.storagepath);
+        VIR_FREE(def->data.emulator.logfile);
+        break;
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
@@ -12648,6 +12654,11 @@ virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt,
  *   </backend>
  * </tpm>
  *
+ * or like this:
+ *
+ * <tpm model='tpm-tis'>
+ *   <backend type='emulator'/>
+ * </tpm>
  */
 static virDomainTPMDefPtr
 virDomainTPMDefParseXML(virDomainXMLOptionPtr xmlopt,
@@ -12714,6 +12725,8 @@ virDomainTPMDefParseXML(virDomainXMLOptionPtr xmlopt,
         def->data.passthrough.source.type = VIR_DOMAIN_CHR_TYPE_DEV;
         path = NULL;
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+        break;
     case VIR_DOMAIN_TPM_TYPE_LAST:
         goto error;
     }
@@ -24925,22 +24938,25 @@ virDomainTPMDefFormat(virBufferPtr buf,
     virBufferAsprintf(buf, "<tpm model='%s'>\n",
                       virDomainTPMModelTypeToString(def->model));
     virBufferAdjustIndent(buf, 2);
-    virBufferAsprintf(buf, "<backend type='%s'>\n",
+    virBufferAsprintf(buf, "<backend type='%s'",
                       virDomainTPMBackendTypeToString(def->type));
-    virBufferAdjustIndent(buf, 2);
 
     switch (def->type) {
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        virBufferAddLit(buf, ">\n");
+        virBufferAdjustIndent(buf, 2);
         virBufferEscapeString(buf, "<device path='%s'/>\n",
                               def->data.passthrough.source.data.file.path);
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</backend>\n");
+        break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+        virBufferAddLit(buf, "/>\n");
         break;
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
 
-    virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</backend>\n");
-
     virDomainDeviceInfoFormat(buf, &def->info, flags);
 
     virBufferAdjustIndent(buf, -2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a78fdee40c..92466278ab 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1286,6 +1286,7 @@ typedef enum {
 
 typedef enum {
     VIR_DOMAIN_TPM_TYPE_PASSTHROUGH,
+    VIR_DOMAIN_TPM_TYPE_EMULATOR,
 
     VIR_DOMAIN_TPM_TYPE_LAST
 } virDomainTPMBackendType;
@@ -1300,6 +1301,11 @@ struct _virDomainTPMDef {
         struct {
             virDomainChrSourceDef source;
         } passthrough;
+        struct {
+            virDomainChrSourceDef source;
+            char *storagepath;
+            char *logfile;
+        } emulator;
     } data;
 };
 
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 546a4c8e63..54b00a5da5 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -305,6 +305,7 @@ qemuSetupTPMCgroup(virDomainObjPtr vm)
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
         ret = qemuSetupChrSourceCgroup(vm, &dev->data.passthrough.source);
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9da2d609e8..fe6d0912cb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9482,6 +9482,7 @@ qemuBuildTPMBackendStr(const virDomainDef *def,
         VIR_FREE(cancel_path);
 
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         goto error;
     }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d3beee5d87..ca5b2c3485 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10418,6 +10418,7 @@ qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg ATTRIBUTE_UNUSED,
             return -1;
         break;
 
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         /* nada */
         break;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8938e2dd89..3ab229992a 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1372,6 +1372,7 @@ virSecurityDACSetTPMFileLabel(virSecurityManagerPtr mgr,
                                             &tpm->data.passthrough.source,
                                             false);
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
@@ -1393,6 +1394,7 @@ virSecurityDACRestoreTPMFileLabel(virSecurityManagerPtr mgr,
                                                 &tpm->data.passthrough.source,
                                                 false);
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5f74ef739b..5d20fdae70 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1472,6 +1472,7 @@ virSecuritySELinuxSetTPMFileLabel(virSecurityManagerPtr mgr,
             return -1;
         }
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
@@ -1505,6 +1506,7 @@ virSecuritySELinuxRestoreTPMFileLabelInt(virSecurityManagerPtr mgr,
             VIR_FREE(cancel_path);
         }
         break;
+    case VIR_DOMAIN_TPM_TYPE_EMULATOR:
     case VIR_DOMAIN_TPM_TYPE_LAST:
         break;
     }
diff --git a/tests/qemuxml2argvdata/tpm-emulator.xml b/tests/qemuxml2argvdata/tpm-emulator.xml
new file mode 100644
index 0000000000..7f1e5756cb
--- /dev/null
+++ b/tests/qemuxml2argvdata/tpm-emulator.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>TPM-VM</name>
+  <uuid>11d7cd22-da89-3094-6212-079a48a309a1</uuid>
+  <memory unit='KiB'>2097152</memory>
+  <currentMemory unit='KiB'>512288</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <tpm model='tpm-tis'>
+      <backend type='emulator'/>
+    </tpm>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/tpm-emulator.xml b/tests/qemuxml2xmloutdata/tpm-emulator.xml
new file mode 100644
index 0000000000..1b66e8b08a
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/tpm-emulator.xml
@@ -0,0 +1,34 @@
+<domain type='qemu'>
+  <name>TPM-VM</name>
+  <uuid>11d7cd22-da89-3094-6212-079a48a309a1</uuid>
+  <memory unit='KiB'>2097152</memory>
+  <currentMemory unit='KiB'>512288</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type>
+    <boot dev='hd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <tpm model='tpm-tis'>
+      <backend type='emulator'/>
+    </tpm>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 7cedc2b999..3068e92ee6 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -675,6 +675,7 @@ mymain(void)
     DO_TEST("disk-copy_on_read", NONE);
     DO_TEST("tpm-passthrough", NONE);
     DO_TEST("tpm-passthrough-crb", NONE);
+    DO_TEST("tpm-emulator", NONE);
 
     DO_TEST("metadata", NONE);
     DO_TEST("metadata-duplicate", NONE);
-- 
2.14.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux