
On 05/15/2018 07:49 AM, Marc Hartmayer wrote:
On Thu, May 10, 2018 at 11:57 PM +0200, Stefan Berger <stefanb@linux.vnet.ibm.com> wrote:
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@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com> --- 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 | 7 +++++++ 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, 138 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 caeb14e..4f56784 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -7650,6 +7650,26 @@ qemu-kvm -net nic,model=? /dev/null </devices> ... </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> + ... + <devices> + <tpm model='tpm-tis'> + <backend type='emulator'> + </backend> + </tpm> + </devices> + ... +</pre> <dl> <dt><code>model</code></dt> <dd> @@ -7683,6 +7703,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 0a6b29b..a9a1020 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4137,6 +4137,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 82868bc..25cccdd 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 f678e26..21b66d7 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: + VIR_FREE(def->data.emulator.source.data.nix.path); Why do we not need virDomainChrSourceDefFree/virObjectUnref(&def->data.emulator.source); here? (the same applies to case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH)
The are declared as embedded structures rather than pointers. The only other similar case is Shmem. union { struct { virDomainChrSourceDef source; } passthrough; struct { virDomainChrSourceDef source; char *storagepath; char *logfile; } emulator; } data; We should call virDomainChrSourceDefClear() rather than VIR_FREE() directly. The end result is the same, though. Fixed. I will fix the passthrough case later. Stefan