On 05/15/2018 07:49 AM, Marc Hartmayer wrote:
On Thu, May 10, 2018 at 11:57 PM +0200, Stefan Berger
<stefanb(a)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(a)linux.vnet.ibm.com>
> Reviewed-by: John Ferlan <jferlan(a)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