[PATCH v2 0/8] Introducing TPM Proxy device support for PPC64

Changes in v2: In this second spin, instead of adding a new Libvirt device, the pSeries TPM Proxy device is at its core a regular TPM passthrough device. What makes it different is that it has its own domain pointer called 'tpmproxy' and it has its own restriction of 'only one TPM Proxy per domain'. This means that the combination of TPM Proxy and another TPM model/type is supported. No changes to the existing non-proxy TPM support was made. This change of design affected all patches but patch 02. Other changes: - even more unit tests added to make sure we're not messing with things we shouldn't - more descriptive commit messages to make it clearer the intention/use case of the TPM Proxy device and how it interacts with the existing TPM models. v1 link: https://www.redhat.com/archives/libvir-list/2020-May/msg00351.html Daniel Henrique Barboza (8): docs: documentation and schema for the new TPM Proxy model qemu: Extend QEMU capabilities with 'spapr-tpm-proxy' conf, qemu: adding 'tpmproxy' in domain definition domain_conf.c: XML parsing for VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY tests: add XML schema tests for the TPM Proxy device qemu: build command line for the TPM Proxy device tests/qemuxml2argvtest.c: add TPM Proxy command line tests docs/news.xml: update for the new TPM Proxy device docs/formatdomain.html.in | 16 ++++- docs/news.xml | 15 +++++ docs/schemas/domaincommon.rng | 1 + src/conf/domain_audit.c | 3 + src/conf/domain_conf.c | 65 +++++++++++++++++-- src/conf/domain_conf.h | 2 + src/qemu/qemu_alias.c | 16 +++++ src/qemu/qemu_capabilities.c | 4 ++ src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_cgroup.c | 12 +++- src/qemu/qemu_command.c | 21 ++++++ src/qemu/qemu_domain.c | 9 +-- src/qemu/qemu_validate.c | 12 ++++ src/security/security_dac.c | 14 ++++ src/security/security_selinux.c | 11 ++++ .../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 + .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + tests/qemuxml2argvdata/ppc64-tpm-double.xml | 34 ++++++++++ .../ppc64-tpmproxy-double.xml | 38 +++++++++++ .../ppc64-tpmproxy-single.ppc64-latest.args | 34 ++++++++++ .../ppc64-tpmproxy-single.xml | 33 ++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.args | 37 +++++++++++ .../ppc64-tpmproxy-with-tpm.xml | 36 ++++++++++ tests/qemuxml2argvtest.c | 15 +++++ .../ppc64-tpmproxy-single.ppc64-latest.xml | 42 ++++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.xml | 46 +++++++++++++ tests/qemuxml2xmltest.c | 2 + 27 files changed, 511 insertions(+), 12 deletions(-) create mode 100644 tests/qemuxml2argvdata/ppc64-tpm-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml -- 2.26.2

QEMU 4.1.0 introduced a new device type called TPM Proxy, currently implemented by PPC64 guests via a new virtual device called 'spapr-tpm-proxy' (see QEMU 0fb6bd073230 for more info). The TPM Proxy device interacts with a TPM Resource Manager, a host device capable of multiplexing the host TPM with multiple processes. This allows multiple guests to access some TPM features at the same time. Note that this mode of operation does not provide full TPM features to be available for the guest - for that case the guest still needs to assign a vTPM device (tpm-spapr for PPC64 guests). Although redundant, there is currently no technical limitation for a guest to assign both a vTPM and a TPM Proxy at the same time. This patch adds documentation and schema for a new TPM model type called 'spapr-tpm-proxy' that creates this new TPM Proxy device. This model is valid only for the 'passthrough' backend. An example of a TPM Proxy device connected to a TPM Resource Manager '/dev/tpmrm0' will look like this: <tpm model='spapr-tpm-proxy'> <backend type='passthrough'> <device path='/dev/tpmrm0'/> </backend> </tpm> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.html.in | 16 +++++++++++++++- docs/schemas/domaincommon.rng | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 23eb029234..ccbb696058 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8792,6 +8792,15 @@ qemu-kvm -net nic,model=? /dev/null backend device is a TPM 2.0. <span class="since">Since 6.1.0</span>, pSeries guests on PPC64 are supported and the default is <code>tpm-spapr</code>. + + <span class="since">Since 6.4.0</span>, a new model called + <code>spapr-tpm-proxy</code> was added for pSeries guests. This model + only works with the 'passthrough' backend. It creates a TPM Proxy + device that allows a QEMU guest to interact with an existing TPM Resource + Manager in the host, for example /dev/tpmrm0. A TPM Resource Manager + enables the host TPM device to be securely multiplexed across + several guests. Only one TPM Proxy device is allowed per guest, but + a TPM Proxy device can be added together with other TPM devices. </p> </dd> <dt><code>backend</code></dt> @@ -8804,7 +8813,7 @@ qemu-kvm -net nic,model=? /dev/null <dt><code>passthrough</code></dt> <dd> <p> - Use the host's TPM device. + Use the host's TPM or TPM Resource Manager device. </p> <p> This backend type requires exclusive access to a TPM device on @@ -8812,6 +8821,11 @@ qemu-kvm -net nic,model=? /dev/null qualified file name is specified by path attribute of the <code>source</code> element. If no file name is specified then /dev/tpm0 is automatically used. + + <span class="since">Since 6.4.0</span>, when choosing the + <code>spapr-tpm-proxy</code> model, the file name specified is + expected to be a TPM Resource Manager device, e.g. + /dev/tpmrm0. </p> </dd> </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9d60b090f3..50860419c3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4610,6 +4610,7 @@ <value>tpm-tis</value> <value>tpm-crb</value> <value>tpm-spapr</value> + <value>spapr-tpm-proxy</value> </choice> </attribute> </optional> -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
QEMU 4.1.0 introduced a new device type called TPM Proxy, currently implemented by PPC64 guests via a new virtual device called 'spapr-tpm-proxy' (see QEMU 0fb6bd073230 for more info).
The TPM Proxy device interacts with a TPM Resource Manager, a host device capable of multiplexing the host TPM with multiple processes. This allows multiple guests to access some TPM features at the same time. Note that this mode of operation does not provide full TPM features to be available for the guest - for that case the guest still needs to assign a vTPM device (tpm-spapr for PPC64 guests). Although redundant, there is currently no technical limitation for a guest to assign both a vTPM and a TPM Proxy at the same time.
This patch adds documentation and schema for a new TPM model type called 'spapr-tpm-proxy' that creates this new TPM Proxy device. This model is valid only for the 'passthrough' backend. An example of a TPM Proxy device connected to a TPM Resource Manager '/dev/tpmrm0' will look like this:
<tpm model='spapr-tpm-proxy'> <backend type='passthrough'> <device path='/dev/tpmrm0'/> </backend> </tpm>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.html.in | 16 +++++++++++++++- docs/schemas/domaincommon.rng | 1 + 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 23eb029234..ccbb696058 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8792,6 +8792,15 @@ qemu-kvm -net nic,model=? /dev/null backend device is a TPM 2.0. <span class="since">Since 6.1.0</span>, pSeries guests on PPC64 are supported and the default is <code>tpm-spapr</code>. + + <span class="since">Since 6.4.0</span>, a new model called + <code>spapr-tpm-proxy</code> was added for pSeries guests. This model
I think you should mention its application is restricted to 'secure VM' here since this seems to be what it is used for. A normal 'pSeries guest' won't make use of it, or would it?
+ only works with the 'passthrough' backend. It creates a TPM Proxy + device that allows a QEMU guest to interact with an existing TPM Resource + Manager in the host, for example /dev/tpmrm0. A TPM Resource Manager + enables the host TPM device to be securely multiplexed across + several guests. Only one TPM Proxy device is allowed per guest, but + a TPM Proxy device can be added together with other TPM devices. </p> </dd> <dt><code>backend</code></dt> @@ -8804,7 +8813,7 @@ qemu-kvm -net nic,model=? /dev/null <dt><code>passthrough</code></dt> <dd> <p> - Use the host's TPM device. + Use the host's TPM or TPM Resource Manager device. </p> <p> This backend type requires exclusive access to a TPM device on @@ -8812,6 +8821,11 @@ qemu-kvm -net nic,model=? /dev/null qualified file name is specified by path attribute of the <code>source</code> element. If no file name is specified then /dev/tpm0 is automatically used. + + <span class="since">Since 6.4.0</span>, when choosing the + <code>spapr-tpm-proxy</code> model, the file name specified is + expected to be a TPM Resource Manager device, e.g. + /dev/tpmrm0. </p> </dd> </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9d60b090f3..50860419c3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4610,6 +4610,7 @@ <value>tpm-tis</value> <value>tpm-crb</value> <value>tpm-spapr</value> + <value>spapr-tpm-proxy</value> </choice> </attribute> </optional>

On 5/13/20 11:28 AM, Stefan Berger wrote:
On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
QEMU 4.1.0 introduced a new device type called TPM Proxy, currently implemented by PPC64 guests via a new virtual device called 'spapr-tpm-proxy' (see QEMU 0fb6bd073230 for more info).
The TPM Proxy device interacts with a TPM Resource Manager, a host device capable of multiplexing the host TPM with multiple processes. This allows multiple guests to access some TPM features at the same time. Note that this mode of operation does not provide full TPM features to be available for the guest - for that case the guest still needs to assign a vTPM device (tpm-spapr for PPC64 guests). Although redundant, there is currently no technical limitation for a guest to assign both a vTPM and a TPM Proxy at the same time.
This patch adds documentation and schema for a new TPM model type called 'spapr-tpm-proxy' that creates this new TPM Proxy device. This model is valid only for the 'passthrough' backend. An example of a TPM Proxy device connected to a TPM Resource Manager '/dev/tpmrm0' will look like this:
<tpm model='spapr-tpm-proxy'> <backend type='passthrough'> <device path='/dev/tpmrm0'/> </backend> </tpm>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.html.in | 16 +++++++++++++++- docs/schemas/domaincommon.rng | 1 + 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 23eb029234..ccbb696058 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8792,6 +8792,15 @@ qemu-kvm -net nic,model=? /dev/null backend device is a TPM 2.0. <span class="since">Since 6.1.0</span>, pSeries guests on PPC64 are supported and the default is <code>tpm-spapr</code>. + + <span class="since">Since 6.4.0</span>, a new model called + <code>spapr-tpm-proxy</code> was added for pSeries guests. This model
I think you should mention its application is restricted to 'secure VM' here since this seems to be what it is used for. A normal 'pSeries guest' won't make use of it, or would it?
What about this: <span class="since">Since 6.4.0</span>, a new model called <code>spapr-tpm-proxy</code> was added for pSeries guests. This model only works with the 'passthrough' backend. It creates a TPM Proxy device that communicates with an existing TPM Resource Manager in the host, for example /dev/tpmrm0, to enable secure VM support for the guest. Only one TPM Proxy device is allowed per guest, but a TPM Proxy device can be added together with other TPM devices. I cut down the bit about what the TPM Resource Manager does to emphasize the intended use of the device. Thanks, DHB

On 5/13/20 11:30 AM, Daniel Henrique Barboza wrote:
On 5/13/20 11:28 AM, Stefan Berger wrote:
On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
QEMU 4.1.0 introduced a new device type called TPM Proxy, currently implemented by PPC64 guests via a new virtual device called 'spapr-tpm-proxy' (see QEMU 0fb6bd073230 for more info).
The TPM Proxy device interacts with a TPM Resource Manager, a host device capable of multiplexing the host TPM with multiple processes. This allows multiple guests to access some TPM features at the same time. Note that this mode of operation does not provide full TPM features to be available for the guest - for that case the guest still needs to assign a vTPM device (tpm-spapr for PPC64 guests). Although redundant, there is currently no technical limitation for a guest to assign both a vTPM and a TPM Proxy at the same time.
This patch adds documentation and schema for a new TPM model type called 'spapr-tpm-proxy' that creates this new TPM Proxy device. This model is valid only for the 'passthrough' backend. An example of a TPM Proxy device connected to a TPM Resource Manager '/dev/tpmrm0' will look like this:
<tpm model='spapr-tpm-proxy'> <backend type='passthrough'> <device path='/dev/tpmrm0'/> </backend> </tpm>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/formatdomain.html.in | 16 +++++++++++++++- docs/schemas/domaincommon.rng | 1 + 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 23eb029234..ccbb696058 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8792,6 +8792,15 @@ qemu-kvm -net nic,model=? /dev/null backend device is a TPM 2.0. <span class="since">Since 6.1.0</span>, pSeries guests on PPC64 are supported and the default is <code>tpm-spapr</code>. + + <span class="since">Since 6.4.0</span>, a new model called + <code>spapr-tpm-proxy</code> was added for pSeries guests. This model
I think you should mention its application is restricted to 'secure VM' here since this seems to be what it is used for. A normal 'pSeries guest' won't make use of it, or would it?
What about this:
<span class="since">Since 6.4.0</span>, a new model called <code>spapr-tpm-proxy</code> was added for pSeries guests. This model only works with the 'passthrough' backend. It creates a TPM Proxy device that communicates with an existing TPM Resource Manager in the host, for example /dev/tpmrm0, to enable secure VM support for the guest. Only one TPM Proxy device is allowed per guest, but a TPM Proxy device can be added together with other TPM devices.
I cut down the bit about what the TPM Resource Manager does to emphasize the intended use of the device.
I think users need to understand that a pSeries guest will not benefit from this but only a pSeries guest that is a secure virtual machine that needs special hardware to run and where there is an Ultravisor. Everyone would want more security for their pSeries guest, especially if it comes for free. Unfortunately this is not the case and one needs new hardware...
Thanks,
DHB

On 5/13/20 12:45 PM, Stefan Berger wrote: [...]
I think users need to understand that a pSeries guest will not benefit from this but only a pSeries guest that is a secure virtual machine that needs special hardware to run and where there is an Ultravisor. Everyone would want more security for their pSeries guest, especially if it comes for free. Unfortunately this is not the case and one needs new hardware...
True. I propose this wording: <span class="since">Since 6.4.0</span>, a new model called <code>spapr-tpm-proxy</code> was added for pSeries guests. This model only works with the 'passthrough' backend. It creates a TPM Proxy device that communicates with an existing TPM Resource Manager in the host, for example /dev/tpmrm0, to enable secure virtual machine support for the guest with the help of an Ultravisor. Adding a TPM Proxy to a pSeries guest brings no security benefits unless the guest is running in a PPC64 host that has Ultravisor support and access to a TPM Resource Manager. Only one TPM Proxy device is allowed per guest, but a TPM Proxy device can be added together with other TPM devices. If you agree, I'll use a similar text in the news.xml changes (patch 8/8) as well. Thanks, DHB
Thanks,
DHB

On 5/13/20 12:49 PM, Daniel Henrique Barboza wrote:
On 5/13/20 12:45 PM, Stefan Berger wrote: [...]
I think users need to understand that a pSeries guest will not benefit from this but only a pSeries guest that is a secure virtual machine that needs special hardware to run and where there is an Ultravisor. Everyone would want more security for their pSeries guest, especially if it comes for free. Unfortunately this is not the case and one needs new hardware...
True. I propose this wording:
<span class="since">Since 6.4.0</span>, a new model called <code>spapr-tpm-proxy</code> was added for pSeries guests. This model only works with the 'passthrough' backend. It creates a TPM Proxy device that communicates with an existing TPM Resource Manager in the host, for example /dev/tpmrm0, to enable secure virtual machine support for the guest with the help of an Ultravisor. Adding a TPM Proxy to a pSeries guest brings no security benefits unless the guest is running in a PPC64 host that
in -> on
has Ultravisor support and access to a TPM Resource Manager. Only one TPM Proxy device is allowed per guest, but a TPM Proxy device can be added together with other TPM devices.
If you agree, I'll use a similar text in the news.xml changes (patch 8/8) as well.
I would agree to this.
Thanks,
DHB
Thanks,
DHB

Expose the TPM Proxy support for PPC64 guests by creating a new cap called QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY. This device is part of the machinery the guest need to orchestrate with the PPC64 Ultravisor the transition to the Secure VM (SVM) mode. Inside QEMU, this device will be used with the H_TPM_COMM hypercall to connect with the TPM Resource Manager, enabling the guest to open and close TPM sessions with the host TPM. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + 4 files changed, 9 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7e711f22f8..d0d8b1ebf5 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -582,6 +582,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "tcg", "virtio-blk-pci.scsi.default.disabled", "pvscsi", + + /* 370 */ + "spapr-tpm-proxy", ); @@ -1304,6 +1307,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS }, { "tcg-accel", QEMU_CAPS_TCG }, { "pvscsi", QEMU_CAPS_SCSI_PVSCSI }, + { "spapr-tpm-proxy", QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 6bfc7386e3..fa22856e12 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -564,6 +564,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED, /* virtio-blk-pci.scsi disabled by default */ QEMU_CAPS_SCSI_PVSCSI, /* -device pvscsi */ + /* 370 */ + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY, /* -device spapr-tpm-proxy */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml index a68786ddc8..9df68ebfc1 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml @@ -185,6 +185,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='spapr-tpm-proxy'/> <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index c8cc07d954..77f51fe4d8 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -201,6 +201,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='spapr-tpm-proxy'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion> -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
Expose the TPM Proxy support for PPC64 guests by creating a new cap called QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY.
This device is part of the machinery the guest need to orchestrate with the PPC64 Ultravisor the transition to the Secure VM (SVM) mode. Inside QEMU, this device will be used with the H_TPM_COMM hypercall to connect with the TPM Resource Manager, enabling the guest to open and close TPM sessions with the host TPM.
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
--- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 1 + 4 files changed, 9 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 7e711f22f8..d0d8b1ebf5 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -582,6 +582,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "tcg", "virtio-blk-pci.scsi.default.disabled", "pvscsi", + + /* 370 */ + "spapr-tpm-proxy", );
@@ -1304,6 +1307,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS }, { "tcg-accel", QEMU_CAPS_TCG }, { "pvscsi", QEMU_CAPS_SCSI_PVSCSI }, + { "spapr-tpm-proxy", QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY }, };
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 6bfc7386e3..fa22856e12 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -564,6 +564,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED, /* virtio-blk-pci.scsi disabled by default */ QEMU_CAPS_SCSI_PVSCSI, /* -device pvscsi */
+ /* 370 */ + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY, /* -device spapr-tpm-proxy */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml index a68786ddc8..9df68ebfc1 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml @@ -185,6 +185,7 @@ <flag name='machine.pseries.cap-ibs'/> <flag name='tcg'/> <flag name='pvscsi'/> + <flag name='spapr-tpm-proxy'/> <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml index c8cc07d954..77f51fe4d8 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml @@ -201,6 +201,7 @@ <flag name='tcg'/> <flag name='virtio-blk-pci.scsi.default.disabled'/> <flag name='pvscsi'/> + <flag name='spapr-tpm-proxy'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>42900241</microcodeVersion>

A TPM Proxy device can coexist with a regular TPM. The TPM Proxy is also always a 'passthrough' device of the 'spapr-tpm-proxy' model. This patch adds a pointer to this device in the domain definition called 'tpmproxy'. This pointer is handled like the existing 'tpm' pointer of the VIR_DOMAIN_TPM_TYPE_PASSTHROUGH type. Cgroup, DAC/SELinux and qemu validation code was adapted to handle this new domain device. XML functions to parse and format this new device from/to XML will be added in the next patch, together with the logic that will guarantee the assumptions made in the first paragraph. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_audit.c | 3 +++ src/conf/domain_conf.c | 18 ++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_cgroup.c | 12 +++++++++--- src/qemu/qemu_domain.c | 9 +++++---- src/qemu/qemu_validate.c | 12 ++++++++++++ src/security/security_dac.c | 14 ++++++++++++++ src/security/security_selinux.c | 11 +++++++++++ 8 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 1b0abb21a0..4575f66e45 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -824,6 +824,9 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success) if (vm->def->tpm) virDomainAuditTPM(vm, vm->def->tpm, "start", true); + if (vm->def->tpmproxy) + virDomainAuditTPM(vm, vm->def->tpmproxy, "start", true); + for (i = 0; i < vm->def->nshmems; i++) virDomainAuditShmem(vm, vm->def->shmems[i], "start", true); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c201fc901d..01a32f62d1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1165,6 +1165,7 @@ VIR_ENUM_IMPL(virDomainTPMModel, "tpm-tis", "tpm-crb", "tpm-spapr", + "spapr-tpm-proxy", ); VIR_ENUM_IMPL(virDomainTPMBackend, @@ -3480,6 +3481,7 @@ void virDomainDefFree(virDomainDefPtr def) VIR_FREE(def->mems); virDomainTPMDefFree(def->tpm); + virDomainTPMDefFree(def->tpmproxy); for (i = 0; i < def->npanics; i++) virDomainPanicDefFree(def->panics[i]); @@ -4318,6 +4320,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def, if ((rc = cb(def, &device, &def->tpm->info, opaque)) != 0) return rc; } + if (def->tpmproxy) { + device.type = VIR_DOMAIN_DEVICE_TPM; + device.data.tpm = def->tpmproxy; + if ((rc = cb(def, &device, &def->tpmproxy->info, opaque)) != 0) + return rc; + } device.type = VIR_DOMAIN_DEVICE_PANIC; for (i = 0; i < def->npanics; i++) { device.data.panic = def->panics[i]; @@ -24344,6 +24352,16 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src, goto error; } + if (src->tpmproxy && dst->tpmproxy) { + if (!virDomainTPMDefCheckABIStability(src->tpmproxy, dst->tpmproxy)) + goto error; + } else if (src->tpmproxy || dst->tpmproxy) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Either both target and source domains or none of " + "them must have TPM Proxy device present")); + goto error; + } + if (src->nmems != dst->nmems) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target domain memory device count %zu " diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ddc75d8de2..8f178ade34 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1293,6 +1293,7 @@ typedef enum { VIR_DOMAIN_TPM_MODEL_TIS, VIR_DOMAIN_TPM_MODEL_CRB, VIR_DOMAIN_TPM_MODEL_SPAPR, + VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY, VIR_DOMAIN_TPM_MODEL_LAST } virDomainTPMModel; @@ -2628,6 +2629,7 @@ struct _virDomainDef { virDomainMemballoonDefPtr memballoon; virDomainNVRAMDefPtr nvram; virDomainTPMDefPtr tpm; + virDomainTPMDefPtr tpmproxy; virCPUDefPtr cpu; virSysinfoDefPtr sysinfo; virDomainRedirFilterDefPtr redirfilter; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2e019b64af..2ed4341655 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -333,10 +333,13 @@ qemuSetupChardevCgroupCB(virDomainDefPtr def G_GNUC_UNUSED, static int -qemuSetupTPMCgroup(virDomainObjPtr vm) +qemuSetupTPMCgroup(virDomainObjPtr vm, + virDomainTPMDefPtr dev) { int ret = 0; - virDomainTPMDefPtr dev = vm->def->tpm; + + if (!dev) + return 0; switch (dev->type) { case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: @@ -806,7 +809,10 @@ qemuSetupDevicesCgroup(virDomainObjPtr vm) vm) < 0) return -1; - if (vm->def->tpm && qemuSetupTPMCgroup(vm) < 0) + if (qemuSetupTPMCgroup(vm, vm->def->tpm) < 0) + return -1; + + if (qemuSetupTPMCgroup(vm, vm->def->tpmproxy) < 0) return -1; for (i = 0; i < vm->def->nhostdevs; i++) { diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a1b250fd0b..a344f8a0e6 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11574,11 +11574,9 @@ qemuDomainSetupAllChardevs(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED, static int qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED, - virDomainObjPtr vm, + virDomainTPMDefPtr dev, const struct qemuDomainCreateDeviceData *data) { - virDomainTPMDefPtr dev = vm->def->tpm; - if (!dev) return 0; @@ -11823,7 +11821,10 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg, if (qemuDomainSetupAllChardevs(cfg, vm, &data) < 0) goto cleanup; - if (qemuDomainSetupTPM(cfg, vm, &data) < 0) + if (qemuDomainSetupTPM(cfg, vm->def->tpm, &data) < 0) + goto cleanup; + + if (qemuDomainSetupTPM(cfg, vm->def->tpmproxy, &data) < 0) goto cleanup; if (qemuDomainSetupAllGraphics(cfg, vm, &data) < 0) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 584d1375b8..7210be3532 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3602,6 +3602,7 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH)) goto no_support; + break; case VIR_DOMAIN_TPM_TYPE_EMULATOR: @@ -3623,6 +3624,17 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, case VIR_DOMAIN_TPM_MODEL_SPAPR: flag = QEMU_CAPS_DEVICE_TPM_SPAPR; break; + case VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY: + if (!ARCH_IS_PPC64(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("TPM Proxy model %s is only available for " + "PPC64 guests"), + virDomainTPMModelTypeToString(tpm->model)); + return -1; + } + + flag = QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY; + break; case VIR_DOMAIN_TPM_MODEL_LAST: default: virReportEnumRangeError(virDomainTPMModel, tpm->model); diff --git a/src/security/security_dac.c b/src/security/security_dac.c index bdc2d7edf3..e0542d2839 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1980,6 +1980,13 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr, rc = -1; } + if (def->tpmproxy) { + if (virSecurityDACRestoreTPMFileLabel(mgr, + def, + def->tpmproxy) < 0) + rc = -1; + } + if (def->sev) { if (virSecurityDACRestoreSEVLabel(mgr, def) < 0) rc = -1; @@ -2159,6 +2166,13 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, return -1; } + if (def->tpmproxy) { + if (virSecurityDACSetTPMFileLabel(mgr, + def, + def->tpmproxy) < 0) + return -1; + } + if (def->sev) { if (virSecurityDACSetSEVLabel(mgr, def) < 0) return -1; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 9a929debe1..e80d43c0a7 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2763,6 +2763,12 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr, rc = -1; } + if (def->tpmproxy) { + if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def, + def->tpmproxy) < 0) + rc = -1; + } + struct _virSecuritySELinuxChardevCallbackData chardevData = { .mgr = mgr, .chardevStdioLogd = chardevStdioLogd @@ -3171,6 +3177,11 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr, return -1; } + if (def->tpmproxy) { + if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpmproxy) < 0) + return -1; + } + struct _virSecuritySELinuxChardevCallbackData chardevData = { .mgr = mgr, .chardevStdioLogd = chardevStdioLogd -- 2.26.2

Aside from trivial XML parsing/format changes, this patch adds additional rules for TPM device support to better accomodate all the available scenarios with the new TPM Proxy. The changes make no impact to existing domains. This means that the scenario of a domain with a single TPM device is still supported in the same way. The restriction of multiple TPM devices got alleviated to allow a TPM Proxy device to be added together with a TPM device in the same domain. All other combinations are still forbidden. To summarize, after this patch, the following combinations in the same domain are valid: - a single TPM device - a single TPM Proxy device - a single TPM + single TPM Proxy devices These combinations in the same domain are NOT allowed: - 2 or more TPM devices - 2 or more TPM Proxy devices Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01a32f62d1..33b7d69318 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13730,6 +13730,14 @@ virDomainTPMDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } + /* TPM Proxy devices have 'passthrough' backend */ + if (def->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY && + def->type != VIR_DOMAIN_TPM_TYPE_PASSTHROUGH) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'Passthrough' backend is required for TPM Proxy devices")); + goto error; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0) goto error; @@ -21972,15 +21980,41 @@ virDomainDefParseXML(xmlDocPtr xml, if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0) goto error; - if (n > 1) { + if (n > 2) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("only a single TPM device is supported")); + _("a maximum of two TPM devices is supported, one of " + "them being a TPM Proxy device")); goto error; } if (n > 0) { - if (!(def->tpm = virDomainTPMDefParseXML(xmlopt, nodes[0], ctxt, flags))) - goto error; + for (i = 0; i < n; i++) { + virDomainTPMDefPtr dev = virDomainTPMDefParseXML(xmlopt, nodes[i], ctxt, flags); + + if (!dev) + goto error; + + /* TPM Proxy devices must be held in def->tpmproxy. Error + * out if there's a TPM Proxy declared already */ + if (dev->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY) { + if (def->tpmproxy) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM Proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpmproxy = g_steal_pointer(&dev); + } else { + /* all other TPM devices goes to def->tpm */ + if (def->tpm) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM non-proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpm = g_steal_pointer(&dev); + } + } } VIR_FREE(nodes); @@ -29807,6 +29841,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, goto error; } + if (def->tpmproxy) { + if (virDomainTPMDefFormat(buf, def->tpmproxy, flags) < 0) + goto error; + } + for (n = 0; n < def->ngraphics; n++) { if (virDomainGraphicsDefFormat(buf, def->graphics[n], flags) < 0) goto error; -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
Aside from trivial XML parsing/format changes, this patch adds additional rules for TPM device support to better accomodate all the available scenarios with the new TPM Proxy.
The changes make no impact to existing domains. This means that the scenario of a domain with a single TPM device is still supported in the same way. The restriction of multiple TPM devices got alleviated to allow a TPM Proxy device to be added together with a TPM device in the same domain. All other combinations are still forbidden.
To summarize, after this patch, the following combinations in the same domain are valid:
- a single TPM device - a single TPM Proxy device - a single TPM + single TPM Proxy devices
These combinations in the same domain are NOT allowed:
- 2 or more TPM devices - 2 or more TPM Proxy devices
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01a32f62d1..33b7d69318 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13730,6 +13730,14 @@ virDomainTPMDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; }
+ /* TPM Proxy devices have 'passthrough' backend */ + if (def->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY && + def->type != VIR_DOMAIN_TPM_TYPE_PASSTHROUGH) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'Passthrough' backend is required for TPM Proxy devices")); + goto error; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0) goto error;
@@ -21972,15 +21980,41 @@ virDomainDefParseXML(xmlDocPtr xml, if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0) goto error;
- if (n > 1) { + if (n > 2) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("only a single TPM device is supported")); + _("a maximum of two TPM devices is supported, one of " + "them being a TPM Proxy device")); goto error; }
if (n > 0) { - if (!(def->tpm = virDomainTPMDefParseXML(xmlopt, nodes[0], ctxt, flags))) - goto error; + for (i = 0; i < n; i++) { + virDomainTPMDefPtr dev = virDomainTPMDefParseXML(xmlopt, nodes[i], ctxt, flags); + + if (!dev) + goto error; + + /* TPM Proxy devices must be held in def->tpmproxy. Error + * out if there's a TPM Proxy declared already */ + if (dev->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY) { + if (def->tpmproxy) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM Proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpmproxy = g_steal_pointer(&dev);
Is g_steal_pointer necessary ?
+ } else { + /* all other TPM devices goes to def->tpm */ + if (def->tpm) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM non-proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpm = g_steal_pointer(&dev); + } + } } VIR_FREE(nodes);
@@ -29807,6 +29841,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, goto error; }
+ if (def->tpmproxy) { + if (virDomainTPMDefFormat(buf, def->tpmproxy, flags) < 0) + goto error; + } + for (n = 0; n < def->ngraphics; n++) { if (virDomainGraphicsDefFormat(buf, def->graphics[n], flags) < 0) goto error;

On 5/13/20 11:35 AM, Stefan Berger wrote:
On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
Aside from trivial XML parsing/format changes, this patch adds additional rules for TPM device support to better accomodate all the available scenarios with the new TPM Proxy.
The changes make no impact to existing domains. This means that the scenario of a domain with a single TPM device is still supported in the same way. The restriction of multiple TPM devices got alleviated to allow a TPM Proxy device to be added together with a TPM device in the same domain. All other combinations are still forbidden.
To summarize, after this patch, the following combinations in the same domain are valid:
- a single TPM device - a single TPM Proxy device - a single TPM + single TPM Proxy devices
These combinations in the same domain are NOT allowed:
- 2 or more TPM devices - 2 or more TPM Proxy devices
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/conf/domain_conf.c | 47 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01a32f62d1..33b7d69318 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13730,6 +13730,14 @@ virDomainTPMDefParseXML(virDomainXMLOptionPtr xmlopt, goto error; } + /* TPM Proxy devices have 'passthrough' backend */ + if (def->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY && + def->type != VIR_DOMAIN_TPM_TYPE_PASSTHROUGH) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'Passthrough' backend is required for TPM Proxy devices")); + goto error; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0) goto error; @@ -21972,15 +21980,41 @@ virDomainDefParseXML(xmlDocPtr xml, if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0) goto error; - if (n > 1) { + if (n > 2) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("only a single TPM device is supported")); + _("a maximum of two TPM devices is supported, one of " + "them being a TPM Proxy device")); goto error; } if (n > 0) { - if (!(def->tpm = virDomainTPMDefParseXML(xmlopt, nodes[0], ctxt, flags))) - goto error; + for (i = 0; i < n; i++) { + virDomainTPMDefPtr dev = virDomainTPMDefParseXML(xmlopt, nodes[i], ctxt, flags); + + if (!dev) + goto error; + + /* TPM Proxy devices must be held in def->tpmproxy. Error + * out if there's a TPM Proxy declared already */ + if (dev->model == VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY) { + if (def->tpmproxy) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM Proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpmproxy = g_steal_pointer(&dev);
Is g_steal_pointer necessary ?
Not in this case, since the VIR_FREE() call is being done before the jump and I'm not using g_autopt() with this pointer. Thing is that we should use g_autoptr() in these scenarios to avoid the manual cleanup. Also, I don't think I can use VIR_FREE() with this pointer - I should've used virDomainTPMDefFree(). I'll change the code to using g_autoptr() and g_steal_pointer(). Thanks, DHB
+ } else { + /* all other TPM devices goes to def->tpm */ + if (def->tpm) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single TPM non-proxy device is supported")); + VIR_FREE(dev); + goto error; + } + def->tpm = g_steal_pointer(&dev); + } + } } VIR_FREE(nodes); @@ -29807,6 +29841,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, goto error; } + if (def->tpmproxy) { + if (virDomainTPMDefFormat(buf, def->tpmproxy, flags) < 0) + goto error; + } + for (n = 0; n < def->ngraphics; n++) { if (virDomainGraphicsDefFormat(buf, def->graphics[n], flags) < 0) goto error;

This tests aims to exercise how a TPM Proxy device can be added in the domain, either alone or with a regular TPM device. It also ensures that we do not allow bogus scenarios to slip by. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- tests/qemuxml2argvdata/ppc64-tpm-double.xml | 34 ++++++++++++++ .../ppc64-tpmproxy-double.xml | 38 +++++++++++++++ .../ppc64-tpmproxy-single.xml | 33 +++++++++++++ .../ppc64-tpmproxy-with-tpm.xml | 36 +++++++++++++++ tests/qemuxml2argvtest.c | 12 +++++ .../ppc64-tpmproxy-single.ppc64-latest.xml | 42 +++++++++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.xml | 46 +++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 8 files changed, 243 insertions(+) create mode 100644 tests/qemuxml2argvdata/ppc64-tpm-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml diff --git a/tests/qemuxml2argvdata/ppc64-tpm-double.xml b/tests/qemuxml2argvdata/ppc64-tpm-double.xml new file mode 100644 index 0000000000..5e077659f3 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpm-double.xml @@ -0,0 +1,34 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + </tpm> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml new file mode 100644 index 0000000000..12abda509e --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml @@ -0,0 +1,38 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml new file mode 100644 index 0000000000..729a2cdf28 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml @@ -0,0 +1,33 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml new file mode 100644 index 0000000000..a61ec9845c --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml @@ -0,0 +1,36 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 43e76956cc..ba82da5f4b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2966,6 +2966,18 @@ mymain(void) QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_QEMU_XHCI); + DO_TEST_PARSE_ERROR("ppc64-tpmproxy-double", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_PCI_OHCI, + QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY); + + DO_TEST_PARSE_ERROR("ppc64-tpm-double", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_PCI_OHCI, + QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY); + DO_TEST("aarch64-usb-controller-qemu-xhci", QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_NEC_USB_XHCI, diff --git a/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml new file mode 100644 index 0000000000..4e0e5f24b8 --- /dev/null +++ b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml @@ -0,0 +1,42 @@ +<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='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER9</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0' model='pci-ohci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml new file mode 100644 index 0000000000..2e0dab4b33 --- /dev/null +++ b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml @@ -0,0 +1,46 @@ +<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='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER9</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0' model='pci-ohci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + <address type='spapr-vio' reg='0x00004000'/> + </tpm> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 033f81013e..8360d5eeca 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -609,6 +609,8 @@ mymain(void) DO_TEST("controller-usb-order", QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4); + DO_TEST_CAPS_ARCH_LATEST("ppc64-tpmproxy-single", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("ppc64-tpmproxy-with-tpm", "ppc64"); DO_TEST_FULL("seclabel-dynamic-baselabel", WHEN_INACTIVE, ARG_QEMU_CAPS, NONE); -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
This tests aims to exercise how a TPM Proxy device can be added in the domain, either alone or with a regular TPM device. It also ensures that we do not allow bogus scenarios to slip by.
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- tests/qemuxml2argvdata/ppc64-tpm-double.xml | 34 ++++++++++++++ .../ppc64-tpmproxy-double.xml | 38 +++++++++++++++ .../ppc64-tpmproxy-single.xml | 33 +++++++++++++ .../ppc64-tpmproxy-with-tpm.xml | 36 +++++++++++++++ tests/qemuxml2argvtest.c | 12 +++++ .../ppc64-tpmproxy-single.ppc64-latest.xml | 42 +++++++++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.xml | 46 +++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 8 files changed, 243 insertions(+) create mode 100644 tests/qemuxml2argvdata/ppc64-tpm-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml
diff --git a/tests/qemuxml2argvdata/ppc64-tpm-double.xml b/tests/qemuxml2argvdata/ppc64-tpm-double.xml new file mode 100644 index 0000000000..5e077659f3 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpm-double.xml @@ -0,0 +1,34 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + </tpm> + <tpm model='tpm-spapr'>
Indentation.
+ <backend type='emulator' version='2.0'/> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml new file mode 100644 index 0000000000..12abda509e --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-double.xml @@ -0,0 +1,38 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml new file mode 100644 index 0000000000..729a2cdf28 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.xml @@ -0,0 +1,33 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml new file mode 100644 index 0000000000..a61ec9845c --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.xml @@ -0,0 +1,36 @@ +<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='ppc64' machine='pseries'>hvm</type> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 43e76956cc..ba82da5f4b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2966,6 +2966,18 @@ mymain(void) QEMU_CAPS_NEC_USB_XHCI, QEMU_CAPS_DEVICE_QEMU_XHCI);
+ DO_TEST_PARSE_ERROR("ppc64-tpmproxy-double", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_PCI_OHCI, + QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY); + + DO_TEST_PARSE_ERROR("ppc64-tpm-double", + QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, + QEMU_CAPS_PCI_OHCI, + QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, + QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY); + DO_TEST("aarch64-usb-controller-qemu-xhci", QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_NEC_USB_XHCI, diff --git a/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml new file mode 100644 index 0000000000..4e0e5f24b8 --- /dev/null +++ b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-single.ppc64-latest.xml @@ -0,0 +1,42 @@ +<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='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER9</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0' model='pci-ohci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml new file mode 100644 index 0000000000..2e0dab4b33 --- /dev/null +++ b/tests/qemuxml2xmloutdata/ppc64-tpmproxy-with-tpm.ppc64-latest.xml @@ -0,0 +1,46 @@ +<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='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>POWER9</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0' model='pci-ohci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <tpm model='tpm-spapr'> + <backend type='emulator' version='2.0'/> + <address type='spapr-vio' reg='0x00004000'/> + </tpm> + <tpm model='spapr-tpm-proxy'> + <backend type='passthrough'> + <device path='/dev/tpmrm0'/> + </backend> + </tpm> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 033f81013e..8360d5eeca 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -609,6 +609,8 @@ mymain(void) DO_TEST("controller-usb-order", QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4); + DO_TEST_CAPS_ARCH_LATEST("ppc64-tpmproxy-single", "ppc64"); + DO_TEST_CAPS_ARCH_LATEST("ppc64-tpmproxy-with-tpm", "ppc64");
DO_TEST_FULL("seclabel-dynamic-baselabel", WHEN_INACTIVE, ARG_QEMU_CAPS, NONE);
With the indentation nit fixed: Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

This patch wraps it up all the wiring done in previous patches, enabling a PPC64 guest to launch a guest using a TPM Proxy device. Note that device validation is already being done in qemu_validate.c, qemuValidateDomainDeviceDefTPM(), on domain define time. We don't need to verify QEMU capabilities for this device again inside qemu_command.c. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- src/qemu/qemu_alias.c | 16 ++++++++++++++++ src/qemu/qemu_command.c | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index b0ea62af39..08fe5aa501 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -413,6 +413,18 @@ qemuAssignDeviceTPMAlias(virDomainTPMDefPtr tpm, } +static int +qemuAssignDeviceTPMProxyAlias(virDomainTPMDefPtr tpmproxy, + int idx) +{ + if (tpmproxy->info.alias) + return 0; + + tpmproxy->info.alias = g_strdup_printf("tpmproxy%d", idx); + return 0; +} + + int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, @@ -673,6 +685,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) if (qemuAssignDeviceTPMAlias(def->tpm, 0) < 0) return -1; } + if (def->tpmproxy) { + if (qemuAssignDeviceTPMProxyAlias(def->tpmproxy, 0) < 0) + return -1; + } for (i = 0; i < def->nmems; i++) { if (qemuAssignDeviceMemoryAlias(NULL, def->mems[i], false) < 0) return -1; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bfe70ed228..0b97db7388 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8981,6 +8981,24 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, return 0; } +static int +qemuBuildTPMProxyCommandLine(virCommandPtr cmd, + const virDomainDef *def) +{ + const virDomainTPMDef *tpmproxy = def->tpmproxy; + + if (!tpmproxy) + return 0; + + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "%s,id=%s,host-path=%s", + virDomainTPMModelTypeToString(tpmproxy->model), + tpmproxy->info.alias, + tpmproxy->data.passthrough.source.data.file.path); + + return 0; +} + static int qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, virDomainSEVDefPtr sev) @@ -9662,6 +9680,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildTPMCommandLine(cmd, def, qemuCaps) < 0) return NULL; + if (qemuBuildTPMProxyCommandLine(cmd, def) < 0) + return NULL; + if (qemuBuildInputCommandLine(cmd, def, qemuCaps) < 0) return NULL; -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
This patch wraps it up all the wiring done in previous patches, enabling a PPC64 guest to launch a guest using a TPM Proxy device.
Note that device validation is already being done in qemu_validate.c, qemuValidateDomainDeviceDefTPM(), on domain define time. We don't need to verify QEMU capabilities for this device again inside qemu_command.c.
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
--- src/qemu/qemu_alias.c | 16 ++++++++++++++++ src/qemu/qemu_command.c | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+)
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index b0ea62af39..08fe5aa501 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -413,6 +413,18 @@ qemuAssignDeviceTPMAlias(virDomainTPMDefPtr tpm, }
+static int +qemuAssignDeviceTPMProxyAlias(virDomainTPMDefPtr tpmproxy, + int idx) +{ + if (tpmproxy->info.alias) + return 0; + + tpmproxy->info.alias = g_strdup_printf("tpmproxy%d", idx); + return 0; +} + + int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, @@ -673,6 +685,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) if (qemuAssignDeviceTPMAlias(def->tpm, 0) < 0) return -1; } + if (def->tpmproxy) { + if (qemuAssignDeviceTPMProxyAlias(def->tpmproxy, 0) < 0) + return -1; + } for (i = 0; i < def->nmems; i++) { if (qemuAssignDeviceMemoryAlias(NULL, def->mems[i], false) < 0) return -1; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bfe70ed228..0b97db7388 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8981,6 +8981,24 @@ qemuBuildTPMCommandLine(virCommandPtr cmd, return 0; }
+static int +qemuBuildTPMProxyCommandLine(virCommandPtr cmd, + const virDomainDef *def) +{ + const virDomainTPMDef *tpmproxy = def->tpmproxy; + + if (!tpmproxy) + return 0; + + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "%s,id=%s,host-path=%s", + virDomainTPMModelTypeToString(tpmproxy->model), + tpmproxy->info.alias, + tpmproxy->data.passthrough.source.data.file.path); + + return 0; +} + static int qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, virDomainSEVDefPtr sev) @@ -9662,6 +9680,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildTPMCommandLine(cmd, def, qemuCaps) < 0) return NULL;
+ if (qemuBuildTPMProxyCommandLine(cmd, def) < 0) + return NULL; + if (qemuBuildInputCommandLine(cmd, def, qemuCaps) < 0) return NULL;

Add tests for both supported scenarios: a single TPM Proxy and a TPM Proxy with a regular TPM device in the same domain. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- .../ppc64-tpmproxy-single.ppc64-latest.args | 34 +++++++++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.args | 37 +++++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 3 files changed, 74 insertions(+) create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args new file mode 100644 index 0000000000..f606cee16b --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pseries,accel=tcg,usb=off,dump-guest-core=off \ +-cpu POWER9 \ +-m 256 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device pci-ohci,id=usb,bus=pci.0,addr=0x1 \ +-device spapr-tpm-proxy,id=tpmproxy0,host-path=/dev/tpmrm0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args new file mode 100644 index 0000000000..9908cd78e0 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pseries,accel=tcg,usb=off,dump-guest-core=off \ +-cpu POWER9 \ +-m 256 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device pci-ohci,id=usb,bus=pci.0,addr=0x1 \ +-tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \ +-chardev socket,id=chrtpm,path=/dev/test \ +-device tpm-spapr,tpmdev=tpm-tpm0,id=tpm0,reg=0x00004000 \ +-device spapr-tpm-proxy,id=tpmproxy0,host-path=/dev/tpmrm0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ba82da5f4b..6a57a4910d 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2978,6 +2978,9 @@ mymain(void) QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY); + DO_TEST_CAPS_LATEST_PPC64("ppc64-tpmproxy-single"); + DO_TEST_CAPS_LATEST_PPC64("ppc64-tpmproxy-with-tpm"); + DO_TEST("aarch64-usb-controller-qemu-xhci", QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_NEC_USB_XHCI, -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
Add tests for both supported scenarios: a single TPM Proxy and a TPM Proxy with a regular TPM device in the same domain.
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> --- .../ppc64-tpmproxy-single.ppc64-latest.args | 34 +++++++++++++++++ .../ppc64-tpmproxy-with-tpm.ppc64-latest.args | 37 +++++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 3 files changed, 74 insertions(+) create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args create mode 100644 tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args
diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args new file mode 100644 index 0000000000..f606cee16b --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-single.ppc64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pseries,accel=tcg,usb=off,dump-guest-core=off \ +-cpu POWER9 \ +-m 256 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device pci-ohci,id=usb,bus=pci.0,addr=0x1 \ +-device spapr-tpm-proxy,id=tpmproxy0,host-path=/dev/tpmrm0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args new file mode 100644 index 0000000000..9908cd78e0 --- /dev/null +++ b/tests/qemuxml2argvdata/ppc64-tpmproxy-with-tpm.ppc64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pseries,accel=tcg,usb=off,dump-guest-core=off \ +-cpu POWER9 \ +-m 256 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device pci-ohci,id=usb,bus=pci.0,addr=0x1 \ +-tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \ +-chardev socket,id=chrtpm,path=/dev/test \ +-device tpm-spapr,tpmdev=tpm-tpm0,id=tpm0,reg=0x00004000 \ +-device spapr-tpm-proxy,id=tpmproxy0,host-path=/dev/tpmrm0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ba82da5f4b..6a57a4910d 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2978,6 +2978,9 @@ mymain(void) QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY);
+ DO_TEST_CAPS_LATEST_PPC64("ppc64-tpmproxy-single"); + DO_TEST_CAPS_LATEST_PPC64("ppc64-tpmproxy-with-tpm"); + DO_TEST("aarch64-usb-controller-qemu-xhci", QEMU_CAPS_OBJECT_GPEX, QEMU_CAPS_NEC_USB_XHCI,

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/news.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 4cef804aac..452f73479e 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -44,6 +44,21 @@ <libvirt> <release version="v6.4.0" date="unreleased"> <section title="New features"> + <change> + <summary> + qemu: add TPM Proxy device support + </summary> + <description> + libvirt can now create guests using a new device type called + "TPM Proxy". This new device type connects with a TPM Resource + Manager in the host, which allows multiple processes to access + TPM features concurrently. Only one TPM Proxy is allowed per + guest. A guest using a TPM Proxy device can instantiate another + TPM device at the same time. This device is supported only for + pSeries guests via the new 'spapr-tpm-proxy' model of the TPM + 'passthrough' backend. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.26.2

On 5/13/20 10:10 AM, Daniel Henrique Barboza wrote:
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> --- docs/news.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml index 4cef804aac..452f73479e 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -44,6 +44,21 @@ <libvirt> <release version="v6.4.0" date="unreleased"> <section title="New features"> + <change> + <summary> + qemu: add TPM Proxy device support + </summary> + <description> + libvirt can now create guests using a new device type called + "TPM Proxy". This new device type connects with a TPM Resource + Manager in the host, which allows multiple processes to access + TPM features concurrently. Only one TPM Proxy is allowed per + guest. A guest using a TPM Proxy device can instantiate another
mention secure virtual machines here?
+ TPM device at the same time. This device is supported only for + pSeries guests via the new 'spapr-tpm-proxy' model of the TPM + 'passthrough' backend. + </description> + </change> </section> <section title="Improvements"> </section>
participants (2)
-
Daniel Henrique Barboza
-
Stefan Berger