aarch64 support vtpm
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
This commit is contained in:
parent
4b2cfa2a18
commit
54e09b7986
26
delete-the-in-tpm.txt.patch
Normal file
26
delete-the-in-tpm.txt.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 3020ae141ef40f06b17eb0f16d2a3c6d5872ff89 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Wed, 29 Jul 2020 08:45:50 +0000
|
||||
Subject: [PATCH 05/19] delete the in tpm.txt
|
||||
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
docs/specs/tpm.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
|
||||
index 5d8c26b1..9c8cca04 100644
|
||||
--- a/docs/specs/tpm.txt
|
||||
+++ b/docs/specs/tpm.txt
|
||||
@@ -89,7 +89,7 @@ TPM upon reboot. The PPI specification defines the operation requests and the
|
||||
actions the firmware has to take. The system administrator passes the operation
|
||||
request number to the firmware through an ACPI interface which writes this
|
||||
number to a memory location that the firmware knows. Upon reboot, the firmware
|
||||
-finds the number and sends commands to the the TPM. The firmware writes the TPM
|
||||
+finds the number and sends commands to the TPM. The firmware writes the TPM
|
||||
result code and the operation request number to a memory location that ACPI can
|
||||
read from and pass the result on to the administrator.
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
66
docs-specs-tpm-Document-TPM_TIS-sysbus-device-for-AR.patch
Normal file
66
docs-specs-tpm-Document-TPM_TIS-sysbus-device-for-AR.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From dd7f6cc3bcd71681920e3530f2c53041c812c5d3 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 5 Mar 2020 17:51:46 +0100
|
||||
Subject: [PATCH 16/19] docs/specs/tpm: Document TPM_TIS sysbus device for ARM
|
||||
|
||||
Update the documentation with recent changes related to the
|
||||
sysbus TPM_TIS device addition and add the command line
|
||||
to be used with arm VIRT.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-id: 20200305165149.618-8-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
docs/specs/tpm.rst | 25 ++++++++++++++++++++++++-
|
||||
1 file changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
|
||||
index 2bdf637f..da9eb39c 100644
|
||||
--- a/docs/specs/tpm.rst
|
||||
+++ b/docs/specs/tpm.rst
|
||||
@@ -18,9 +18,15 @@ The TIS interface makes a memory mapped IO region in the area
|
||||
0xfed40000-0xfed44fff available to the guest operating system.
|
||||
|
||||
QEMU files related to TPM TIS interface:
|
||||
- - ``hw/tpm/tpm_tis.c``
|
||||
+ - ``hw/tpm/tpm_tis_common.c``
|
||||
+ - ``hw/tpm/tpm_tis_isa.c``
|
||||
+ - ``hw/tpm/tpm_tis_sysbus.c``
|
||||
- ``hw/tpm/tpm_tis.h``
|
||||
|
||||
+Both an ISA device and a sysbus device are available. The former is
|
||||
+used with pc/q35 machine while the latter can be instantiated in the
|
||||
+ARM virt machine.
|
||||
+
|
||||
CRB interface
|
||||
-------------
|
||||
|
||||
@@ -325,6 +331,23 @@ In case a pSeries machine is emulated, use the following command line:
|
||||
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
|
||||
-drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
|
||||
|
||||
+In case an ARM virt machine is emulated, use the following command line:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-aarch64 -machine virt,gic-version=3,accel=kvm \
|
||||
+ -cpu host -m 4G \
|
||||
+ -nographic -no-acpi \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-tis-device,tpmdev=tpm0 \
|
||||
+ -device virtio-blk-pci,drive=drv0 \
|
||||
+ -drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \
|
||||
+ -drive if=pflash,format=raw,file=flash0.img,readonly \
|
||||
+ -drive if=pflash,format=raw,file=flash1.img
|
||||
+
|
||||
+ On ARM, ACPI boot with TPM is not yet supported.
|
||||
+
|
||||
In case SeaBIOS is used as firmware, it should show the TPM menu item
|
||||
after entering the menu with 'ESC'.
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
993
docs-specs-tpm-reST-ify-TPM-documentation.patch
Normal file
993
docs-specs-tpm-reST-ify-TPM-documentation.patch
Normal file
@ -0,0 +1,993 @@
|
||||
From 5d1865496ca39f08142a0c1eb2c9b14ec1ec9140 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:35 -0500
|
||||
Subject: [PATCH 09/19] docs/specs/tpm: reST-ify TPM documentation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-Id: <20200121152935.649898-7-stefanb@linux.ibm.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
docs/specs/index.rst | 1 +
|
||||
docs/specs/tpm.rst | 503 +++++++++++++++++++++++++++++++++++++++++++
|
||||
docs/specs/tpm.txt | 445 --------------------------------------
|
||||
3 files changed, 504 insertions(+), 445 deletions(-)
|
||||
create mode 100644 docs/specs/tpm.rst
|
||||
delete mode 100644 docs/specs/tpm.txt
|
||||
|
||||
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
|
||||
index 984ba440..de46a8b5 100644
|
||||
--- a/docs/specs/index.rst
|
||||
+++ b/docs/specs/index.rst
|
||||
@@ -13,3 +13,4 @@ Contents:
|
||||
ppc-xive
|
||||
ppc-spapr-xive
|
||||
acpi_hw_reduced_hotplug
|
||||
+ tpm
|
||||
diff --git a/docs/specs/tpm.rst b/docs/specs/tpm.rst
|
||||
new file mode 100644
|
||||
index 00000000..2bdf637f
|
||||
--- /dev/null
|
||||
+++ b/docs/specs/tpm.rst
|
||||
@@ -0,0 +1,503 @@
|
||||
+===============
|
||||
+QEMU TPM Device
|
||||
+===============
|
||||
+
|
||||
+Guest-side hardware interface
|
||||
+=============================
|
||||
+
|
||||
+TIS interface
|
||||
+-------------
|
||||
+
|
||||
+The QEMU TPM emulation implements a TPM TIS hardware interface
|
||||
+following the Trusted Computing Group's specification "TCG PC Client
|
||||
+Specific TPM Interface Specification (TIS)", Specification Version
|
||||
+1.3, 21 March 2013. (see the `TIS specification`_, or a later version
|
||||
+of it).
|
||||
+
|
||||
+The TIS interface makes a memory mapped IO region in the area
|
||||
+0xfed40000-0xfed44fff available to the guest operating system.
|
||||
+
|
||||
+QEMU files related to TPM TIS interface:
|
||||
+ - ``hw/tpm/tpm_tis.c``
|
||||
+ - ``hw/tpm/tpm_tis.h``
|
||||
+
|
||||
+CRB interface
|
||||
+-------------
|
||||
+
|
||||
+QEMU also implements a TPM CRB interface following the Trusted
|
||||
+Computing Group's specification "TCG PC Client Platform TPM Profile
|
||||
+(PTP) Specification", Family "2.0", Level 00 Revision 01.03 v22, May
|
||||
+22, 2017. (see the `CRB specification`_, or a later version of it)
|
||||
+
|
||||
+The CRB interface makes a memory mapped IO region in the area
|
||||
+0xfed40000-0xfed40fff (1 locality) available to the guest
|
||||
+operating system.
|
||||
+
|
||||
+QEMU files related to TPM CRB interface:
|
||||
+ - ``hw/tpm/tpm_crb.c``
|
||||
+
|
||||
+SPAPR interface
|
||||
+---------------
|
||||
+
|
||||
+pSeries (ppc64) machines offer a tpm-spapr device model.
|
||||
+
|
||||
+QEMU files related to the SPAPR interface:
|
||||
+ - ``hw/tpm/tpm_spapr.c``
|
||||
+
|
||||
+fw_cfg interface
|
||||
+================
|
||||
+
|
||||
+The bios/firmware may read the ``"etc/tpm/config"`` fw_cfg entry for
|
||||
+configuring the guest appropriately.
|
||||
+
|
||||
+The entry of 6 bytes has the following content, in little-endian:
|
||||
+
|
||||
+.. code-block:: c
|
||||
+
|
||||
+ #define TPM_VERSION_UNSPEC 0
|
||||
+ #define TPM_VERSION_1_2 1
|
||||
+ #define TPM_VERSION_2_0 2
|
||||
+
|
||||
+ #define TPM_PPI_VERSION_NONE 0
|
||||
+ #define TPM_PPI_VERSION_1_30 1
|
||||
+
|
||||
+ struct FwCfgTPMConfig {
|
||||
+ uint32_t tpmppi_address; /* PPI memory location */
|
||||
+ uint8_t tpm_version; /* TPM version */
|
||||
+ uint8_t tpmppi_version; /* PPI version */
|
||||
+ };
|
||||
+
|
||||
+ACPI interface
|
||||
+==============
|
||||
+
|
||||
+The TPM device is defined with ACPI ID "PNP0C31". QEMU builds a SSDT
|
||||
+and passes it into the guest through the fw_cfg device. The device
|
||||
+description contains the base address of the TIS interface 0xfed40000
|
||||
+and the size of the MMIO area (0x5000). In case a TPM2 is used by
|
||||
+QEMU, a TPM2 ACPI table is also provided. The device is described to
|
||||
+be used in polling mode rather than interrupt mode primarily because
|
||||
+no unused IRQ could be found.
|
||||
+
|
||||
+To support measurement logs to be written by the firmware,
|
||||
+e.g. SeaBIOS, a TCPA table is implemented. This table provides a 64kb
|
||||
+buffer where the firmware can write its log into. For TPM 2 only a
|
||||
+more recent version of the TPM2 table provides support for
|
||||
+measurements logs and a TCPA table does not need to be created.
|
||||
+
|
||||
+The TCPA and TPM2 ACPI tables follow the Trusted Computing Group
|
||||
+specification "TCG ACPI Specification" Family "1.2" and "2.0", Level
|
||||
+00 Revision 00.37. (see the `ACPI specification`_, or a later version
|
||||
+of it)
|
||||
+
|
||||
+ACPI PPI Interface
|
||||
+------------------
|
||||
+
|
||||
+QEMU supports the Physical Presence Interface (PPI) for TPM 1.2 and
|
||||
+TPM 2. This interface requires ACPI and firmware support. (see the
|
||||
+`PPI specification`_)
|
||||
+
|
||||
+PPI enables a system administrator (root) to request a modification to
|
||||
+the TPM upon reboot. The PPI specification defines the operation
|
||||
+requests and the actions the firmware has to take. The system
|
||||
+administrator passes the operation request number to the firmware
|
||||
+through an ACPI interface which writes this number to a memory
|
||||
+location that the firmware knows. Upon reboot, the firmware finds the
|
||||
+number and sends commands to the TPM. The firmware writes the TPM
|
||||
+result code and the operation request number to a memory location that
|
||||
+ACPI can read from and pass the result on to the administrator.
|
||||
+
|
||||
+The PPI specification defines a set of mandatory and optional
|
||||
+operations for the firmware to implement. The ACPI interface also
|
||||
+allows an administrator to list the supported operations. In QEMU the
|
||||
+ACPI code is generated by QEMU, yet the firmware needs to implement
|
||||
+support on a per-operations basis, and different firmwares may support
|
||||
+a different subset. Therefore, QEMU introduces the virtual memory
|
||||
+device for PPI where the firmware can indicate which operations it
|
||||
+supports and ACPI can enable the ones that are supported and disable
|
||||
+all others. This interface lies in main memory and has the following
|
||||
+layout:
|
||||
+
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | Field | Length | Offset | Description |
|
||||
+ +=============+========+========+===========================================+
|
||||
+ | ``func`` | 0x100 | 0x000 | Firmware sets values for each supported |
|
||||
+ | | | | operation. See defined values below. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``ppin`` | 0x1 | 0x100 | SMI interrupt to use. Set by firmware. |
|
||||
+ | | | | Not supported. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``ppip`` | 0x4 | 0x101 | ACPI function index to pass to SMM code. |
|
||||
+ | | | | Set by ACPI. Not supported. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``pprp`` | 0x4 | 0x105 | Result of last executed operation. Set by |
|
||||
+ | | | | firmware. See function index 5 for values.|
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``pprq`` | 0x4 | 0x109 | Operation request number to execute. See |
|
||||
+ | | | | 'Physical Presence Interface Operation |
|
||||
+ | | | | Summary' tables in specs. Set by ACPI. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``pprm`` | 0x4 | 0x10d | Operation request optional parameter. |
|
||||
+ | | | | Values depend on operation. Set by ACPI. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``lppr`` | 0x4 | 0x111 | Last executed operation request number. |
|
||||
+ | | | | Copied from pprq field by firmware. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``fret`` | 0x4 | 0x115 | Result code from SMM function. |
|
||||
+ | | | | Not supported. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``res1`` | 0x40 | 0x119 | Reserved for future use |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ |``next_step``| 0x1 | 0x159 | Operation to execute after reboot by |
|
||||
+ | | | | firmware. Used by firmware. |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+ | ``movv`` | 0x1 | 0x15a | Memory overwrite variable |
|
||||
+ +-------------+--------+--------+-------------------------------------------+
|
||||
+
|
||||
+The following values are supported for the ``func`` field. They
|
||||
+correspond to the values used by ACPI function index 8.
|
||||
+
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+ | Value | Description |
|
||||
+ +==========+=============================================================+
|
||||
+ | 0 | Operation is not implemented. |
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+ | 1 | Operation is only accessible through firmware. |
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+ | 2 | Operation is blocked for OS by firmware configuration. |
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+ | 3 | Operation is allowed and physically present user required. |
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+ | 4 | Operation is allowed and physically present user is not |
|
||||
+ | | required. |
|
||||
+ +----------+-------------------------------------------------------------+
|
||||
+
|
||||
+The location of the table is given by the fw_cfg ``tpmppi_address``
|
||||
+field. The PPI memory region size is 0x400 (``TPM_PPI_ADDR_SIZE``) to
|
||||
+leave enough room for future updates.
|
||||
+
|
||||
+QEMU files related to TPM ACPI tables:
|
||||
+ - ``hw/i386/acpi-build.c``
|
||||
+ - ``include/hw/acpi/tpm.h``
|
||||
+
|
||||
+TPM backend devices
|
||||
+===================
|
||||
+
|
||||
+The TPM implementation is split into two parts, frontend and
|
||||
+backend. The frontend part is the hardware interface, such as the TPM
|
||||
+TIS interface described earlier, and the other part is the TPM backend
|
||||
+interface. The backend interfaces implement the interaction with a TPM
|
||||
+device, which may be a physical or an emulated device. The split
|
||||
+between the front- and backend devices allows a frontend to be
|
||||
+connected with any available backend. This enables the TIS interface
|
||||
+to be used with the passthrough backend or the swtpm backend.
|
||||
+
|
||||
+QEMU files related to TPM backends:
|
||||
+ - ``backends/tpm.c``
|
||||
+ - ``include/sysemu/tpm_backend.h``
|
||||
+ - ``include/sysemu/tpm_backend_int.h``
|
||||
+
|
||||
+The QEMU TPM passthrough device
|
||||
+-------------------------------
|
||||
+
|
||||
+In case QEMU is run on Linux as the host operating system it is
|
||||
+possible to make the hardware TPM device available to a single QEMU
|
||||
+guest. In this case the user must make sure that no other program is
|
||||
+using the device, e.g., /dev/tpm0, before trying to start QEMU with
|
||||
+it.
|
||||
+
|
||||
+The passthrough driver uses the host's TPM device for sending TPM
|
||||
+commands and receiving responses from. Besides that it accesses the
|
||||
+TPM device's sysfs entry for support of command cancellation. Since
|
||||
+none of the state of a hardware TPM can be migrated between hosts,
|
||||
+virtual machine migration is disabled when the TPM passthrough driver
|
||||
+is used.
|
||||
+
|
||||
+Since the host's TPM device will already be initialized by the host's
|
||||
+firmware, certain commands, e.g. ``TPM_Startup()``, sent by the
|
||||
+virtual firmware for device initialization, will fail. In this case
|
||||
+the firmware should not use the TPM.
|
||||
+
|
||||
+Sharing the device with the host is generally not a recommended usage
|
||||
+scenario for a TPM device. The primary reason for this is that two
|
||||
+operating systems can then access the device's single set of
|
||||
+resources, such as platform configuration registers
|
||||
+(PCRs). Applications or kernel security subsystems, such as the Linux
|
||||
+Integrity Measurement Architecture (IMA), are not expecting to share
|
||||
+PCRs.
|
||||
+
|
||||
+QEMU files related to the TPM passthrough device:
|
||||
+ - ``hw/tpm/tpm_passthrough.c``
|
||||
+ - ``hw/tpm/tpm_util.c``
|
||||
+ - ``hw/tpm/tpm_util.h``
|
||||
+
|
||||
+
|
||||
+Command line to start QEMU with the TPM passthrough device using the host's
|
||||
+hardware TPM ``/dev/tpm0``:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-x86_64 -display sdl -accel kvm \
|
||||
+ -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
+ -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \
|
||||
+ -device tpm-tis,tpmdev=tpm0 test.img
|
||||
+
|
||||
+
|
||||
+The following commands should result in similar output inside the VM
|
||||
+with a Linux kernel that either has the TPM TIS driver built-in or
|
||||
+available as a module:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ # dmesg | grep -i tpm
|
||||
+ [ 0.711310] tpm_tis 00:06: 1.2 TPM (device=id 0x1, rev-id 1)
|
||||
+
|
||||
+ # dmesg | grep TCPA
|
||||
+ [ 0.000000] ACPI: TCPA 0x0000000003FFD191C 000032 (v02 BOCHS \
|
||||
+ BXPCTCPA 0000001 BXPC 00000001)
|
||||
+
|
||||
+ # ls -l /dev/tpm*
|
||||
+ crw-------. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
|
||||
+
|
||||
+ # find /sys/devices/ | grep pcrs$ | xargs cat
|
||||
+ PCR-00: 35 4E 3B CE 23 9F 38 59 ...
|
||||
+ ...
|
||||
+ PCR-23: 00 00 00 00 00 00 00 00 ...
|
||||
+
|
||||
+The QEMU TPM emulator device
|
||||
+----------------------------
|
||||
+
|
||||
+The TPM emulator device uses an external TPM emulator called 'swtpm'
|
||||
+for sending TPM commands to and receiving responses from. The swtpm
|
||||
+program must have been started before trying to access it through the
|
||||
+TPM emulator with QEMU.
|
||||
+
|
||||
+The TPM emulator implements a command channel for transferring TPM
|
||||
+commands and responses as well as a control channel over which control
|
||||
+commands can be sent. (see the `SWTPM protocol`_ specification)
|
||||
+
|
||||
+The control channel serves the purpose of resetting, initializing, and
|
||||
+migrating the TPM state, among other things.
|
||||
+
|
||||
+The swtpm program behaves like a hardware TPM and therefore needs to
|
||||
+be initialized by the firmware running inside the QEMU virtual
|
||||
+machine. One necessary step for initializing the device is to send
|
||||
+the TPM_Startup command to it. SeaBIOS, for example, has been
|
||||
+instrumented to initialize a TPM 1.2 or TPM 2 device using this
|
||||
+command.
|
||||
+
|
||||
+QEMU files related to the TPM emulator device:
|
||||
+ - ``hw/tpm/tpm_emulator.c``
|
||||
+ - ``hw/tpm/tpm_util.c``
|
||||
+ - ``hw/tpm/tpm_util.h``
|
||||
+
|
||||
+The following commands start the swtpm with a UnixIO control channel over
|
||||
+a socket interface. They do not need to be run as root.
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ mkdir /tmp/mytpm1
|
||||
+ swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
+ --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ --log level=20
|
||||
+
|
||||
+Command line to start QEMU with the TPM emulator device communicating
|
||||
+with the swtpm (x86):
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-x86_64 -display sdl -accel kvm \
|
||||
+ -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-tis,tpmdev=tpm0 test.img
|
||||
+
|
||||
+In case a pSeries machine is emulated, use the following command line:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-ppc64 -display sdl -machine pseries,accel=kvm \
|
||||
+ -m 1024 -bios slof.bin -boot menu=on \
|
||||
+ -nodefaults -device VGA -device pci-ohci -device usb-kbd \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-spapr,tpmdev=tpm0 \
|
||||
+ -device spapr-vscsi,id=scsi0,reg=0x00002000 \
|
||||
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
|
||||
+ -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
|
||||
+
|
||||
+In case SeaBIOS is used as firmware, it should show the TPM menu item
|
||||
+after entering the menu with 'ESC'.
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ Select boot device:
|
||||
+ 1. DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD]
|
||||
+ [...]
|
||||
+ 5. Legacy option rom
|
||||
+
|
||||
+ t. TPM Configuration
|
||||
+
|
||||
+The following commands should result in similar output inside the VM
|
||||
+with a Linux kernel that either has the TPM TIS driver built-in or
|
||||
+available as a module:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ # dmesg | grep -i tpm
|
||||
+ [ 0.711310] tpm_tis 00:06: 1.2 TPM (device=id 0x1, rev-id 1)
|
||||
+
|
||||
+ # dmesg | grep TCPA
|
||||
+ [ 0.000000] ACPI: TCPA 0x0000000003FFD191C 000032 (v02 BOCHS \
|
||||
+ BXPCTCPA 0000001 BXPC 00000001)
|
||||
+
|
||||
+ # ls -l /dev/tpm*
|
||||
+ crw-------. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
|
||||
+
|
||||
+ # find /sys/devices/ | grep pcrs$ | xargs cat
|
||||
+ PCR-00: 35 4E 3B CE 23 9F 38 59 ...
|
||||
+ ...
|
||||
+ PCR-23: 00 00 00 00 00 00 00 00 ...
|
||||
+
|
||||
+Migration with the TPM emulator
|
||||
+===============================
|
||||
+
|
||||
+The TPM emulator supports the following types of virtual machine
|
||||
+migration:
|
||||
+
|
||||
+- VM save / restore (migration into a file)
|
||||
+- Network migration
|
||||
+- Snapshotting (migration into storage like QoW2 or QED)
|
||||
+
|
||||
+The following command sequences can be used to test VM save / restore.
|
||||
+
|
||||
+In a 1st terminal start an instance of a swtpm using the following command:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ mkdir /tmp/mytpm1
|
||||
+ swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
+ --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ --log level=20 --tpm2
|
||||
+
|
||||
+In a 2nd terminal start the VM:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-x86_64 -display sdl -accel kvm \
|
||||
+ -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-tis,tpmdev=tpm0 \
|
||||
+ -monitor stdio \
|
||||
+ test.img
|
||||
+
|
||||
+Verify that the attached TPM is working as expected using applications
|
||||
+inside the VM.
|
||||
+
|
||||
+To store the state of the VM use the following command in the QEMU
|
||||
+monitor in the 2nd terminal:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ (qemu) migrate "exec:cat > testvm.bin"
|
||||
+ (qemu) quit
|
||||
+
|
||||
+At this point a file called ``testvm.bin`` should exists and the swtpm
|
||||
+and QEMU processes should have ended.
|
||||
+
|
||||
+To test 'VM restore' you have to start the swtpm with the same
|
||||
+parameters as before. If previously a TPM 2 [--tpm2] was saved, --tpm2
|
||||
+must now be passed again on the command line.
|
||||
+
|
||||
+In the 1st terminal restart the swtpm with the same command line as
|
||||
+before:
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
+ --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ --log level=20 --tpm2
|
||||
+
|
||||
+In the 2nd terminal restore the state of the VM using the additional
|
||||
+'-incoming' option.
|
||||
+
|
||||
+.. code-block:: console
|
||||
+
|
||||
+ qemu-system-x86_64 -display sdl -accel kvm \
|
||||
+ -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-tis,tpmdev=tpm0 \
|
||||
+ -incoming "exec:cat < testvm.bin" \
|
||||
+ test.img
|
||||
+
|
||||
+Troubleshooting migration
|
||||
+-------------------------
|
||||
+
|
||||
+There are several reasons why migration may fail. In case of problems,
|
||||
+please ensure that the command lines adhere to the following rules
|
||||
+and, if possible, that identical versions of QEMU and swtpm are used
|
||||
+at all times.
|
||||
+
|
||||
+VM save and restore:
|
||||
+
|
||||
+ - QEMU command line parameters should be identical apart from the
|
||||
+ '-incoming' option on VM restore
|
||||
+
|
||||
+ - swtpm command line parameters should be identical
|
||||
+
|
||||
+VM migration to 'localhost':
|
||||
+
|
||||
+ - QEMU command line parameters should be identical apart from the
|
||||
+ '-incoming' option on the destination side
|
||||
+
|
||||
+ - swtpm command line parameters should point to two different
|
||||
+ directories on the source and destination swtpm (--tpmstate dir=...)
|
||||
+ (especially if different versions of libtpms were to be used on the
|
||||
+ same machine).
|
||||
+
|
||||
+VM migration across the network:
|
||||
+
|
||||
+ - QEMU command line parameters should be identical apart from the
|
||||
+ '-incoming' option on the destination side
|
||||
+
|
||||
+ - swtpm command line parameters should be identical
|
||||
+
|
||||
+VM Snapshotting:
|
||||
+ - QEMU command line parameters should be identical
|
||||
+
|
||||
+ - swtpm command line parameters should be identical
|
||||
+
|
||||
+
|
||||
+Besides that, migration failure reasons on the swtpm level may include
|
||||
+the following:
|
||||
+
|
||||
+ - the versions of the swtpm on the source and destination sides are
|
||||
+ incompatible
|
||||
+
|
||||
+ - downgrading of TPM state may not be supported
|
||||
+
|
||||
+ - the source and destination libtpms were compiled with different
|
||||
+ compile-time options and the destination side refuses to accept the
|
||||
+ state
|
||||
+
|
||||
+ - different migration keys are used on the source and destination side
|
||||
+ and the destination side cannot decrypt the migrated state
|
||||
+ (swtpm ... --migration-key ... )
|
||||
+
|
||||
+
|
||||
+.. _TIS specification:
|
||||
+ https://trustedcomputinggroup.org/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis/
|
||||
+
|
||||
+.. _CRB specification:
|
||||
+ https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
|
||||
+
|
||||
+
|
||||
+.. _ACPI specification:
|
||||
+ https://trustedcomputinggroup.org/tcg-acpi-specification/
|
||||
+
|
||||
+.. _PPI specification:
|
||||
+ https://trustedcomputinggroup.org/resource/tcg-physical-presence-interface-specification/
|
||||
+
|
||||
+.. _SWTPM protocol:
|
||||
+ https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
|
||||
diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
|
||||
deleted file mode 100644
|
||||
index 9c3e67d8..00000000
|
||||
--- a/docs/specs/tpm.txt
|
||||
+++ /dev/null
|
||||
@@ -1,445 +0,0 @@
|
||||
-QEMU TPM Device
|
||||
-===============
|
||||
-
|
||||
-= Guest-side Hardware Interface =
|
||||
-
|
||||
-The QEMU TPM emulation implements a TPM TIS hardware interface following the
|
||||
-Trusted Computing Group's specification "TCG PC Client Specific TPM Interface
|
||||
-Specification (TIS)", Specification Version 1.3, 21 March 2013. This
|
||||
-specification, or a later version of it, can be accessed from the following
|
||||
-URL:
|
||||
-
|
||||
-https://trustedcomputinggroup.org/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis/
|
||||
-
|
||||
-The TIS interface makes a memory mapped IO region in the area 0xfed40000 -
|
||||
-0xfed44fff available to the guest operating system.
|
||||
-
|
||||
-
|
||||
-QEMU files related to TPM TIS interface:
|
||||
- - hw/tpm/tpm_tis.c
|
||||
- - hw/tpm/tpm_tis.h
|
||||
-
|
||||
-
|
||||
-QEMU also implements a TPM CRB interface following the Trusted Computing
|
||||
-Group's specification "TCG PC Client Platform TPM Profile (PTP)
|
||||
-Specification", Family "2.0", Level 00 Revision 01.03 v22, May 22, 2017.
|
||||
-This specification, or a later version of it, can be accessed from the
|
||||
-following URL:
|
||||
-
|
||||
-https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
|
||||
-
|
||||
-The CRB interface makes a memory mapped IO region in the area 0xfed40000 -
|
||||
-0xfed40fff (1 locality) available to the guest operating system.
|
||||
-
|
||||
-QEMU files related to TPM CRB interface:
|
||||
- - hw/tpm/tpm_crb.c
|
||||
-
|
||||
-
|
||||
-pSeries (ppc64) machines offer a tpm-spapr device model.
|
||||
-
|
||||
-QEMU files related to the SPAPR interface:
|
||||
- - hw/tpm/tpm_spapr.c
|
||||
-
|
||||
-= fw_cfg interface =
|
||||
-
|
||||
-The bios/firmware may read the "etc/tpm/config" fw_cfg entry for
|
||||
-configuring the guest appropriately.
|
||||
-
|
||||
-The entry of 6 bytes has the following content, in little-endian:
|
||||
-
|
||||
- #define TPM_VERSION_UNSPEC 0
|
||||
- #define TPM_VERSION_1_2 1
|
||||
- #define TPM_VERSION_2_0 2
|
||||
-
|
||||
- #define TPM_PPI_VERSION_NONE 0
|
||||
- #define TPM_PPI_VERSION_1_30 1
|
||||
-
|
||||
- struct FwCfgTPMConfig {
|
||||
- uint32_t tpmppi_address; /* PPI memory location */
|
||||
- uint8_t tpm_version; /* TPM version */
|
||||
- uint8_t tpmppi_version; /* PPI version */
|
||||
- };
|
||||
-
|
||||
-= ACPI Interface =
|
||||
-
|
||||
-The TPM device is defined with ACPI ID "PNP0C31". QEMU builds a SSDT and passes
|
||||
-it into the guest through the fw_cfg device. The device description contains
|
||||
-the base address of the TIS interface 0xfed40000 and the size of the MMIO area
|
||||
-(0x5000). In case a TPM2 is used by QEMU, a TPM2 ACPI table is also provided.
|
||||
-The device is described to be used in polling mode rather than interrupt mode
|
||||
-primarily because no unused IRQ could be found.
|
||||
-
|
||||
-To support measurement logs to be written by the firmware, e.g. SeaBIOS, a TCPA
|
||||
-table is implemented. This table provides a 64kb buffer where the firmware can
|
||||
-write its log into. For TPM 2 only a more recent version of the TPM2 table
|
||||
-provides support for measurements logs and a TCPA table does not need to be
|
||||
-created.
|
||||
-
|
||||
-The TCPA and TPM2 ACPI tables follow the Trusted Computing Group specification
|
||||
-"TCG ACPI Specification" Family "1.2" and "2.0", Level 00 Revision 00.37. This
|
||||
-specification, or a later version of it, can be accessed from the following
|
||||
-URL:
|
||||
-
|
||||
-https://trustedcomputinggroup.org/tcg-acpi-specification/
|
||||
-
|
||||
-== ACPI PPI Interface ==
|
||||
-
|
||||
-QEMU supports the Physical Presence Interface (PPI) for TPM 1.2 and TPM 2. This
|
||||
-interface requires ACPI and firmware support. The specification can be found at
|
||||
-the following URL:
|
||||
-
|
||||
-https://trustedcomputinggroup.org/resource/tcg-physical-presence-interface-specification/
|
||||
-
|
||||
-PPI enables a system administrator (root) to request a modification to the
|
||||
-TPM upon reboot. The PPI specification defines the operation requests and the
|
||||
-actions the firmware has to take. The system administrator passes the operation
|
||||
-request number to the firmware through an ACPI interface which writes this
|
||||
-number to a memory location that the firmware knows. Upon reboot, the firmware
|
||||
-finds the number and sends commands to the TPM. The firmware writes the TPM
|
||||
-result code and the operation request number to a memory location that ACPI can
|
||||
-read from and pass the result on to the administrator.
|
||||
-
|
||||
-The PPI specification defines a set of mandatory and optional operations for
|
||||
-the firmware to implement. The ACPI interface also allows an administrator to
|
||||
-list the supported operations. In QEMU the ACPI code is generated by QEMU, yet
|
||||
-the firmware needs to implement support on a per-operations basis, and
|
||||
-different firmwares may support a different subset. Therefore, QEMU introduces
|
||||
-the virtual memory device for PPI where the firmware can indicate which
|
||||
-operations it supports and ACPI can enable the ones that are supported and
|
||||
-disable all others. This interface lies in main memory and has the following
|
||||
-layout:
|
||||
-
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | Field | Length | Offset | Description |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | func | 0x100 | 0x000 | Firmware sets values for each supported |
|
||||
- | | | | operation. See defined values below. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | ppin | 0x1 | 0x100 | SMI interrupt to use. Set by firmware. |
|
||||
- | | | | Not supported. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | ppip | 0x4 | 0x101 | ACPI function index to pass to SMM code. |
|
||||
- | | | | Set by ACPI. Not supported. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | pprp | 0x4 | 0x105 | Result of last executed operation. Set by |
|
||||
- | | | | firmware. See function index 5 for values.|
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | pprq | 0x4 | 0x109 | Operation request number to execute. See |
|
||||
- | | | | 'Physical Presence Interface Operation |
|
||||
- | | | | Summary' tables in specs. Set by ACPI. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | pprm | 0x4 | 0x10d | Operation request optional parameter. |
|
||||
- | | | | Values depend on operation. Set by ACPI. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | lppr | 0x4 | 0x111 | Last executed operation request number. |
|
||||
- | | | | Copied from pprq field by firmware. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | fret | 0x4 | 0x115 | Result code from SMM function. |
|
||||
- | | | | Not supported. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | res1 | 0x40 | 0x119 | Reserved for future use |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | next_step| 0x1 | 0x159 | Operation to execute after reboot by |
|
||||
- | | | | firmware. Used by firmware. |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
- | movv | 0x1 | 0x15a | Memory overwrite variable |
|
||||
- +----------+--------+--------+-------------------------------------------+
|
||||
-
|
||||
- The following values are supported for the 'func' field. They correspond
|
||||
- to the values used by ACPI function index 8.
|
||||
-
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | value | Description |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | 0 | Operation is not implemented. |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | 1 | Operation is only accessible through firmware. |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | 2 | Operation is blocked for OS by firmware configuration. |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | 3 | Operation is allowed and physically present user required. |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
- | 4 | Operation is allowed and physically present user is not |
|
||||
- | | required. |
|
||||
- +----------+-------------------------------------------------------------+
|
||||
-
|
||||
-The location of the table is given by the fw_cfg tpmppi_address field.
|
||||
-The PPI memory region size is 0x400 (TPM_PPI_ADDR_SIZE) to leave
|
||||
-enough room for future updates.
|
||||
-
|
||||
-
|
||||
-QEMU files related to TPM ACPI tables:
|
||||
- - hw/i386/acpi-build.c
|
||||
- - include/hw/acpi/tpm.h
|
||||
-
|
||||
-
|
||||
-= TPM backend devices =
|
||||
-
|
||||
-The TPM implementation is split into two parts, frontend and backend. The
|
||||
-frontend part is the hardware interface, such as the TPM TIS interface
|
||||
-described earlier, and the other part is the TPM backend interface. The backend
|
||||
-interfaces implement the interaction with a TPM device, which may be a physical
|
||||
-or an emulated device. The split between the front- and backend devices allows
|
||||
-a frontend to be connected with any available backend. This enables the TIS
|
||||
-interface to be used with the passthrough backend or the (future) swtpm backend.
|
||||
-
|
||||
-
|
||||
-QEMU files related to TPM backends:
|
||||
- - backends/tpm.c
|
||||
- - include/sysemu/tpm_backend.h
|
||||
- - include/sysemu/tpm_backend_int.h
|
||||
-
|
||||
-
|
||||
-== The QEMU TPM passthrough device ==
|
||||
-
|
||||
-In case QEMU is run on Linux as the host operating system it is possible to
|
||||
-make the hardware TPM device available to a single QEMU guest. In this case the
|
||||
-user must make sure that no other program is using the device, e.g., /dev/tpm0,
|
||||
-before trying to start QEMU with it.
|
||||
-
|
||||
-The passthrough driver uses the host's TPM device for sending TPM commands
|
||||
-and receiving responses from. Besides that it accesses the TPM device's sysfs
|
||||
-entry for support of command cancellation. Since none of the state of a
|
||||
-hardware TPM can be migrated between hosts, virtual machine migration is
|
||||
-disabled when the TPM passthrough driver is used.
|
||||
-
|
||||
-Since the host's TPM device will already be initialized by the host's firmware,
|
||||
-certain commands, e.g. TPM_Startup(), sent by the virtual firmware for device
|
||||
-initialization, will fail. In this case the firmware should not use the TPM.
|
||||
-
|
||||
-Sharing the device with the host is generally not a recommended usage scenario
|
||||
-for a TPM device. The primary reason for this is that two operating systems can
|
||||
-then access the device's single set of resources, such as platform configuration
|
||||
-registers (PCRs). Applications or kernel security subsystems, such as the
|
||||
-Linux Integrity Measurement Architecture (IMA), are not expecting to share PCRs.
|
||||
-
|
||||
-
|
||||
-QEMU files related to the TPM passthrough device:
|
||||
- - hw/tpm/tpm_passthrough.c
|
||||
- - hw/tpm/tpm_util.c
|
||||
- - hw/tpm/tpm_util.h
|
||||
-
|
||||
-
|
||||
-Command line to start QEMU with the TPM passthrough device using the host's
|
||||
-hardware TPM /dev/tpm0:
|
||||
-
|
||||
-qemu-system-x86_64 -display sdl -accel kvm \
|
||||
- -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
- -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \
|
||||
- -device tpm-tis,tpmdev=tpm0 test.img
|
||||
-
|
||||
-The following commands should result in similar output inside the VM with a
|
||||
-Linux kernel that either has the TPM TIS driver built-in or available as a
|
||||
-module:
|
||||
-
|
||||
-#> dmesg | grep -i tpm
|
||||
-[ 0.711310] tpm_tis 00:06: 1.2 TPM (device=id 0x1, rev-id 1)
|
||||
-
|
||||
-#> dmesg | grep TCPA
|
||||
-[ 0.000000] ACPI: TCPA 0x0000000003FFD191C 000032 (v02 BOCHS \
|
||||
- BXPCTCPA 0000001 BXPC 00000001)
|
||||
-
|
||||
-#> ls -l /dev/tpm*
|
||||
-crw-------. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
|
||||
-
|
||||
-#> find /sys/devices/ | grep pcrs$ | xargs cat
|
||||
-PCR-00: 35 4E 3B CE 23 9F 38 59 ...
|
||||
-...
|
||||
-PCR-23: 00 00 00 00 00 00 00 00 ...
|
||||
-
|
||||
-
|
||||
-== The QEMU TPM emulator device ==
|
||||
-
|
||||
-The TPM emulator device uses an external TPM emulator called 'swtpm' for
|
||||
-sending TPM commands to and receiving responses from. The swtpm program
|
||||
-must have been started before trying to access it through the TPM emulator
|
||||
-with QEMU.
|
||||
-
|
||||
-The TPM emulator implements a command channel for transferring TPM commands
|
||||
-and responses as well as a control channel over which control commands can
|
||||
-be sent. The specification for the control channel can be found here:
|
||||
-
|
||||
-https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod
|
||||
-
|
||||
-
|
||||
-The control channel serves the purpose of resetting, initializing, and
|
||||
-migrating the TPM state, among other things.
|
||||
-
|
||||
-The swtpm program behaves like a hardware TPM and therefore needs to be
|
||||
-initialized by the firmware running inside the QEMU virtual machine.
|
||||
-One necessary step for initializing the device is to send the TPM_Startup
|
||||
-command to it. SeaBIOS, for example, has been instrumented to initialize
|
||||
-a TPM 1.2 or TPM 2 device using this command.
|
||||
-
|
||||
-
|
||||
-QEMU files related to the TPM emulator device:
|
||||
- - hw/tpm/tpm_emulator.c
|
||||
- - hw/tpm/tpm_util.c
|
||||
- - hw/tpm/tpm_util.h
|
||||
-
|
||||
-
|
||||
-The following commands start the swtpm with a UnixIO control channel over
|
||||
-a socket interface. They do not need to be run as root.
|
||||
-
|
||||
-mkdir /tmp/mytpm1
|
||||
-swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
- --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
- --log level=20
|
||||
-
|
||||
-Command line to start QEMU with the TPM emulator device communicating with
|
||||
-the swtpm (x86):
|
||||
-
|
||||
-qemu-system-x86_64 -display sdl -accel kvm \
|
||||
- -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
- -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
- -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
- -device tpm-tis,tpmdev=tpm0 test.img
|
||||
-
|
||||
-In case a pSeries machine is emulated, use the following command line:
|
||||
-
|
||||
-qemu-system-ppc64 -display sdl -machine pseries,accel=kvm \
|
||||
- -m 1024 -bios slof.bin -boot menu=on \
|
||||
- -nodefaults -device VGA -device pci-ohci -device usb-kbd \
|
||||
- -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
- -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
- -device tpm-spapr,tpmdev=tpm0 \
|
||||
- -device spapr-vscsi,id=scsi0,reg=0x00002000 \
|
||||
- -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
|
||||
- -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
|
||||
-
|
||||
-
|
||||
-In case SeaBIOS is used as firmware, it should show the TPM menu item
|
||||
-after entering the menu with 'ESC'.
|
||||
-
|
||||
-Select boot device:
|
||||
-1. DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD]
|
||||
-[...]
|
||||
-5. Legacy option rom
|
||||
-
|
||||
-t. TPM Configuration
|
||||
-
|
||||
-
|
||||
-The following commands should result in similar output inside the VM with a
|
||||
-Linux kernel that either has the TPM TIS driver built-in or available as a
|
||||
-module:
|
||||
-
|
||||
-#> dmesg | grep -i tpm
|
||||
-[ 0.711310] tpm_tis 00:06: 1.2 TPM (device=id 0x1, rev-id 1)
|
||||
-
|
||||
-#> dmesg | grep TCPA
|
||||
-[ 0.000000] ACPI: TCPA 0x0000000003FFD191C 000032 (v02 BOCHS \
|
||||
- BXPCTCPA 0000001 BXPC 00000001)
|
||||
-
|
||||
-#> ls -l /dev/tpm*
|
||||
-crw-------. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
|
||||
-
|
||||
-#> find /sys/devices/ | grep pcrs$ | xargs cat
|
||||
-PCR-00: 35 4E 3B CE 23 9F 38 59 ...
|
||||
-...
|
||||
-PCR-23: 00 00 00 00 00 00 00 00 ...
|
||||
-
|
||||
-
|
||||
-=== Migration with the TPM emulator ===
|
||||
-
|
||||
-The TPM emulator supports the following types of virtual machine migration:
|
||||
-
|
||||
-- VM save / restore (migration into a file)
|
||||
-- Network migration
|
||||
-- Snapshotting (migration into storage like QoW2 or QED)
|
||||
-
|
||||
-The following command sequences can be used to test VM save / restore.
|
||||
-
|
||||
-
|
||||
-In a 1st terminal start an instance of a swtpm using the following command:
|
||||
-
|
||||
-mkdir /tmp/mytpm1
|
||||
-swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
- --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
- --log level=20 --tpm2
|
||||
-
|
||||
-In a 2nd terminal start the VM:
|
||||
-
|
||||
-qemu-system-x86_64 -display sdl -accel kvm \
|
||||
- -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
- -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
- -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
- -device tpm-tis,tpmdev=tpm0 \
|
||||
- -monitor stdio \
|
||||
- test.img
|
||||
-
|
||||
-Verify that the attached TPM is working as expected using applications inside
|
||||
-the VM.
|
||||
-
|
||||
-To store the state of the VM use the following command in the QEMU monitor in
|
||||
-the 2nd terminal:
|
||||
-
|
||||
-(qemu) migrate "exec:cat > testvm.bin"
|
||||
-(qemu) quit
|
||||
-
|
||||
-At this point a file called 'testvm.bin' should exists and the swtpm and QEMU
|
||||
-processes should have ended.
|
||||
-
|
||||
-To test 'VM restore' you have to start the swtpm with the same parameters
|
||||
-as before. If previously a TPM 2 [--tpm2] was saved, --tpm2 must now be
|
||||
-passed again on the command line.
|
||||
-
|
||||
-In the 1st terminal restart the swtpm with the same command line as before:
|
||||
-
|
||||
-swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
- --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
|
||||
- --log level=20 --tpm2
|
||||
-
|
||||
-In the 2nd terminal restore the state of the VM using the additional
|
||||
-'-incoming' option.
|
||||
-
|
||||
-qemu-system-x86_64 -display sdl -accel kvm \
|
||||
- -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
- -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
- -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
- -device tpm-tis,tpmdev=tpm0 \
|
||||
- -incoming "exec:cat < testvm.bin" \
|
||||
- test.img
|
||||
-
|
||||
-
|
||||
-Troubleshooting migration:
|
||||
-
|
||||
-There are several reasons why migration may fail. In case of problems,
|
||||
-please ensure that the command lines adhere to the following rules and,
|
||||
-if possible, that identical versions of QEMU and swtpm are used at all
|
||||
-times.
|
||||
-
|
||||
-VM save and restore:
|
||||
- - QEMU command line parameters should be identical apart from the
|
||||
- '-incoming' option on VM restore
|
||||
- - swtpm command line parameters should be identical
|
||||
-
|
||||
-VM migration to 'localhost':
|
||||
- - QEMU command line parameters should be identical apart from the
|
||||
- '-incoming' option on the destination side
|
||||
- - swtpm command line parameters should point to two different
|
||||
- directories on the source and destination swtpm (--tpmstate dir=...)
|
||||
- (especially if different versions of libtpms were to be used on the
|
||||
- same machine).
|
||||
-
|
||||
-VM migration across the network:
|
||||
- - QEMU command line parameters should be identical apart from the
|
||||
- '-incoming' option on the destination side
|
||||
- - swtpm command line parameters should be identical
|
||||
-
|
||||
-VM Snapshotting:
|
||||
- - QEMU command line parameters should be identical
|
||||
- - swtpm command line parameters should be identical
|
||||
-
|
||||
-
|
||||
-Besides that, migration failure reasons on the swtpm level may include
|
||||
-the following:
|
||||
-
|
||||
- - the versions of the swtpm on the source and destination sides are
|
||||
- incompatible
|
||||
- - downgrading of TPM state may not be supported
|
||||
- - the source and destination libtpms were compiled with different
|
||||
- compile-time options and the destination side refuses to accept the
|
||||
- state
|
||||
- - different migration keys are used on the source and destination side
|
||||
- and the destination side cannot decrypt the migrated state
|
||||
- (swtpm ... --migration-key ... )
|
||||
--
|
||||
2.23.0
|
||||
|
||||
141
hw-arm-virt-vTPM-support.patch
Normal file
141
hw-arm-virt-vTPM-support.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 443ebab9c299b04f020a6873454facb078723141 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Thu, 13 Aug 2020 20:01:10 +0800
|
||||
Subject: [PATCH 15/19] hw/arm/virt: vTPM support
|
||||
|
||||
Let the TPM TIS SYSBUS device be dynamically instantiable
|
||||
in ARM virt. A device tree node is dynamically created
|
||||
(TPM via MMIO).
|
||||
|
||||
The TPM Physical Presence interface (PPI) is not supported.
|
||||
|
||||
To run with the swtmp TPM emulator, the qemu command line must
|
||||
be augmented with:
|
||||
|
||||
-chardev socket,id=chrtpm,path=swtpm-sock
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm
|
||||
-device tpm-tis-device,tpmdev=tpm0
|
||||
|
||||
swtpm/libtpms command line example:
|
||||
|
||||
swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm
|
||||
--ctrl type=unixio,path=swtpm-sock
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Message-id: 20200305165149.618-7-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/arm/Kconfig | 1 +
|
||||
hw/arm/sysbus-fdt.c | 33 +++++++++++++++++++++++++++++++++
|
||||
hw/arm/virt.c | 7 +++++++
|
||||
3 files changed, 41 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
|
||||
index 15e18b0a..06e49f26 100644
|
||||
--- a/hw/arm/Kconfig
|
||||
+++ b/hw/arm/Kconfig
|
||||
@@ -5,6 +5,7 @@ config ARM_VIRT
|
||||
imply VFIO_AMD_XGBE
|
||||
imply VFIO_PLATFORM
|
||||
imply VFIO_XGMAC
|
||||
+ imply TPM_TIS_SYSBUS
|
||||
select A15MPCORE
|
||||
select ACPI
|
||||
select ARM_SMMUV3
|
||||
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
|
||||
index 57f94e65..c725d325 100644
|
||||
--- a/hw/arm/sysbus-fdt.c
|
||||
+++ b/hw/arm/sysbus-fdt.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "hw/arm/sysbus-fdt.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
+#include "sysemu/tpm.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/vfio/vfio-platform.h"
|
||||
@@ -437,6 +438,37 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
|
||||
|
||||
#endif /* CONFIG_LINUX */
|
||||
|
||||
+/*
|
||||
+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS
|
||||
+ *
|
||||
+ * See kernel documentation:
|
||||
+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt
|
||||
+ * Optional interrupt for command completion is not exposed
|
||||
+ */
|
||||
+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
+{
|
||||
+ PlatformBusFDTData *data = opaque;
|
||||
+ PlatformBusDevice *pbus = data->pbus;
|
||||
+ void *fdt = data->fdt;
|
||||
+ const char *parent_node = data->pbus_node_name;
|
||||
+ char *nodename;
|
||||
+ uint32_t reg_attr[2];
|
||||
+ uint64_t mmio_base;
|
||||
+
|
||||
+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
+ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base);
|
||||
+ qemu_fdt_add_subnode(fdt, nodename);
|
||||
+
|
||||
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio");
|
||||
+
|
||||
+ reg_attr[0] = cpu_to_be32(mmio_base);
|
||||
+ reg_attr[1] = cpu_to_be32(0x5000);
|
||||
+ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t));
|
||||
+
|
||||
+ g_free(nodename);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int no_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
return 0;
|
||||
@@ -457,6 +489,7 @@ static const BindingEntry bindings[] = {
|
||||
TYPE_BINDING(TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node),
|
||||
VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
|
||||
#endif
|
||||
+ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
|
||||
TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
|
||||
TYPE_BINDING("", NULL), /* last element */
|
||||
};
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 133d36a4..7afc6c5e 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "sysemu/numa.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
+#include "sysemu/tpm.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/hw_accel.h"
|
||||
@@ -2368,6 +2369,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
|
||||
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||
mc->block_default_type = IF_VIRTIO;
|
||||
mc->no_cdrom = 1;
|
||||
mc->pci_allow_0_address = true;
|
||||
@@ -2481,6 +2483,11 @@ type_init(machvirt_machine_init);
|
||||
|
||||
static void virt_machine_4_1_options(MachineClass *mc)
|
||||
{
|
||||
+ static GlobalProperty compat[] = {
|
||||
+ { TYPE_TPM_TIS_SYSBUS, "ppi", "false" },
|
||||
+ };
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
||||
}
|
||||
DEFINE_VIRT_MACHINE_AS_LATEST(4, 1)
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
36
hw-ppc-Kconfig-Enable-TPM_SPAPR-as-part-of-PSERIES-c.patch
Normal file
36
hw-ppc-Kconfig-Enable-TPM_SPAPR-as-part-of-PSERIES-c.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 95cbe18c649a20f98562a993537a67e0ad78bf36 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:34 -0500
|
||||
Subject: [PATCH 08/19] hw/ppc/Kconfig: Enable TPM_SPAPR as part of PSERIES
|
||||
config
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Message-Id: <20200121152935.649898-6-stefanb@linux.ibm.com>
|
||||
[dwg: Use default in Kconfig rather than select to avoid breaking
|
||||
Windows host build]
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
|
||||
index 4d4ab085..9e67d990 100644
|
||||
--- a/hw/tpm/Kconfig
|
||||
+++ b/hw/tpm/Kconfig
|
||||
@@ -25,6 +25,6 @@ config TPM_EMULATOR
|
||||
|
||||
config TPM_SPAPR
|
||||
bool
|
||||
- default n
|
||||
+ default y
|
||||
depends on TPM && PSERIES
|
||||
select TPMDEV
|
||||
--
|
||||
2.23.0
|
||||
|
||||
58
hw-tpm-rename-Error-parameter-to-more-common-errp.patch
Normal file
58
hw-tpm-rename-Error-parameter-to-more-common-errp.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From f2dceb3cde537210896a2cadb8958cfd310113a3 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Date: Thu, 5 Dec 2019 20:46:30 +0300
|
||||
Subject: [PATCH 01/19] hw/tpm: rename Error ** parameter to more common errp
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-Id: <20191205174635.18758-17-vsementsov@virtuozzo.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/tpm_emulator.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
|
||||
index fc0b512f..38bf5fd6 100644
|
||||
--- a/hw/tpm/tpm_emulator.c
|
||||
+++ b/hw/tpm/tpm_emulator.c
|
||||
@@ -155,7 +155,7 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
|
||||
const uint8_t *in, uint32_t in_len,
|
||||
uint8_t *out, uint32_t out_len,
|
||||
bool *selftest_done,
|
||||
- Error **err)
|
||||
+ Error **errp)
|
||||
{
|
||||
ssize_t ret;
|
||||
bool is_selftest = false;
|
||||
@@ -165,20 +165,20 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
|
||||
is_selftest = tpm_util_is_selftest(in, in_len);
|
||||
}
|
||||
|
||||
- ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, err);
|
||||
+ ret = qio_channel_write_all(tpm_emu->data_ioc, (char *)in, in_len, errp);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
|
||||
- sizeof(struct tpm_resp_hdr), err);
|
||||
+ sizeof(struct tpm_resp_hdr), errp);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qio_channel_read_all(tpm_emu->data_ioc,
|
||||
(char *)out + sizeof(struct tpm_resp_hdr),
|
||||
- tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), err);
|
||||
+ tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), errp);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
25
qemu.spec
25
qemu.spec
@ -1,6 +1,6 @@
|
||||
Name: qemu
|
||||
Version: 4.1.0
|
||||
Release: 17
|
||||
Release: 18
|
||||
Epoch: 2
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY
|
||||
@ -184,6 +184,25 @@ Patch0171: megasas-avoid-NULL-pointer-dereference.patch
|
||||
Patch0172: megasas-use-unsigned-type-for-positive-numeric-field.patch
|
||||
Patch0173: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch
|
||||
Patch0174: hw-arm-acpi-enable-SHPC-native-hot-plug.patch
|
||||
Patch0175: hw-tpm-rename-Error-parameter-to-more-common-errp.patch
|
||||
Patch0176: tpm-ppi-page-align-PPI-RAM.patch
|
||||
Patch0177: tpm-Move-tpm_tis_show_buffer-to-tpm_util.c.patch
|
||||
Patch0178: spapr-Implement-get_dt_compatible-callback.patch
|
||||
Patch0179: delete-the-in-tpm.txt.patch
|
||||
Patch0180: tpm_spapr-Support-TPM-for-ppc64-using-CRQ-based-inte.patch
|
||||
Patch0181: tpm_spapr-Support-suspend-and-resume.patch
|
||||
Patch0182: hw-ppc-Kconfig-Enable-TPM_SPAPR-as-part-of-PSERIES-c.patch
|
||||
Patch0183: docs-specs-tpm-reST-ify-TPM-documentation.patch
|
||||
Patch0184: tpm-rename-TPM_TIS-into-TPM_TIS_ISA.patch
|
||||
Patch0185: tpm-Use-TPMState-as-a-common-struct.patch
|
||||
Patch0186: tpm-Separate-tpm_tis-common-functions-from-isa-code.patch
|
||||
Patch0187: tpm-Separate-TPM_TIS-and-TPM_TIS_ISA-configs.patch
|
||||
Patch0188: tpm-Add-the-SysBus-TPM-TIS-device.patch
|
||||
Patch0189: hw-arm-virt-vTPM-support.patch
|
||||
Patch0190: docs-specs-tpm-Document-TPM_TIS-sysbus-device-for-AR.patch
|
||||
Patch0191: test-tpm-pass-optional-machine-options-to-swtpm-test.patch
|
||||
Patch0192: test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch
|
||||
Patch0193: test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: bison
|
||||
@ -326,6 +345,7 @@ buildldflags="VL_LDFLAGS=-Wl,--build-id"
|
||||
--enable-linux-aio \
|
||||
--enable-cap-ng \
|
||||
--enable-vhost-user \
|
||||
--enable-tpm \
|
||||
%ifarch aarch64
|
||||
--enable-fdt \
|
||||
--enable-virglrenderer \
|
||||
@ -529,6 +549,9 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Aug 13 2020 Huawei Technologies Co., Ltd <jiangfangjie@huawei.com>
|
||||
-target/arm: Aarch64 support vtpm
|
||||
|
||||
* Wed Aug 12 2020 Huawei Technologies Co., Ltd <jinzeyu@huawei.com>
|
||||
- backport upstream patch to support SHPCHotplug in arm
|
||||
|
||||
|
||||
68
spapr-Implement-get_dt_compatible-callback.patch
Normal file
68
spapr-Implement-get_dt_compatible-callback.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From c520d8e823431be94268daa2a911e224cab81521 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:31 -0500
|
||||
Subject: [PATCH 04/19] spapr: Implement get_dt_compatible() callback
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
For devices that cannot be statically initialized, implement a
|
||||
get_dt_compatible() callback that allows us to ask the device for
|
||||
the 'compatible' value.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Message-Id: <20200121152935.649898-3-stefanb@linux.ibm.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/ppc/spapr_vio.c | 11 +++++++++--
|
||||
include/hw/ppc/spapr_vio.h | 1 +
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
|
||||
index 583c13de..4e50916f 100644
|
||||
--- a/hw/ppc/spapr_vio.c
|
||||
+++ b/hw/ppc/spapr_vio.c
|
||||
@@ -89,6 +89,7 @@ static int vio_make_devnode(SpaprVioDevice *dev,
|
||||
SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
int vdevice_off, node_off, ret;
|
||||
char *dt_name;
|
||||
+ const char *dt_compatible;
|
||||
|
||||
vdevice_off = fdt_path_offset(fdt, "/vdevice");
|
||||
if (vdevice_off < 0) {
|
||||
@@ -115,9 +116,15 @@ static int vio_make_devnode(SpaprVioDevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
- if (pc->dt_compatible) {
|
||||
+ if (pc->get_dt_compatible) {
|
||||
+ dt_compatible = pc->get_dt_compatible(dev);
|
||||
+ } else {
|
||||
+ dt_compatible = pc->dt_compatible;
|
||||
+ }
|
||||
+
|
||||
+ if (dt_compatible) {
|
||||
ret = fdt_setprop_string(fdt, node_off, "compatible",
|
||||
- pc->dt_compatible);
|
||||
+ dt_compatible);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
|
||||
index 04609f21..97951fc6 100644
|
||||
--- a/include/hw/ppc/spapr_vio.h
|
||||
+++ b/include/hw/ppc/spapr_vio.h
|
||||
@@ -56,6 +56,7 @@ typedef struct SpaprVioDeviceClass {
|
||||
void (*realize)(SpaprVioDevice *dev, Error **errp);
|
||||
void (*reset)(SpaprVioDevice *dev);
|
||||
int (*devnode)(SpaprVioDevice *dev, void *fdt, int node_off);
|
||||
+ const char *(*get_dt_compatible)(SpaprVioDevice *dev);
|
||||
} SpaprVioDeviceClass;
|
||||
|
||||
struct SpaprVioDevice {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
187
test-tpm-pass-optional-machine-options-to-swtpm-test.patch
Normal file
187
test-tpm-pass-optional-machine-options-to-swtpm-test.patch
Normal file
@ -0,0 +1,187 @@
|
||||
From c06a3ceacc1793bc1cfe5c2a6ed510c9aea8253d Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Thu, 13 Aug 2020 20:28:25 +0800
|
||||
Subject: [PATCH 17/19] test: tpm: pass optional machine options to swtpm test
|
||||
functions
|
||||
|
||||
We plan to use swtpm test functions on ARM for testing the
|
||||
sysbus TPM-TIS device. However on ARM there is no default machine
|
||||
type. So we need to explictly pass some machine options on startup.
|
||||
Let's allow this by adding a new parameter to both swtpm test
|
||||
functions and update all call sites.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-id: 20200305165149.618-9-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
tests/tpm-crb-swtpm-test.c | 5 +++--
|
||||
tests/tpm-tests.c | 10 ++++++----
|
||||
tests/tpm-tests.h | 5 +++--
|
||||
tests/tpm-tis-swtpm-test.c | 5 +++--
|
||||
tests/tpm-util.c | 8 ++++++--
|
||||
tests/tpm-util.h | 3 ++-
|
||||
6 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/tests/tpm-crb-swtpm-test.c b/tests/tpm-crb-swtpm-test.c
|
||||
index 2c4fb8ae..5228cb7a 100644
|
||||
--- a/tests/tpm-crb-swtpm-test.c
|
||||
+++ b/tests/tpm-crb-swtpm-test.c
|
||||
@@ -29,7 +29,8 @@ static void tpm_crb_swtpm_test(const void *data)
|
||||
{
|
||||
const TestState *ts = data;
|
||||
|
||||
- tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer, "tpm-crb");
|
||||
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_crb_transfer,
|
||||
+ "tpm-crb", NULL);
|
||||
}
|
||||
|
||||
static void tpm_crb_swtpm_migration_test(const void *data)
|
||||
@@ -37,7 +38,7 @@ static void tpm_crb_swtpm_migration_test(const void *data)
|
||||
const TestState *ts = data;
|
||||
|
||||
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
|
||||
- tpm_util_crb_transfer, "tpm-crb");
|
||||
+ tpm_util_crb_transfer, "tpm-crb", NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
diff --git a/tests/tpm-tests.c b/tests/tpm-tests.c
|
||||
index e640777a..d823bda8 100644
|
||||
--- a/tests/tpm-tests.c
|
||||
+++ b/tests/tpm-tests.c
|
||||
@@ -30,7 +30,7 @@ tpm_test_swtpm_skip(void)
|
||||
}
|
||||
|
||||
void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
|
||||
- const char *ifmodel)
|
||||
+ const char *ifmodel, const char *machine_options)
|
||||
{
|
||||
char *args = NULL;
|
||||
QTestState *s;
|
||||
@@ -47,10 +47,11 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
|
||||
g_assert_true(succ);
|
||||
|
||||
args = g_strdup_printf(
|
||||
+ "%s "
|
||||
"-chardev socket,id=chr,path=%s "
|
||||
"-tpmdev emulator,id=dev,chardev=chr "
|
||||
"-device %s,tpmdev=dev",
|
||||
- addr->u.q_unix.path, ifmodel);
|
||||
+ machine_options ? : "", addr->u.q_unix.path, ifmodel);
|
||||
|
||||
s = qtest_start(args);
|
||||
g_free(args);
|
||||
@@ -78,7 +79,8 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
|
||||
void tpm_test_swtpm_migration_test(const char *src_tpm_path,
|
||||
const char *dst_tpm_path,
|
||||
const char *uri, tx_func *tx,
|
||||
- const char *ifmodel)
|
||||
+ const char *ifmodel,
|
||||
+ const char *machine_options)
|
||||
{
|
||||
gboolean succ;
|
||||
GPid src_tpm_pid, dst_tpm_pid;
|
||||
@@ -100,7 +102,7 @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
|
||||
|
||||
tpm_util_migration_start_qemu(&src_qemu, &dst_qemu,
|
||||
src_tpm_addr, dst_tpm_addr, uri,
|
||||
- ifmodel);
|
||||
+ ifmodel, machine_options);
|
||||
|
||||
tpm_util_startup(src_qemu, tx);
|
||||
tpm_util_pcrextend(src_qemu, tx);
|
||||
diff --git a/tests/tpm-tests.h b/tests/tpm-tests.h
|
||||
index b97688fe..a5df35ab 100644
|
||||
--- a/tests/tpm-tests.h
|
||||
+++ b/tests/tpm-tests.h
|
||||
@@ -16,11 +16,12 @@
|
||||
#include "tpm-util.h"
|
||||
|
||||
void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx,
|
||||
- const char *ifmodel);
|
||||
+ const char *ifmodel, const char *machine_options);
|
||||
|
||||
void tpm_test_swtpm_migration_test(const char *src_tpm_path,
|
||||
const char *dst_tpm_path,
|
||||
const char *uri, tx_func *tx,
|
||||
- const char *ifmodel);
|
||||
+ const char *ifmodel,
|
||||
+ const char *machine_options);
|
||||
|
||||
#endif /* TESTS_TPM_TESTS_H */
|
||||
diff --git a/tests/tpm-tis-swtpm-test.c b/tests/tpm-tis-swtpm-test.c
|
||||
index 9f58a3a9..9470f157 100644
|
||||
--- a/tests/tpm-tis-swtpm-test.c
|
||||
+++ b/tests/tpm-tis-swtpm-test.c
|
||||
@@ -29,7 +29,8 @@ static void tpm_tis_swtpm_test(const void *data)
|
||||
{
|
||||
const TestState *ts = data;
|
||||
|
||||
- tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer, "tpm-tis");
|
||||
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
|
||||
+ "tpm-tis", NULL);
|
||||
}
|
||||
|
||||
static void tpm_tis_swtpm_migration_test(const void *data)
|
||||
@@ -37,7 +38,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
|
||||
const TestState *ts = data;
|
||||
|
||||
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
|
||||
- tpm_util_tis_transfer, "tpm-tis");
|
||||
+ tpm_util_tis_transfer, "tpm-tis", NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
diff --git a/tests/tpm-util.c b/tests/tpm-util.c
|
||||
index e08b1376..7ecdae2f 100644
|
||||
--- a/tests/tpm-util.c
|
||||
+++ b/tests/tpm-util.c
|
||||
@@ -258,23 +258,27 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu,
|
||||
SocketAddress *src_tpm_addr,
|
||||
SocketAddress *dst_tpm_addr,
|
||||
const char *miguri,
|
||||
- const char *ifmodel)
|
||||
+ const char *ifmodel,
|
||||
+ const char *machine_options)
|
||||
{
|
||||
char *src_qemu_args, *dst_qemu_args;
|
||||
|
||||
src_qemu_args = g_strdup_printf(
|
||||
+ "%s "
|
||||
"-chardev socket,id=chr,path=%s "
|
||||
"-tpmdev emulator,id=dev,chardev=chr "
|
||||
"-device %s,tpmdev=dev ",
|
||||
- src_tpm_addr->u.q_unix.path, ifmodel);
|
||||
+ machine_options ? : "", src_tpm_addr->u.q_unix.path, ifmodel);
|
||||
|
||||
*src_qemu = qtest_init(src_qemu_args);
|
||||
|
||||
dst_qemu_args = g_strdup_printf(
|
||||
+ "%s "
|
||||
"-chardev socket,id=chr,path=%s "
|
||||
"-tpmdev emulator,id=dev,chardev=chr "
|
||||
"-device %s,tpmdev=dev "
|
||||
"-incoming %s",
|
||||
+ machine_options ? : "",
|
||||
dst_tpm_addr->u.q_unix.path,
|
||||
ifmodel, miguri);
|
||||
|
||||
diff --git a/tests/tpm-util.h b/tests/tpm-util.h
|
||||
index 5755698a..15e39249 100644
|
||||
--- a/tests/tpm-util.h
|
||||
+++ b/tests/tpm-util.h
|
||||
@@ -44,7 +44,8 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu,
|
||||
SocketAddress *src_tpm_addr,
|
||||
SocketAddress *dst_tpm_addr,
|
||||
const char *miguri,
|
||||
- const char *ifmodel);
|
||||
+ const char *ifmodel,
|
||||
+ const char *machine_options);
|
||||
|
||||
void tpm_util_wait_for_migration_complete(QTestState *who);
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
226
test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch
Normal file
226
test-tpm-tis-Add-Sysbus-TPM-TIS-device-test.patch
Normal file
@ -0,0 +1,226 @@
|
||||
From 2d28c0edddeaee5e4aa6e8c6b109776cddc1c4e4 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Thu, 13 Aug 2020 21:37:23 +0800
|
||||
Subject: [PATCH 19/19] test: tpm-tis: Add Sysbus TPM-TIS device test
|
||||
|
||||
The tests themselves are the same as the ISA device ones.
|
||||
Only the main() changes as the tpm-tis-device device gets
|
||||
instantiated. Also the base address of the device is not
|
||||
0xFED40000 anymore but matches the base address of the
|
||||
ARM virt platform bus.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-id: 20200305165149.618-11-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
tests/Makefile.include | 5 ++
|
||||
tests/tpm-tis-device-swtpm-test.c | 76 +++++++++++++++++++++++++++
|
||||
tests/tpm-tis-device-test.c | 87 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 168 insertions(+)
|
||||
create mode 100644 tests/tpm-tis-device-swtpm-test.c
|
||||
create mode 100644 tests/tpm-tis-device-test.c
|
||||
|
||||
diff --git a/tests/Makefile.include b/tests/Makefile.include
|
||||
index 950b32a2..d6de4e10 100644
|
||||
--- a/tests/Makefile.include
|
||||
+++ b/tests/Makefile.include
|
||||
@@ -263,6 +263,8 @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
|
||||
check-qtest-arm-y += tests/hexloader-test$(EXESUF)
|
||||
check-qtest-arm-$(CONFIG_PFLASH_CFI02) += tests/pflash-cfi02-test$(EXESUF)
|
||||
|
||||
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-test
|
||||
+check-qtest-aarch64-$(CONFIG_TPM_TIS_SYSBUS) += tpm-tis-device-swtpm-test
|
||||
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
|
||||
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
|
||||
check-qtest-aarch64-y += tests/migration-test$(EXESUF)
|
||||
@@ -667,7 +669,10 @@ tests/tpm-crb-swtpm-test$(EXESUF): tests/tpm-crb-swtpm-test.o tests/tpm-emu.o \
|
||||
tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o $(test-io-obj-y)
|
||||
tests/tpm-tis-swtpm-test$(EXESUF): tests/tpm-tis-swtpm-test.o tests/tpm-emu.o \
|
||||
tests/tpm-util.o tests/tpm-tests.o $(test-io-obj-y)
|
||||
+tests/tpm-tis-device-swtpm-test$(EXESUF): tests/tpm-tis-device-swtpm-test.o tests/tpm-emu.o \
|
||||
+ tests/tpm-util.o tests/tpm-tests.o $(test-io-obj-y)
|
||||
tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-tis-util.o tests/tpm-emu.o $(test-io-obj-y)
|
||||
+tests/tpm-tis-device-test$(EXESUF): tests/tpm-tis-device-test.o tests/tpm-tis-util.o tests/tpm-emu.o $(test-io-obj-y)
|
||||
tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
|
||||
tests/io-channel-helpers.o $(test-io-obj-y)
|
||||
tests/test-io-channel-tls$(EXESUF): tests/test-io-channel-tls.o \
|
||||
diff --git a/tests/tpm-tis-device-swtpm-test.c b/tests/tpm-tis-device-swtpm-test.c
|
||||
new file mode 100644
|
||||
index 00000000..7b200351
|
||||
--- /dev/null
|
||||
+++ b/tests/tpm-tis-device-swtpm-test.c
|
||||
@@ -0,0 +1,76 @@
|
||||
+/*
|
||||
+ * QTest testcase for Sysbus TPM TIS talking to external swtpm and swtpm
|
||||
+ * migration
|
||||
+ *
|
||||
+ * Copyright (c) 2018 IBM Corporation
|
||||
+ * with parts borrowed from migration-test.c that is:
|
||||
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include <glib/gstdio.h>
|
||||
+
|
||||
+#include "libqtest.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "tpm-tests.h"
|
||||
+#include "hw/acpi/tpm.h"
|
||||
+
|
||||
+uint64_t tpm_tis_base_addr = 0xc000000;
|
||||
+#define MACHINE_OPTIONS "-machine virt,gic-version=max -accel tcg"
|
||||
+
|
||||
+typedef struct TestState {
|
||||
+ char *src_tpm_path;
|
||||
+ char *dst_tpm_path;
|
||||
+ char *uri;
|
||||
+} TestState;
|
||||
+
|
||||
+static void tpm_tis_swtpm_test(const void *data)
|
||||
+{
|
||||
+ const TestState *ts = data;
|
||||
+
|
||||
+ tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer,
|
||||
+ "tpm-tis-device", MACHINE_OPTIONS);
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_swtpm_migration_test(const void *data)
|
||||
+{
|
||||
+ const TestState *ts = data;
|
||||
+
|
||||
+ tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
|
||||
+ tpm_util_tis_transfer, "tpm-tis-device",
|
||||
+ MACHINE_OPTIONS);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ int ret;
|
||||
+ TestState ts = { 0 };
|
||||
+
|
||||
+ ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XXXXXX",
|
||||
+ NULL);
|
||||
+ ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-tis-device-swtpm-test.XXXXXX",
|
||||
+ NULL);
|
||||
+ ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path);
|
||||
+
|
||||
+ module_call_init(MODULE_INIT_QOM);
|
||||
+ g_test_init(&argc, &argv, NULL);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm/tis-swtpm/test", &ts, tpm_tis_swtpm_test);
|
||||
+ qtest_add_data_func("/tpm/tis-swtpm-migration/test", &ts,
|
||||
+ tpm_tis_swtpm_migration_test);
|
||||
+ ret = g_test_run();
|
||||
+
|
||||
+ g_rmdir(ts.dst_tpm_path);
|
||||
+ g_free(ts.dst_tpm_path);
|
||||
+ g_rmdir(ts.src_tpm_path);
|
||||
+ g_free(ts.src_tpm_path);
|
||||
+ g_free(ts.uri);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/tests/tpm-tis-device-test.c b/tests/tpm-tis-device-test.c
|
||||
new file mode 100644
|
||||
index 00000000..63ed3644
|
||||
--- /dev/null
|
||||
+++ b/tests/tpm-tis-device-test.c
|
||||
@@ -0,0 +1,87 @@
|
||||
+/*
|
||||
+ * QTest testcase for SYSBUS TPM TIS
|
||||
+ *
|
||||
+ * Copyright (c) 2018 Red Hat, Inc.
|
||||
+ * Copyright (c) 2018 IBM Corporation
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
+ * Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include <glib/gstdio.h>
|
||||
+
|
||||
+#include "io/channel-socket.h"
|
||||
+#include "libqtest-single.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "tpm-emu.h"
|
||||
+#include "tpm-util.h"
|
||||
+#include "tpm-tis-util.h"
|
||||
+
|
||||
+/*
|
||||
+ * As the Sysbus tpm-tis-device is instantiated on the ARM virt
|
||||
+ * platform bus and it is the only sysbus device dynamically
|
||||
+ * instantiated, it gets plugged at its base address
|
||||
+ */
|
||||
+uint64_t tpm_tis_base_addr = 0xc000000;
|
||||
+
|
||||
+int main(int argc, char **argv)
|
||||
+{
|
||||
+ char *tmp_path = g_dir_make_tmp("qemu-tpm-tis-device-test.XXXXXX", NULL);
|
||||
+ GThread *thread;
|
||||
+ TestState test;
|
||||
+ char *args;
|
||||
+ int ret;
|
||||
+
|
||||
+ module_call_init(MODULE_INIT_QOM);
|
||||
+ g_test_init(&argc, &argv, NULL);
|
||||
+
|
||||
+ test.addr = g_new0(SocketAddress, 1);
|
||||
+ test.addr->type = SOCKET_ADDRESS_TYPE_UNIX;
|
||||
+ test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL);
|
||||
+ g_mutex_init(&test.data_mutex);
|
||||
+ g_cond_init(&test.data_cond);
|
||||
+ test.data_cond_signal = false;
|
||||
+
|
||||
+ thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
|
||||
+ tpm_emu_test_wait_cond(&test);
|
||||
+
|
||||
+ args = g_strdup_printf(
|
||||
+ "-machine virt,gic-version=max -accel tcg "
|
||||
+ "-chardev socket,id=chr,path=%s "
|
||||
+ "-tpmdev emulator,id=dev,chardev=chr "
|
||||
+ "-device tpm-tis-device,tpmdev=dev",
|
||||
+ test.addr->u.q_unix.path);
|
||||
+ qtest_start(args);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm-tis/test_check_localities", &test,
|
||||
+ tpm_tis_test_check_localities);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm-tis/test_check_access_reg", &test,
|
||||
+ tpm_tis_test_check_access_reg);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm-tis/test_check_access_reg_seize", &test,
|
||||
+ tpm_tis_test_check_access_reg_seize);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm-tis/test_check_access_reg_release", &test,
|
||||
+ tpm_tis_test_check_access_reg_release);
|
||||
+
|
||||
+ qtest_add_data_func("/tpm-tis/test_check_transmit", &test,
|
||||
+ tpm_tis_test_check_transmit);
|
||||
+
|
||||
+ ret = g_test_run();
|
||||
+
|
||||
+ qtest_end();
|
||||
+
|
||||
+ g_thread_join(thread);
|
||||
+ g_unlink(test.addr->u.q_unix.path);
|
||||
+ qapi_free_SocketAddress(test.addr);
|
||||
+ g_rmdir(tmp_path);
|
||||
+ g_free(tmp_path);
|
||||
+ g_free(args);
|
||||
+ return ret;
|
||||
+}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
1044
test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch
Normal file
1044
test-tpm-tis-Get-prepared-to-share-tests-between-ISA.patch
Normal file
File diff suppressed because it is too large
Load Diff
231
tpm-Add-the-SysBus-TPM-TIS-device.patch
Normal file
231
tpm-Add-the-SysBus-TPM-TIS-device.patch
Normal file
@ -0,0 +1,231 @@
|
||||
From 4fe655326eeae322b621dcc25c53af722d2e1afa Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 Aug 2020 11:23:34 +0800
|
||||
Subject: [PATCH 14/19] tpm: Add the SysBus TPM TIS device
|
||||
|
||||
Introduce the tpm-tis-device which is a sysbus device
|
||||
and is bound to be used on ARM.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Message-id: 20200305165149.618-6-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/Kconfig | 5 ++
|
||||
hw/tpm/Makefile.objs | 1 +
|
||||
hw/tpm/tpm_tis_sysbus.c | 159 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/sysemu/tpm.h | 1 +
|
||||
4 files changed, 166 insertions(+)
|
||||
create mode 100644 hw/tpm/tpm_tis_sysbus.c
|
||||
|
||||
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
|
||||
index 686f8206..4794e7fe 100644
|
||||
--- a/hw/tpm/Kconfig
|
||||
+++ b/hw/tpm/Kconfig
|
||||
@@ -7,6 +7,11 @@ config TPM_TIS_ISA
|
||||
depends on TPM && ISA_BUS
|
||||
select TPM_TIS
|
||||
|
||||
+config TPM_TIS_SYSBUS
|
||||
+ bool
|
||||
+ depends on TPM
|
||||
+ select TPM_TIS
|
||||
+
|
||||
config TPM_TIS
|
||||
bool
|
||||
depends on TPM
|
||||
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
|
||||
index 3ef2036c..f1ec4beb 100644
|
||||
--- a/hw/tpm/Makefile.objs
|
||||
+++ b/hw/tpm/Makefile.objs
|
||||
@@ -1,6 +1,7 @@
|
||||
common-obj-$(CONFIG_TPM) += tpm_util.o
|
||||
obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
|
||||
common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
|
||||
+common-obj-$(CONFIG_TPM_TIS_SYSBUS) += tpm_tis_sysbus.o
|
||||
common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
|
||||
common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
|
||||
common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
|
||||
diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c
|
||||
new file mode 100644
|
||||
index 00000000..18c02aed
|
||||
--- /dev/null
|
||||
+++ b/hw/tpm/tpm_tis_sysbus.c
|
||||
@@ -0,0 +1,159 @@
|
||||
+/*
|
||||
+ * tpm_tis_sysbus.c - QEMU's TPM TIS SYSBUS Device
|
||||
+ *
|
||||
+ * Copyright (C) 2006,2010-2013 IBM Corporation
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Stefan Berger <stefanb@us.ibm.com>
|
||||
+ * David Safford <safford@us.ibm.com>
|
||||
+ *
|
||||
+ * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ *
|
||||
+ * Implementation of the TIS interface according to specs found at
|
||||
+ * http://www.trustedcomputinggroup.org. This implementation currently
|
||||
+ * supports version 1.3, 21 March 2013
|
||||
+ * In the developers menu choose the PC Client section then find the TIS
|
||||
+ * specification.
|
||||
+ *
|
||||
+ * TPM TIS for TPM 2 implementation following TCG PC Client Platform
|
||||
+ * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+#include "tpm_util.h"
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "tpm_tis.h"
|
||||
+
|
||||
+typedef struct TPMStateSysBus {
|
||||
+ /*< private >*/
|
||||
+ SysBusDevice parent_obj;
|
||||
+
|
||||
+ /*< public >*/
|
||||
+ TPMState state; /* not a QOM object */
|
||||
+} TPMStateSysBus;
|
||||
+
|
||||
+#define TPM_TIS_SYSBUS(obj) OBJECT_CHECK(TPMStateSysBus, (obj), TYPE_TPM_TIS_SYSBUS)
|
||||
+
|
||||
+static int tpm_tis_pre_save_sysbus(void *opaque)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = opaque;
|
||||
+
|
||||
+ return tpm_tis_pre_save(&sbdev->state);
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_tpm_tis_sysbus = {
|
||||
+ .name = "tpm-tis",
|
||||
+ .version_id = 0,
|
||||
+ .pre_save = tpm_tis_pre_save_sysbus,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_BUFFER(state.buffer, TPMStateSysBus),
|
||||
+ VMSTATE_UINT16(state.rw_offset, TPMStateSysBus),
|
||||
+ VMSTATE_UINT8(state.active_locty, TPMStateSysBus),
|
||||
+ VMSTATE_UINT8(state.aborting_locty, TPMStateSysBus),
|
||||
+ VMSTATE_UINT8(state.next_locty, TPMStateSysBus),
|
||||
+
|
||||
+ VMSTATE_STRUCT_ARRAY(state.loc, TPMStateSysBus, TPM_TIS_NUM_LOCALITIES,
|
||||
+ 0, vmstate_locty, TPMLocality),
|
||||
+
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void tpm_tis_sysbus_request_completed(TPMIf *ti, int ret)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
|
||||
+ TPMState *s = &sbdev->state;
|
||||
+
|
||||
+ tpm_tis_request_completed(s, ret);
|
||||
+}
|
||||
+
|
||||
+static enum TPMVersion tpm_tis_sysbus_get_tpm_version(TPMIf *ti)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(ti);
|
||||
+ TPMState *s = &sbdev->state;
|
||||
+
|
||||
+ return tpm_tis_get_tpm_version(s);
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_sysbus_reset(DeviceState *dev)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
|
||||
+ TPMState *s = &sbdev->state;
|
||||
+
|
||||
+ return tpm_tis_reset(s);
|
||||
+}
|
||||
+
|
||||
+static Property tpm_tis_sysbus_properties[] = {
|
||||
+ DEFINE_PROP_UINT32("irq", TPMStateSysBus, state.irq_num, TPM_TIS_IRQ),
|
||||
+ DEFINE_PROP_TPMBE("tpmdev", TPMStateSysBus, state.be_driver),
|
||||
+ DEFINE_PROP_BOOL("ppi", TPMStateSysBus, state.ppi_enabled, true),
|
||||
+ DEFINE_PROP_END_OF_LIST(),
|
||||
+};
|
||||
+
|
||||
+static void tpm_tis_sysbus_initfn(Object *obj)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(obj);
|
||||
+ TPMState *s = &sbdev->state;
|
||||
+
|
||||
+ memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
|
||||
+ s, "tpm-tis-mmio",
|
||||
+ TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
|
||||
+
|
||||
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
|
||||
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ TPMStateSysBus *sbdev = TPM_TIS_SYSBUS(dev);
|
||||
+ TPMState *s = &sbdev->state;
|
||||
+
|
||||
+ if (!tpm_find()) {
|
||||
+ error_setg(errp, "at most one TPM device is permitted");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!s->be_driver) {
|
||||
+ error_setg(errp, "'tpmdev' property is required");
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_sysbus_class_init(ObjectClass *klass, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
+ TPMIfClass *tc = TPM_IF_CLASS(klass);
|
||||
+
|
||||
+ dc->props = tpm_tis_sysbus_properties;
|
||||
+ dc->vmsd = &vmstate_tpm_tis_sysbus;
|
||||
+ tc->model = TPM_MODEL_TPM_TIS;
|
||||
+ dc->realize = tpm_tis_sysbus_realizefn;
|
||||
+ dc->user_creatable = true;
|
||||
+ dc->reset = tpm_tis_sysbus_reset;
|
||||
+ tc->request_completed = tpm_tis_sysbus_request_completed;
|
||||
+ tc->get_version = tpm_tis_sysbus_get_tpm_version;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo tpm_tis_sysbus_info = {
|
||||
+ .name = TYPE_TPM_TIS_SYSBUS,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(TPMStateSysBus),
|
||||
+ .instance_init = tpm_tis_sysbus_initfn,
|
||||
+ .class_init = tpm_tis_sysbus_class_init,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_TPM_IF },
|
||||
+ { }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void tpm_tis_sysbus_register(void)
|
||||
+{
|
||||
+ type_register_static(&tpm_tis_sysbus_info);
|
||||
+}
|
||||
+
|
||||
+type_init(tpm_tis_sysbus_register)
|
||||
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
|
||||
index 1691b92c..f37851b1 100644
|
||||
--- a/include/sysemu/tpm.h
|
||||
+++ b/include/sysemu/tpm.h
|
||||
@@ -44,6 +44,7 @@ typedef struct TPMIfClass {
|
||||
} TPMIfClass;
|
||||
|
||||
#define TYPE_TPM_TIS_ISA "tpm-tis"
|
||||
+#define TYPE_TPM_TIS_SYSBUS "tpm-tis-device"
|
||||
#define TYPE_TPM_CRB "tpm-crb"
|
||||
#define TYPE_TPM_SPAPR "tpm-spapr"
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
146
tpm-Move-tpm_tis_show_buffer-to-tpm_util.c.patch
Normal file
146
tpm-Move-tpm_tis_show_buffer-to-tpm_util.c.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From c6cf45f38cb6e28cf4db42296fedcd5f26ca610b Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:30 -0500
|
||||
Subject: [PATCH 03/19] tpm: Move tpm_tis_show_buffer to tpm_util.c
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Message-Id: <20200121152935.649898-2-stefanb@linux.ibm.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/tpm_tis.c | 32 ++++----------------------------
|
||||
hw/tpm/tpm_util.c | 25 +++++++++++++++++++++++++
|
||||
hw/tpm/tpm_util.h | 3 +++
|
||||
hw/tpm/trace-events | 2 +-
|
||||
4 files changed, 33 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
|
||||
index d6b32128..96a9ac48 100644
|
||||
--- a/hw/tpm/tpm_tis.c
|
||||
+++ b/hw/tpm/tpm_tis.c
|
||||
@@ -104,30 +104,6 @@ static uint8_t tpm_tis_locality_from_addr(hwaddr addr)
|
||||
return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7);
|
||||
}
|
||||
|
||||
-static void tpm_tis_show_buffer(const unsigned char *buffer,
|
||||
- size_t buffer_size, const char *string)
|
||||
-{
|
||||
- size_t len, i;
|
||||
- char *line_buffer, *p;
|
||||
-
|
||||
- len = MIN(tpm_cmd_get_size(buffer), buffer_size);
|
||||
-
|
||||
- /*
|
||||
- * allocate enough room for 3 chars per buffer entry plus a
|
||||
- * newline after every 16 chars and a final null terminator.
|
||||
- */
|
||||
- line_buffer = g_malloc(len * 3 + (len / 16) + 1);
|
||||
-
|
||||
- for (i = 0, p = line_buffer; i < len; i++) {
|
||||
- if (i && !(i % 16)) {
|
||||
- p += sprintf(p, "\n");
|
||||
- }
|
||||
- p += sprintf(p, "%.2X ", buffer[i]);
|
||||
- }
|
||||
- trace_tpm_tis_show_buffer(string, len, line_buffer);
|
||||
-
|
||||
- g_free(line_buffer);
|
||||
-}
|
||||
|
||||
/*
|
||||
* Set the given flags in the STS register by clearing the register but
|
||||
@@ -153,8 +129,8 @@ static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
|
||||
*/
|
||||
static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
|
||||
{
|
||||
- if (trace_event_get_state_backends(TRACE_TPM_TIS_SHOW_BUFFER)) {
|
||||
- tpm_tis_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
|
||||
+ if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
|
||||
+ tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -322,8 +298,8 @@ static void tpm_tis_request_completed(TPMIf *ti, int ret)
|
||||
s->loc[locty].state = TPM_TIS_STATE_COMPLETION;
|
||||
s->rw_offset = 0;
|
||||
|
||||
- if (trace_event_get_state_backends(TRACE_TPM_TIS_SHOW_BUFFER)) {
|
||||
- tpm_tis_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
|
||||
+ if (trace_event_get_state_backends(TRACE_TPM_UTIL_SHOW_BUFFER)) {
|
||||
+ tpm_util_show_buffer(s->buffer, s->be_buffer_size, "From TPM");
|
||||
}
|
||||
|
||||
if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) {
|
||||
diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
|
||||
index ee41757e..8643eb50 100644
|
||||
--- a/hw/tpm/tpm_util.c
|
||||
+++ b/hw/tpm/tpm_util.c
|
||||
@@ -350,3 +350,28 @@ void tpm_sized_buffer_reset(TPMSizedBuffer *tsb)
|
||||
tsb->buffer = NULL;
|
||||
tsb->size = 0;
|
||||
}
|
||||
+
|
||||
+void tpm_util_show_buffer(const unsigned char *buffer,
|
||||
+ size_t buffer_size, const char *string)
|
||||
+{
|
||||
+ size_t len, i;
|
||||
+ char *line_buffer, *p;
|
||||
+
|
||||
+ len = MIN(tpm_cmd_get_size(buffer), buffer_size);
|
||||
+
|
||||
+ /*
|
||||
+ * allocate enough room for 3 chars per buffer entry plus a
|
||||
+ * newline after every 16 chars and a final null terminator.
|
||||
+ */
|
||||
+ line_buffer = g_malloc(len * 3 + (len / 16) + 1);
|
||||
+
|
||||
+ for (i = 0, p = line_buffer; i < len; i++) {
|
||||
+ if (i && !(i % 16)) {
|
||||
+ p += sprintf(p, "\n");
|
||||
+ }
|
||||
+ p += sprintf(p, "%.2X ", buffer[i]);
|
||||
+ }
|
||||
+ trace_tpm_util_show_buffer(string, len, line_buffer);
|
||||
+
|
||||
+ g_free(line_buffer);
|
||||
+}
|
||||
diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
|
||||
index f397ac21..7889081f 100644
|
||||
--- a/hw/tpm/tpm_util.h
|
||||
+++ b/hw/tpm/tpm_util.h
|
||||
@@ -79,4 +79,7 @@ typedef struct TPMSizedBuffer {
|
||||
|
||||
void tpm_sized_buffer_reset(TPMSizedBuffer *tsb);
|
||||
|
||||
+void tpm_util_show_buffer(const unsigned char *buffer,
|
||||
+ size_t buffer_size, const char *string);
|
||||
+
|
||||
#endif /* TPM_TPM_UTIL_H */
|
||||
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
|
||||
index 0b94aa15..82c45ee5 100644
|
||||
--- a/hw/tpm/trace-events
|
||||
+++ b/hw/tpm/trace-events
|
||||
@@ -14,6 +14,7 @@ tpm_util_get_buffer_size_len(uint32_t len, size_t expected) "tpm_resp->len = %u,
|
||||
tpm_util_get_buffer_size_hdr_len2(uint32_t len, size_t expected) "tpm2_resp->hdr.len = %u, expected = %zu"
|
||||
tpm_util_get_buffer_size_len2(uint32_t len, size_t expected) "tpm2_resp->len = %u, expected = %zu"
|
||||
tpm_util_get_buffer_size(size_t len) "buffersize of device: %zu"
|
||||
+tpm_util_show_buffer(const char *direction, size_t len, const char *buf) "direction: %s len: %zu\n%s"
|
||||
|
||||
# tpm_emulator.c
|
||||
tpm_emulator_set_locality(uint8_t locty) "setting locality to %d"
|
||||
@@ -36,7 +37,6 @@ tpm_emulator_pre_save(void) ""
|
||||
tpm_emulator_inst_init(void) ""
|
||||
|
||||
# tpm_tis.c
|
||||
-tpm_tis_show_buffer(const char *direction, size_t len, const char *buf) "direction: %s len: %zu\nbuf: %s"
|
||||
tpm_tis_raise_irq(uint32_t irqmask) "Raising IRQ for flag 0x%08x"
|
||||
tpm_tis_new_active_locality(uint8_t locty) "Active locality is now %d"
|
||||
tpm_tis_abort(uint8_t locty) "New active locality is %d"
|
||||
--
|
||||
2.23.0
|
||||
|
||||
108
tpm-Separate-TPM_TIS-and-TPM_TIS_ISA-configs.patch
Normal file
108
tpm-Separate-TPM_TIS-and-TPM_TIS_ISA-configs.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 1eca7dbacabbc8ccc737f320839e7800fef5dfa1 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 Aug 2020 12:42:31 +0800
|
||||
Subject: [PATCH 13/19] tpm: Separate TPM_TIS and TPM_TIS_ISA configs
|
||||
MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Let's separate the compilation of tpm_tis_common.c from
|
||||
the compilation of tpm_tis_isa.c
|
||||
|
||||
The common part will be also compiled along with the
|
||||
tpm_tis_sysbus device.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Message-id: 20200305165149.618-5-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
default-configs/i386-softmmu.mak | 2 +-
|
||||
hw/i386/Kconfig | 2 +-
|
||||
hw/tpm/Kconfig | 7 ++++++-
|
||||
hw/tpm/Makefile.objs | 3 ++-
|
||||
tests/Makefile.include | 4 ++--
|
||||
5 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
|
||||
index cd5ea391..bdeef670 100644
|
||||
--- a/default-configs/i386-softmmu.mak
|
||||
+++ b/default-configs/i386-softmmu.mak
|
||||
@@ -17,7 +17,7 @@
|
||||
#CONFIG_SGA=n
|
||||
#CONFIG_TEST_DEVICES=n
|
||||
#CONFIG_TPM_CRB=n
|
||||
-#CONFIG_TPM_TIS=n
|
||||
+#CONFIG_TPM_TIS_ISA=n
|
||||
#CONFIG_VTD=n
|
||||
|
||||
# Boards:
|
||||
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
|
||||
index 63504380..60334504 100644
|
||||
--- a/hw/i386/Kconfig
|
||||
+++ b/hw/i386/Kconfig
|
||||
@@ -17,7 +17,7 @@ config PC
|
||||
imply SGA
|
||||
imply TEST_DEVICES
|
||||
imply TPM_CRB
|
||||
- imply TPM_TIS
|
||||
+ imply TPM_TIS_ISA
|
||||
imply VGA_PCI
|
||||
imply VIRTIO_VGA
|
||||
select FDC
|
||||
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
|
||||
index 9e67d990..686f8206 100644
|
||||
--- a/hw/tpm/Kconfig
|
||||
+++ b/hw/tpm/Kconfig
|
||||
@@ -2,9 +2,14 @@ config TPMDEV
|
||||
bool
|
||||
depends on TPM
|
||||
|
||||
-config TPM_TIS
|
||||
+config TPM_TIS_ISA
|
||||
bool
|
||||
depends on TPM && ISA_BUS
|
||||
+ select TPM_TIS
|
||||
+
|
||||
+config TPM_TIS
|
||||
+ bool
|
||||
+ depends on TPM
|
||||
select TPMDEV
|
||||
|
||||
config TPM_CRB
|
||||
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
|
||||
index fcc4c2f2..3ef2036c 100644
|
||||
--- a/hw/tpm/Makefile.objs
|
||||
+++ b/hw/tpm/Makefile.objs
|
||||
@@ -1,6 +1,7 @@
|
||||
common-obj-$(CONFIG_TPM) += tpm_util.o
|
||||
obj-$(call lor,$(CONFIG_TPM_TIS),$(CONFIG_TPM_CRB)) += tpm_ppi.o
|
||||
-common-obj-$(CONFIG_TPM_TIS) += tpm_tis_isa.o tpm_tis_common.o
|
||||
+common-obj-$(CONFIG_TPM_TIS_ISA) += tpm_tis_isa.o
|
||||
+common-obj-$(CONFIG_TPM_TIS) += tpm_tis_common.o
|
||||
common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
|
||||
common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
|
||||
common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
|
||||
diff --git a/tests/Makefile.include b/tests/Makefile.include
|
||||
index f3273ad3..c151de64 100644
|
||||
--- a/tests/Makefile.include
|
||||
+++ b/tests/Makefile.include
|
||||
@@ -190,8 +190,8 @@ check-qtest-i386-y += tests/q35-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-swtpm-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-test$(EXESUF)
|
||||
-check-qtest-i386-$(CONFIG_TPM_TIS) += tests/tpm-tis-swtpm-test$(EXESUF)
|
||||
-check-qtest-i386-$(CONFIG_TPM_TIS) += tests/tpm-tis-test$(EXESUF)
|
||||
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tests/tpm-tis-swtpm-test$(EXESUF)
|
||||
+check-qtest-i386-$(CONFIG_TPM_TIS_ISA) += tests/tpm-tis-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_RTL8139_PCI) += tests/test-filter-redirector$(EXESUF)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
1194
tpm-Separate-tpm_tis-common-functions-from-isa-code.patch
Normal file
1194
tpm-Separate-tpm_tis-common-functions-from-isa-code.patch
Normal file
File diff suppressed because it is too large
Load Diff
314
tpm-Use-TPMState-as-a-common-struct.patch
Normal file
314
tpm-Use-TPMState-as-a-common-struct.patch
Normal file
@ -0,0 +1,314 @@
|
||||
From c57e57c86f9d3c13b33746436bc1f09db88d4d42 Mon Sep 17 00:00:00 2001
|
||||
From: jiangfangjie <jiangfangjie@huawei.com>
|
||||
Date: Tue, 11 Aug 2020 02:52:12 +0000
|
||||
Subject: [PATCH 11/19] tpm: Use TPMState as a common struct
|
||||
|
||||
As we plan to introduce a SysBus TPM TIS device, let's
|
||||
make the TPMState a common struct usable by both the
|
||||
ISADevice and the SysBusDevice. TPMStateISA embeds the
|
||||
struct and inherits from the ISADevice.
|
||||
|
||||
The prototype of functions bound to be used by both
|
||||
the ISA and SysBus devices is changed to take TPMState
|
||||
handle.
|
||||
|
||||
A bunch of structs also are renamed to be specialized
|
||||
for the ISA device. Besides those transformations, no
|
||||
functional change is expected.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Message-id: 20200305165149.618-3-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/tpm_tis.c | 147 +++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 92 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
|
||||
index 49d44652..735a528f 100644
|
||||
--- a/hw/tpm/tpm_tis.c
|
||||
+++ b/hw/tpm/tpm_tis.c
|
||||
@@ -62,7 +62,6 @@ typedef struct TPMLocality {
|
||||
} TPMLocality;
|
||||
|
||||
typedef struct TPMState {
|
||||
- ISADevice busdev;
|
||||
MemoryRegion mmio;
|
||||
|
||||
unsigned char buffer[TPM_TIS_BUFFER_MAX];
|
||||
@@ -88,7 +87,15 @@ typedef struct TPMState {
|
||||
TPMPPI ppi;
|
||||
} TPMState;
|
||||
|
||||
-#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS_ISA)
|
||||
+typedef struct TPMStateISA {
|
||||
+ /*< private >*/
|
||||
+ ISADevice parent_obj;
|
||||
+
|
||||
+ /*< public >*/
|
||||
+ TPMState state; /* not a QOM object */
|
||||
+} TPMStateISA;
|
||||
+
|
||||
+#define TPM_TIS_ISA(obj) OBJECT_CHECK(TPMStateISA, (obj), TYPE_TPM_TIS_ISA)
|
||||
|
||||
#define DEBUG_TIS 0
|
||||
|
||||
@@ -278,9 +285,8 @@ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty)
|
||||
/*
|
||||
* Callback from the TPM to indicate that the response was received.
|
||||
*/
|
||||
-static void tpm_tis_request_completed(TPMIf *ti, int ret)
|
||||
+static void tpm_tis_request_completed(TPMState *s, int ret)
|
||||
{
|
||||
- TPMState *s = TPM(ti);
|
||||
uint8_t locty = s->cmd.locty;
|
||||
uint8_t l;
|
||||
|
||||
@@ -335,7 +341,7 @@ static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TIS
|
||||
-static void tpm_tis_dump_state(void *opaque, hwaddr addr)
|
||||
+static void tpm_tis_dump_state(TPMState *s, hwaddr addr)
|
||||
{
|
||||
static const unsigned regs[] = {
|
||||
TPM_TIS_REG_ACCESS,
|
||||
@@ -350,7 +356,6 @@ static void tpm_tis_dump_state(void *opaque, hwaddr addr)
|
||||
int idx;
|
||||
uint8_t locty = tpm_tis_locality_from_addr(addr);
|
||||
hwaddr base = addr & ~0xfff;
|
||||
- TPMState *s = opaque;
|
||||
|
||||
printf("tpm_tis: active locality : %d\n"
|
||||
"tpm_tis: state of locality %d : %d\n"
|
||||
@@ -360,7 +365,7 @@ static void tpm_tis_dump_state(void *opaque, hwaddr addr)
|
||||
|
||||
for (idx = 0; regs[idx] != 0xfff; idx++) {
|
||||
printf("tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
|
||||
- (int)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
|
||||
+ (int)tpm_tis_mmio_read(s, base + regs[idx], 4));
|
||||
}
|
||||
|
||||
printf("tpm_tis: r/w offset : %d\n"
|
||||
@@ -485,7 +490,7 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
|
||||
break;
|
||||
#ifdef DEBUG_TIS
|
||||
case TPM_TIS_REG_DEBUG:
|
||||
- tpm_tis_dump_state(opaque, addr);
|
||||
+ tpm_tis_dump_state(s, addr);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@@ -832,10 +837,8 @@ static const MemoryRegionOps tpm_tis_memory_ops = {
|
||||
/*
|
||||
* Get the TPMVersion of the backend device being used
|
||||
*/
|
||||
-static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
|
||||
+static enum TPMVersion tpm_tis_get_tpm_version(TPMState *s)
|
||||
{
|
||||
- TPMState *s = TPM(ti);
|
||||
-
|
||||
if (tpm_backend_had_startup_error(s->be_driver)) {
|
||||
return TPM_VERSION_UNSPEC;
|
||||
}
|
||||
@@ -847,9 +850,8 @@ static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti)
|
||||
* This function is called when the machine starts, resets or due to
|
||||
* S3 resume.
|
||||
*/
|
||||
-static void tpm_tis_reset(DeviceState *dev)
|
||||
+static void tpm_tis_reset(TPMState *s)
|
||||
{
|
||||
- TPMState *s = TPM(dev);
|
||||
int c;
|
||||
|
||||
s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
|
||||
@@ -893,15 +895,14 @@ static void tpm_tis_reset(DeviceState *dev)
|
||||
|
||||
/* persistent state handling */
|
||||
|
||||
-static int tpm_tis_pre_save(void *opaque)
|
||||
+static int tpm_tis_pre_save(TPMState *s)
|
||||
{
|
||||
- TPMState *s = opaque;
|
||||
uint8_t locty = s->active_locty;
|
||||
|
||||
trace_tpm_tis_pre_save(locty, s->rw_offset);
|
||||
|
||||
if (DEBUG_TIS) {
|
||||
- tpm_tis_dump_state(opaque, 0);
|
||||
+ tpm_tis_dump_state(s, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -926,34 +927,78 @@ static const VMStateDescription vmstate_locty = {
|
||||
}
|
||||
};
|
||||
|
||||
-static const VMStateDescription vmstate_tpm_tis = {
|
||||
+/* ISA */
|
||||
+
|
||||
+static int tpm_tis_pre_save_isa(void *opaque)
|
||||
+{
|
||||
+ TPMStateISA *isadev = opaque;
|
||||
+
|
||||
+ return tpm_tis_pre_save(&isadev->state);
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_tpm_tis_isa = {
|
||||
.name = "tpm-tis",
|
||||
.version_id = 0,
|
||||
- .pre_save = tpm_tis_pre_save,
|
||||
+ .pre_save = tpm_tis_pre_save_isa,
|
||||
.fields = (VMStateField[]) {
|
||||
- VMSTATE_BUFFER(buffer, TPMState),
|
||||
- VMSTATE_UINT16(rw_offset, TPMState),
|
||||
- VMSTATE_UINT8(active_locty, TPMState),
|
||||
- VMSTATE_UINT8(aborting_locty, TPMState),
|
||||
- VMSTATE_UINT8(next_locty, TPMState),
|
||||
+ VMSTATE_BUFFER(state.buffer, TPMStateISA),
|
||||
+ VMSTATE_UINT16(state.rw_offset, TPMStateISA),
|
||||
+ VMSTATE_UINT8(state.active_locty, TPMStateISA),
|
||||
+ VMSTATE_UINT8(state.aborting_locty, TPMStateISA),
|
||||
+ VMSTATE_UINT8(state.next_locty, TPMStateISA),
|
||||
|
||||
- VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 0,
|
||||
+ VMSTATE_STRUCT_ARRAY(state.loc, TPMStateISA, TPM_TIS_NUM_LOCALITIES, 0,
|
||||
vmstate_locty, TPMLocality),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
-static Property tpm_tis_properties[] = {
|
||||
- DEFINE_PROP_UINT32("irq", TPMState, irq_num, TPM_TIS_IRQ),
|
||||
- DEFINE_PROP_TPMBE("tpmdev", TPMState, be_driver),
|
||||
- DEFINE_PROP_BOOL("ppi", TPMState, ppi_enabled, true),
|
||||
+static void tpm_tis_isa_request_completed(TPMIf *ti, int ret)
|
||||
+{
|
||||
+ TPMStateISA *isadev = TPM_TIS_ISA(ti);
|
||||
+ TPMState *s = &isadev->state;
|
||||
+
|
||||
+ tpm_tis_request_completed(s, ret);
|
||||
+}
|
||||
+
|
||||
+static enum TPMVersion tpm_tis_isa_get_tpm_version(TPMIf *ti)
|
||||
+{
|
||||
+ TPMStateISA *isadev = TPM_TIS_ISA(ti);
|
||||
+ TPMState *s = &isadev->state;
|
||||
+
|
||||
+ return tpm_tis_get_tpm_version(s);
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_isa_reset(DeviceState *dev)
|
||||
+{
|
||||
+ TPMStateISA *isadev = TPM_TIS_ISA(dev);
|
||||
+ TPMState *s = &isadev->state;
|
||||
+
|
||||
+ return tpm_tis_reset(s);
|
||||
+}
|
||||
+
|
||||
+static Property tpm_tis_isa_properties[] = {
|
||||
+ DEFINE_PROP_UINT32("irq", TPMStateISA, state.irq_num, TPM_TIS_IRQ),
|
||||
+ DEFINE_PROP_TPMBE("tpmdev", TPMStateISA, state.be_driver),
|
||||
+ DEFINE_PROP_BOOL("ppi", TPMStateISA, state.ppi_enabled, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
-static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
|
||||
+static void tpm_tis_isa_initfn(Object *obj)
|
||||
{
|
||||
- TPMState *s = TPM(dev);
|
||||
+ TPMStateISA *isadev = TPM_TIS_ISA(obj);
|
||||
+ TPMState *s = &isadev->state;
|
||||
+
|
||||
+ memory_region_init_io(&s->mmio, obj, &tpm_tis_memory_ops,
|
||||
+ s, "tpm-tis-mmio",
|
||||
+ TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
|
||||
+}
|
||||
+
|
||||
+static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ TPMStateISA *isadev = TPM_TIS_ISA(dev);
|
||||
+ TPMState *s = &isadev->state;
|
||||
|
||||
if (!tpm_find()) {
|
||||
error_setg(errp, "at most one TPM device is permitted");
|
||||
@@ -970,55 +1015,47 @@ static void tpm_tis_realizefn(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
- isa_init_irq(&s->busdev, &s->irq, s->irq_num);
|
||||
+ isa_init_irq(ISA_DEVICE(dev), &s->irq, s->irq_num);
|
||||
|
||||
memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
|
||||
TPM_TIS_ADDR_BASE, &s->mmio);
|
||||
|
||||
if (s->ppi_enabled) {
|
||||
tpm_ppi_init(&s->ppi, isa_address_space(ISA_DEVICE(dev)),
|
||||
- TPM_PPI_ADDR_BASE, OBJECT(s));
|
||||
+ TPM_PPI_ADDR_BASE, OBJECT(dev));
|
||||
}
|
||||
}
|
||||
|
||||
-static void tpm_tis_initfn(Object *obj)
|
||||
-{
|
||||
- TPMState *s = TPM(obj);
|
||||
-
|
||||
- memory_region_init_io(&s->mmio, OBJECT(s), &tpm_tis_memory_ops,
|
||||
- s, "tpm-tis-mmio",
|
||||
- TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);
|
||||
-}
|
||||
-
|
||||
-static void tpm_tis_class_init(ObjectClass *klass, void *data)
|
||||
+static void tpm_tis_isa_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
TPMIfClass *tc = TPM_IF_CLASS(klass);
|
||||
|
||||
- dc->realize = tpm_tis_realizefn;
|
||||
- dc->props = tpm_tis_properties;
|
||||
- dc->reset = tpm_tis_reset;
|
||||
- dc->vmsd = &vmstate_tpm_tis;
|
||||
+ dc->props = tpm_tis_isa_properties;
|
||||
+ dc->vmsd = &vmstate_tpm_tis_isa;
|
||||
tc->model = TPM_MODEL_TPM_TIS;
|
||||
- tc->get_version = tpm_tis_get_tpm_version;
|
||||
- tc->request_completed = tpm_tis_request_completed;
|
||||
+ dc->realize = tpm_tis_isa_realizefn;
|
||||
+ dc->reset = tpm_tis_isa_reset;
|
||||
+ tc->request_completed = tpm_tis_isa_request_completed;
|
||||
+ tc->get_version = tpm_tis_isa_get_tpm_version;
|
||||
+
|
||||
}
|
||||
|
||||
-static const TypeInfo tpm_tis_info = {
|
||||
+static const TypeInfo tpm_tis_isa_info = {
|
||||
.name = TYPE_TPM_TIS_ISA,
|
||||
.parent = TYPE_ISA_DEVICE,
|
||||
- .instance_size = sizeof(TPMState),
|
||||
- .instance_init = tpm_tis_initfn,
|
||||
- .class_init = tpm_tis_class_init,
|
||||
+ .instance_size = sizeof(TPMStateISA),
|
||||
+ .instance_init = tpm_tis_isa_initfn,
|
||||
+ .class_init = tpm_tis_isa_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_TPM_IF },
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
-static void tpm_tis_register(void)
|
||||
+static void tpm_tis_isa_register(void)
|
||||
{
|
||||
- type_register_static(&tpm_tis_info);
|
||||
+ type_register_static(&tpm_tis_isa_info);
|
||||
}
|
||||
|
||||
-type_init(tpm_tis_register)
|
||||
+type_init(tpm_tis_isa_register)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
43
tpm-ppi-page-align-PPI-RAM.patch
Normal file
43
tpm-ppi-page-align-PPI-RAM.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 26b54c545f253049faa633ff886132602ff47241 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||
Date: Fri, 3 Jan 2020 11:39:59 +0400
|
||||
Subject: [PATCH 02/19] tpm-ppi: page-align PPI RAM
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
post-copy migration fails on destination with error such as:
|
||||
2019-12-26T10:22:44.714644Z qemu-kvm: ram_block_discard_range:
|
||||
Unaligned start address: 0x559d2afae9a0
|
||||
|
||||
Use qemu_memalign() to constrain the PPI RAM memory alignment.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Message-id: 20200103074000.1006389-3-marcandre.lureau@redhat.com
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/tpm_ppi.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/tpm/tpm_ppi.c b/hw/tpm/tpm_ppi.c
|
||||
index cd8205f2..6509ffd4 100644
|
||||
--- a/hw/tpm/tpm_ppi.c
|
||||
+++ b/hw/tpm/tpm_ppi.c
|
||||
@@ -44,7 +44,8 @@ void tpm_ppi_reset(TPMPPI *tpmppi)
|
||||
void tpm_ppi_init(TPMPPI *tpmppi, struct MemoryRegion *m,
|
||||
hwaddr addr, Object *obj)
|
||||
{
|
||||
- tpmppi->buf = g_malloc0(HOST_PAGE_ALIGN(TPM_PPI_ADDR_SIZE));
|
||||
+ tpmppi->buf = qemu_memalign(qemu_real_host_page_size,
|
||||
+ HOST_PAGE_ALIGN(TPM_PPI_ADDR_SIZE));
|
||||
memory_region_init_ram_device_ptr(&tpmppi->ram, obj, "tpm-ppi",
|
||||
TPM_PPI_ADDR_SIZE, tpmppi->buf);
|
||||
vmstate_register_ram(&tpmppi->ram, DEVICE(obj));
|
||||
--
|
||||
2.23.0
|
||||
|
||||
101
tpm-rename-TPM_TIS-into-TPM_TIS_ISA.patch
Normal file
101
tpm-rename-TPM_TIS-into-TPM_TIS_ISA.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 7974f8ffd75171be106a1ce2705878abbb6c4477 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 5 Mar 2020 17:51:40 +0100
|
||||
Subject: [PATCH 10/19] tpm: rename TPM_TIS into TPM_TIS_ISA
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
As we plan to introduce a sysbus TPM_TIS, let's rename
|
||||
TPM_TIS into TPM_TIS_ISA.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
|
||||
Message-id: 20200305165149.618-2-eric.auger@redhat.com
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/i386/acpi-build.c | 6 +++---
|
||||
hw/tpm/tpm_tis.c | 4 ++--
|
||||
include/sysemu/tpm.h | 6 +++---
|
||||
3 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
|
||||
index c97731ec..093f7d93 100644
|
||||
--- a/hw/i386/acpi-build.c
|
||||
+++ b/hw/i386/acpi-build.c
|
||||
@@ -2007,7 +2007,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
}
|
||||
}
|
||||
|
||||
- if (TPM_IS_TIS(tpm_find())) {
|
||||
+ if (TPM_IS_TIS_ISA(tpm_find())) {
|
||||
aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
|
||||
TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
|
||||
}
|
||||
@@ -2178,7 +2178,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
/* Scan all PCI buses. Generate tables to support hotplug. */
|
||||
build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
|
||||
|
||||
- if (TPM_IS_TIS(tpm)) {
|
||||
+ if (TPM_IS_TIS_ISA(tpm)) {
|
||||
if (misc->tpm_version == TPM_VERSION_2_0) {
|
||||
dev = aml_device("TPM");
|
||||
aml_append(dev, aml_name_decl("_HID",
|
||||
@@ -2285,7 +2285,7 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
|
||||
(char *)&tpm2_ptr->log_area_start_address - table_data->data;
|
||||
|
||||
tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
|
||||
- if (TPM_IS_TIS(tpm_find())) {
|
||||
+ if (TPM_IS_TIS_ISA(tpm_find())) {
|
||||
tpm2_ptr->control_area_address = cpu_to_le64(0);
|
||||
tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
|
||||
} else if (TPM_IS_CRB(tpm_find())) {
|
||||
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
|
||||
index 96a9ac48..49d44652 100644
|
||||
--- a/hw/tpm/tpm_tis.c
|
||||
+++ b/hw/tpm/tpm_tis.c
|
||||
@@ -88,7 +88,7 @@ typedef struct TPMState {
|
||||
TPMPPI ppi;
|
||||
} TPMState;
|
||||
|
||||
-#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS)
|
||||
+#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS_ISA)
|
||||
|
||||
#define DEBUG_TIS 0
|
||||
|
||||
@@ -1005,7 +1005,7 @@ static void tpm_tis_class_init(ObjectClass *klass, void *data)
|
||||
}
|
||||
|
||||
static const TypeInfo tpm_tis_info = {
|
||||
- .name = TYPE_TPM_TIS,
|
||||
+ .name = TYPE_TPM_TIS_ISA,
|
||||
.parent = TYPE_ISA_DEVICE,
|
||||
.instance_size = sizeof(TPMState),
|
||||
.instance_init = tpm_tis_initfn,
|
||||
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
|
||||
index 15979a36..1691b92c 100644
|
||||
--- a/include/sysemu/tpm.h
|
||||
+++ b/include/sysemu/tpm.h
|
||||
@@ -43,12 +43,12 @@ typedef struct TPMIfClass {
|
||||
enum TPMVersion (*get_version)(TPMIf *obj);
|
||||
} TPMIfClass;
|
||||
|
||||
-#define TYPE_TPM_TIS "tpm-tis"
|
||||
+#define TYPE_TPM_TIS_ISA "tpm-tis"
|
||||
#define TYPE_TPM_CRB "tpm-crb"
|
||||
#define TYPE_TPM_SPAPR "tpm-spapr"
|
||||
|
||||
-#define TPM_IS_TIS(chr) \
|
||||
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
|
||||
+#define TPM_IS_TIS_ISA(chr) \
|
||||
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
|
||||
#define TPM_IS_CRB(chr) \
|
||||
object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
|
||||
#define TPM_IS_SPAPR(chr) \
|
||||
--
|
||||
2.23.0
|
||||
|
||||
552
tpm_spapr-Support-TPM-for-ppc64-using-CRQ-based-inte.patch
Normal file
552
tpm_spapr-Support-TPM-for-ppc64-using-CRQ-based-inte.patch
Normal file
@ -0,0 +1,552 @@
|
||||
From 14402a8ca57fb722eb324d141fafb41ef06f4c2b Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:32 -0500
|
||||
Subject: [PATCH 06/19] tpm_spapr: Support TPM for ppc64 using CRQ based
|
||||
interface
|
||||
|
||||
Implement support for TPM on ppc64 by implementing the vTPM CRQ interface
|
||||
as a frontend. It can use the tpm_emulator driver backend with the external
|
||||
swtpm.
|
||||
|
||||
The Linux vTPM driver for ppc64 works with this emulation.
|
||||
|
||||
This TPM emulator also handles the TPM 2 case.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Message-Id: <20200121152935.649898-4-stefanb@linux.ibm.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
docs/specs/tpm.txt | 20 ++-
|
||||
hw/tpm/Kconfig | 6 +
|
||||
hw/tpm/Makefile.objs | 1 +
|
||||
hw/tpm/tpm_spapr.c | 379 +++++++++++++++++++++++++++++++++++++++++++
|
||||
hw/tpm/trace-events | 12 ++
|
||||
include/sysemu/tpm.h | 3 +
|
||||
qapi/tpm.json | 6 +-
|
||||
7 files changed, 423 insertions(+), 4 deletions(-)
|
||||
create mode 100644 hw/tpm/tpm_spapr.c
|
||||
|
||||
diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
|
||||
index 9c8cca04..9c3e67d8 100644
|
||||
--- a/docs/specs/tpm.txt
|
||||
+++ b/docs/specs/tpm.txt
|
||||
@@ -34,6 +34,12 @@ The CRB interface makes a memory mapped IO region in the area 0xfed40000 -
|
||||
QEMU files related to TPM CRB interface:
|
||||
- hw/tpm/tpm_crb.c
|
||||
|
||||
+
|
||||
+pSeries (ppc64) machines offer a tpm-spapr device model.
|
||||
+
|
||||
+QEMU files related to the SPAPR interface:
|
||||
+ - hw/tpm/tpm_spapr.c
|
||||
+
|
||||
= fw_cfg interface =
|
||||
|
||||
The bios/firmware may read the "etc/tpm/config" fw_cfg entry for
|
||||
@@ -281,7 +287,7 @@ swtpm socket --tpmstate dir=/tmp/mytpm1 \
|
||||
--log level=20
|
||||
|
||||
Command line to start QEMU with the TPM emulator device communicating with
|
||||
-the swtpm:
|
||||
+the swtpm (x86):
|
||||
|
||||
qemu-system-x86_64 -display sdl -accel kvm \
|
||||
-m 1024 -boot d -bios bios-256k.bin -boot menu=on \
|
||||
@@ -289,6 +295,18 @@ qemu-system-x86_64 -display sdl -accel kvm \
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
-device tpm-tis,tpmdev=tpm0 test.img
|
||||
|
||||
+In case a pSeries machine is emulated, use the following command line:
|
||||
+
|
||||
+qemu-system-ppc64 -display sdl -machine pseries,accel=kvm \
|
||||
+ -m 1024 -bios slof.bin -boot menu=on \
|
||||
+ -nodefaults -device VGA -device pci-ohci -device usb-kbd \
|
||||
+ -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
|
||||
+ -tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
+ -device tpm-spapr,tpmdev=tpm0 \
|
||||
+ -device spapr-vscsi,id=scsi0,reg=0x00002000 \
|
||||
+ -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \
|
||||
+ -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0
|
||||
+
|
||||
|
||||
In case SeaBIOS is used as firmware, it should show the TPM menu item
|
||||
after entering the menu with 'ESC'.
|
||||
diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig
|
||||
index 4c8ee87d..4d4ab085 100644
|
||||
--- a/hw/tpm/Kconfig
|
||||
+++ b/hw/tpm/Kconfig
|
||||
@@ -22,3 +22,9 @@ config TPM_EMULATOR
|
||||
bool
|
||||
default y
|
||||
depends on TPMDEV
|
||||
+
|
||||
+config TPM_SPAPR
|
||||
+ bool
|
||||
+ default n
|
||||
+ depends on TPM && PSERIES
|
||||
+ select TPMDEV
|
||||
diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
|
||||
index de0b85d0..85eb99ae 100644
|
||||
--- a/hw/tpm/Makefile.objs
|
||||
+++ b/hw/tpm/Makefile.objs
|
||||
@@ -4,3 +4,4 @@ common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
|
||||
common-obj-$(CONFIG_TPM_CRB) += tpm_crb.o
|
||||
common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
|
||||
common-obj-$(CONFIG_TPM_EMULATOR) += tpm_emulator.o
|
||||
+obj-$(CONFIG_TPM_SPAPR) += tpm_spapr.o
|
||||
diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
|
||||
new file mode 100644
|
||||
index 00000000..1db9696a
|
||||
--- /dev/null
|
||||
+++ b/hw/tpm/tpm_spapr.c
|
||||
@@ -0,0 +1,379 @@
|
||||
+/*
|
||||
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
|
||||
+ *
|
||||
+ * PAPR Virtual TPM
|
||||
+ *
|
||||
+ * Copyright (c) 2015, 2017, 2019 IBM Corporation.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
+ *
|
||||
+ * This code is licensed under the GPL version 2 or later. See the
|
||||
+ * COPYING file in the top-level directory.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+
|
||||
+#include "sysemu/tpm_backend.h"
|
||||
+#include "tpm_int.h"
|
||||
+#include "tpm_util.h"
|
||||
+
|
||||
+#include "hw/ppc/spapr.h"
|
||||
+#include "hw/ppc/spapr_vio.h"
|
||||
+#include "trace.h"
|
||||
+
|
||||
+#define DEBUG_SPAPR 0
|
||||
+
|
||||
+#define VIO_SPAPR_VTPM(obj) \
|
||||
+ OBJECT_CHECK(SpaprTpmState, (obj), TYPE_TPM_SPAPR)
|
||||
+
|
||||
+typedef struct TpmCrq {
|
||||
+ uint8_t valid; /* 0x80: cmd; 0xc0: init crq */
|
||||
+ /* 0x81-0x83: CRQ message response */
|
||||
+ uint8_t msg; /* see below */
|
||||
+ uint16_t len; /* len of TPM request; len of TPM response */
|
||||
+ uint32_t data; /* rtce_dma_handle when sending TPM request */
|
||||
+ uint64_t reserved;
|
||||
+} TpmCrq;
|
||||
+
|
||||
+#define SPAPR_VTPM_VALID_INIT_CRQ_COMMAND 0xC0
|
||||
+#define SPAPR_VTPM_VALID_COMMAND 0x80
|
||||
+#define SPAPR_VTPM_MSG_RESULT 0x80
|
||||
+
|
||||
+/* msg types for valid = SPAPR_VTPM_VALID_INIT_CRQ */
|
||||
+#define SPAPR_VTPM_INIT_CRQ_RESULT 0x1
|
||||
+#define SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT 0x2
|
||||
+
|
||||
+/* msg types for valid = SPAPR_VTPM_VALID_CMD */
|
||||
+#define SPAPR_VTPM_GET_VERSION 0x1
|
||||
+#define SPAPR_VTPM_TPM_COMMAND 0x2
|
||||
+#define SPAPR_VTPM_GET_RTCE_BUFFER_SIZE 0x3
|
||||
+#define SPAPR_VTPM_PREPARE_TO_SUSPEND 0x4
|
||||
+
|
||||
+/* response error messages */
|
||||
+#define SPAPR_VTPM_VTPM_ERROR 0xff
|
||||
+
|
||||
+/* error codes */
|
||||
+#define SPAPR_VTPM_ERR_COPY_IN_FAILED 0x3
|
||||
+#define SPAPR_VTPM_ERR_COPY_OUT_FAILED 0x4
|
||||
+
|
||||
+#define TPM_SPAPR_BUFFER_MAX 4096
|
||||
+
|
||||
+typedef struct {
|
||||
+ SpaprVioDevice vdev;
|
||||
+
|
||||
+ TpmCrq crq; /* track single TPM command */
|
||||
+
|
||||
+ uint8_t state;
|
||||
+#define SPAPR_VTPM_STATE_NONE 0
|
||||
+#define SPAPR_VTPM_STATE_EXECUTION 1
|
||||
+#define SPAPR_VTPM_STATE_COMPLETION 2
|
||||
+
|
||||
+ unsigned char *buffer;
|
||||
+
|
||||
+ TPMBackendCmd cmd;
|
||||
+
|
||||
+ TPMBackend *be_driver;
|
||||
+ TPMVersion be_tpm_version;
|
||||
+
|
||||
+ size_t be_buffer_size;
|
||||
+} SpaprTpmState;
|
||||
+
|
||||
+/*
|
||||
+ * Send a request to the TPM.
|
||||
+ */
|
||||
+static void tpm_spapr_tpm_send(SpaprTpmState *s)
|
||||
+{
|
||||
+ if (trace_event_get_state_backends(TRACE_TPM_SPAPR_SHOW_BUFFER)) {
|
||||
+ tpm_util_show_buffer(s->buffer, s->be_buffer_size, "To TPM");
|
||||
+ }
|
||||
+
|
||||
+ s->state = SPAPR_VTPM_STATE_EXECUTION;
|
||||
+ s->cmd = (TPMBackendCmd) {
|
||||
+ .locty = 0,
|
||||
+ .in = s->buffer,
|
||||
+ .in_len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size),
|
||||
+ .out = s->buffer,
|
||||
+ .out_len = s->be_buffer_size,
|
||||
+ };
|
||||
+
|
||||
+ tpm_backend_deliver_request(s->be_driver, &s->cmd);
|
||||
+}
|
||||
+
|
||||
+static int tpm_spapr_process_cmd(SpaprTpmState *s, uint64_t dataptr)
|
||||
+{
|
||||
+ long rc;
|
||||
+
|
||||
+ /* a max. of be_buffer_size bytes can be transported */
|
||||
+ rc = spapr_vio_dma_read(&s->vdev, dataptr,
|
||||
+ s->buffer, s->be_buffer_size);
|
||||
+ if (rc) {
|
||||
+ error_report("tpm_spapr_got_payload: DMA read failure");
|
||||
+ }
|
||||
+ /* let vTPM handle any malformed request */
|
||||
+ tpm_spapr_tpm_send(s);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static inline int spapr_tpm_send_crq(struct SpaprVioDevice *dev, TpmCrq *crq)
|
||||
+{
|
||||
+ return spapr_vio_send_crq(dev, (uint8_t *)crq);
|
||||
+}
|
||||
+
|
||||
+static int tpm_spapr_do_crq(struct SpaprVioDevice *dev, uint8_t *crq_data)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
|
||||
+ TpmCrq local_crq;
|
||||
+ TpmCrq *crq = &s->crq; /* requests only */
|
||||
+ int rc;
|
||||
+ uint8_t valid = crq_data[0];
|
||||
+ uint8_t msg = crq_data[1];
|
||||
+
|
||||
+ trace_tpm_spapr_do_crq(valid, msg);
|
||||
+
|
||||
+ switch (valid) {
|
||||
+ case SPAPR_VTPM_VALID_INIT_CRQ_COMMAND: /* Init command/response */
|
||||
+
|
||||
+ /* Respond to initialization request */
|
||||
+ switch (msg) {
|
||||
+ case SPAPR_VTPM_INIT_CRQ_RESULT:
|
||||
+ trace_tpm_spapr_do_crq_crq_result();
|
||||
+ memset(&local_crq, 0, sizeof(local_crq));
|
||||
+ local_crq.valid = SPAPR_VTPM_VALID_INIT_CRQ_COMMAND;
|
||||
+ local_crq.msg = SPAPR_VTPM_INIT_CRQ_RESULT;
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ break;
|
||||
+
|
||||
+ case SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT:
|
||||
+ trace_tpm_spapr_do_crq_crq_complete_result();
|
||||
+ memset(&local_crq, 0, sizeof(local_crq));
|
||||
+ local_crq.valid = SPAPR_VTPM_VALID_INIT_CRQ_COMMAND;
|
||||
+ local_crq.msg = SPAPR_VTPM_INIT_CRQ_COMPLETE_RESULT;
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case SPAPR_VTPM_VALID_COMMAND: /* Payloads */
|
||||
+ switch (msg) {
|
||||
+ case SPAPR_VTPM_TPM_COMMAND:
|
||||
+ trace_tpm_spapr_do_crq_tpm_command();
|
||||
+ if (s->state == SPAPR_VTPM_STATE_EXECUTION) {
|
||||
+ return H_BUSY;
|
||||
+ }
|
||||
+ memcpy(crq, crq_data, sizeof(*crq));
|
||||
+
|
||||
+ rc = tpm_spapr_process_cmd(s, be32_to_cpu(crq->data));
|
||||
+
|
||||
+ if (rc == H_SUCCESS) {
|
||||
+ crq->valid = be16_to_cpu(0);
|
||||
+ } else {
|
||||
+ local_crq.valid = SPAPR_VTPM_MSG_RESULT;
|
||||
+ local_crq.msg = SPAPR_VTPM_VTPM_ERROR;
|
||||
+ local_crq.len = cpu_to_be16(0);
|
||||
+ local_crq.data = cpu_to_be32(SPAPR_VTPM_ERR_COPY_IN_FAILED);
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case SPAPR_VTPM_GET_RTCE_BUFFER_SIZE:
|
||||
+ trace_tpm_spapr_do_crq_tpm_get_rtce_buffer_size(s->be_buffer_size);
|
||||
+ local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
|
||||
+ local_crq.msg = SPAPR_VTPM_GET_RTCE_BUFFER_SIZE |
|
||||
+ SPAPR_VTPM_MSG_RESULT;
|
||||
+ local_crq.len = cpu_to_be16(s->be_buffer_size);
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ break;
|
||||
+
|
||||
+ case SPAPR_VTPM_GET_VERSION:
|
||||
+ local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
|
||||
+ local_crq.msg = SPAPR_VTPM_GET_VERSION | SPAPR_VTPM_MSG_RESULT;
|
||||
+ local_crq.len = cpu_to_be16(0);
|
||||
+ switch (s->be_tpm_version) {
|
||||
+ case TPM_VERSION_1_2:
|
||||
+ local_crq.data = cpu_to_be32(1);
|
||||
+ break;
|
||||
+ case TPM_VERSION_2_0:
|
||||
+ local_crq.data = cpu_to_be32(2);
|
||||
+ break;
|
||||
+ default:
|
||||
+ g_assert_not_reached();
|
||||
+ break;
|
||||
+ }
|
||||
+ trace_tpm_spapr_do_crq_get_version(be32_to_cpu(local_crq.data));
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ break;
|
||||
+
|
||||
+ case SPAPR_VTPM_PREPARE_TO_SUSPEND:
|
||||
+ trace_tpm_spapr_do_crq_prepare_to_suspend();
|
||||
+ local_crq.valid = SPAPR_VTPM_VALID_COMMAND;
|
||||
+ local_crq.msg = SPAPR_VTPM_PREPARE_TO_SUSPEND |
|
||||
+ SPAPR_VTPM_MSG_RESULT;
|
||||
+ spapr_tpm_send_crq(dev, &local_crq);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ trace_tpm_spapr_do_crq_unknown_msg_type(crq->msg);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ trace_tpm_spapr_do_crq_unknown_crq(valid, msg);
|
||||
+ };
|
||||
+
|
||||
+ return H_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static void tpm_spapr_request_completed(TPMIf *ti, int ret)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(ti);
|
||||
+ TpmCrq *crq = &s->crq;
|
||||
+ uint32_t len;
|
||||
+ int rc;
|
||||
+
|
||||
+ s->state = SPAPR_VTPM_STATE_COMPLETION;
|
||||
+
|
||||
+ /* a max. of be_buffer_size bytes can be transported */
|
||||
+ len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size);
|
||||
+ rc = spapr_vio_dma_write(&s->vdev, be32_to_cpu(crq->data),
|
||||
+ s->buffer, len);
|
||||
+
|
||||
+ if (trace_event_get_state_backends(TRACE_TPM_SPAPR_SHOW_BUFFER)) {
|
||||
+ tpm_util_show_buffer(s->buffer, len, "From TPM");
|
||||
+ }
|
||||
+
|
||||
+ crq->valid = SPAPR_VTPM_MSG_RESULT;
|
||||
+ if (rc == H_SUCCESS) {
|
||||
+ crq->msg = SPAPR_VTPM_TPM_COMMAND | SPAPR_VTPM_MSG_RESULT;
|
||||
+ crq->len = cpu_to_be16(len);
|
||||
+ } else {
|
||||
+ error_report("%s: DMA write failure", __func__);
|
||||
+ crq->msg = SPAPR_VTPM_VTPM_ERROR;
|
||||
+ crq->len = cpu_to_be16(0);
|
||||
+ crq->data = cpu_to_be32(SPAPR_VTPM_ERR_COPY_OUT_FAILED);
|
||||
+ }
|
||||
+
|
||||
+ rc = spapr_tpm_send_crq(&s->vdev, crq);
|
||||
+ if (rc) {
|
||||
+ error_report("%s: Error sending response", __func__);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int tpm_spapr_do_startup_tpm(SpaprTpmState *s, size_t buffersize)
|
||||
+{
|
||||
+ return tpm_backend_startup_tpm(s->be_driver, buffersize);
|
||||
+}
|
||||
+
|
||||
+static const char *tpm_spapr_get_dt_compatible(SpaprVioDevice *dev)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
|
||||
+
|
||||
+ switch (s->be_tpm_version) {
|
||||
+ case TPM_VERSION_1_2:
|
||||
+ return "IBM,vtpm";
|
||||
+ case TPM_VERSION_2_0:
|
||||
+ return "IBM,vtpm20";
|
||||
+ default:
|
||||
+ g_assert_not_reached();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void tpm_spapr_reset(SpaprVioDevice *dev)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
|
||||
+
|
||||
+ s->state = SPAPR_VTPM_STATE_NONE;
|
||||
+
|
||||
+ s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
|
||||
+
|
||||
+ s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver),
|
||||
+ TPM_SPAPR_BUFFER_MAX);
|
||||
+
|
||||
+ tpm_backend_reset(s->be_driver);
|
||||
+ tpm_spapr_do_startup_tpm(s, s->be_buffer_size);
|
||||
+}
|
||||
+
|
||||
+static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(ti);
|
||||
+
|
||||
+ if (tpm_backend_had_startup_error(s->be_driver)) {
|
||||
+ return TPM_VERSION_UNSPEC;
|
||||
+ }
|
||||
+
|
||||
+ return tpm_backend_get_tpm_version(s->be_driver);
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_spapr_vtpm = {
|
||||
+ .name = "tpm-spapr",
|
||||
+ .unmigratable = 1,
|
||||
+};
|
||||
+
|
||||
+static Property tpm_spapr_properties[] = {
|
||||
+ DEFINE_SPAPR_PROPERTIES(SpaprTpmState, vdev),
|
||||
+ DEFINE_PROP_TPMBE("tpmdev", SpaprTpmState, be_driver),
|
||||
+ DEFINE_PROP_END_OF_LIST(),
|
||||
+};
|
||||
+
|
||||
+static void tpm_spapr_realizefn(SpaprVioDevice *dev, Error **errp)
|
||||
+{
|
||||
+ SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
|
||||
+
|
||||
+ if (!tpm_find()) {
|
||||
+ error_setg(errp, "at most one TPM device is permitted");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dev->crq.SendFunc = tpm_spapr_do_crq;
|
||||
+
|
||||
+ if (!s->be_driver) {
|
||||
+ error_setg(errp, "'tpmdev' property is required");
|
||||
+ return;
|
||||
+ }
|
||||
+ s->buffer = g_malloc(TPM_SPAPR_BUFFER_MAX);
|
||||
+}
|
||||
+
|
||||
+static void tpm_spapr_class_init(ObjectClass *klass, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
+ SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
+ TPMIfClass *tc = TPM_IF_CLASS(klass);
|
||||
+
|
||||
+ k->realize = tpm_spapr_realizefn;
|
||||
+ k->reset = tpm_spapr_reset;
|
||||
+ k->dt_name = "vtpm";
|
||||
+ k->dt_type = "IBM,vtpm";
|
||||
+ k->get_dt_compatible = tpm_spapr_get_dt_compatible;
|
||||
+ k->signal_mask = 0x00000001;
|
||||
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
+ dc->props = tpm_spapr_properties;
|
||||
+ k->rtce_window_size = 0x10000000;
|
||||
+ dc->vmsd = &vmstate_spapr_vtpm;
|
||||
+
|
||||
+ tc->model = TPM_MODEL_TPM_SPAPR;
|
||||
+ tc->get_version = tpm_spapr_get_version;
|
||||
+ tc->request_completed = tpm_spapr_request_completed;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo tpm_spapr_info = {
|
||||
+ .name = TYPE_TPM_SPAPR,
|
||||
+ .parent = TYPE_VIO_SPAPR_DEVICE,
|
||||
+ .instance_size = sizeof(SpaprTpmState),
|
||||
+ .class_init = tpm_spapr_class_init,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_TPM_IF },
|
||||
+ { }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void tpm_spapr_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&tpm_spapr_info);
|
||||
+}
|
||||
+
|
||||
+type_init(tpm_spapr_register_types)
|
||||
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
|
||||
index 82c45ee5..edbe1bd7 100644
|
||||
--- a/hw/tpm/trace-events
|
||||
+++ b/hw/tpm/trace-events
|
||||
@@ -55,3 +55,15 @@ tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
|
||||
|
||||
# tpm_ppi.c
|
||||
tpm_ppi_memset(uint8_t *ptr, size_t size) "memset: %p %zu"
|
||||
+
|
||||
+# hw/tpm/tpm_spapr.c
|
||||
+tpm_spapr_show_buffer(const char *direction, size_t len, const char *buf) "direction: %s len: %zu\n%s"
|
||||
+tpm_spapr_do_crq(uint8_t raw1, uint8_t raw2) "1st 2 bytes in CRQ: 0x%02x 0x%02x"
|
||||
+tpm_spapr_do_crq_crq_result(void) "SPAPR_VTPM_INIT_CRQ_RESULT"
|
||||
+tpm_spapr_do_crq_crq_complete_result(void) "SPAPR_VTPM_INIT_CRQ_COMP_RESULT"
|
||||
+tpm_spapr_do_crq_tpm_command(void) "got TPM command payload"
|
||||
+tpm_spapr_do_crq_tpm_get_rtce_buffer_size(size_t buffersize) "response: buffer size is %zu"
|
||||
+tpm_spapr_do_crq_get_version(uint32_t version) "response: version %u"
|
||||
+tpm_spapr_do_crq_prepare_to_suspend(void) "response: preparing to suspend"
|
||||
+tpm_spapr_do_crq_unknown_msg_type(uint8_t type) "Unknown message type 0x%02x"
|
||||
+tpm_spapr_do_crq_unknown_crq(uint8_t raw1, uint8_t raw2) "unknown CRQ 0x%02x 0x%02x ..."
|
||||
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
|
||||
index 5b541a71..15979a36 100644
|
||||
--- a/include/sysemu/tpm.h
|
||||
+++ b/include/sysemu/tpm.h
|
||||
@@ -45,11 +45,14 @@ typedef struct TPMIfClass {
|
||||
|
||||
#define TYPE_TPM_TIS "tpm-tis"
|
||||
#define TYPE_TPM_CRB "tpm-crb"
|
||||
+#define TYPE_TPM_SPAPR "tpm-spapr"
|
||||
|
||||
#define TPM_IS_TIS(chr) \
|
||||
object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS)
|
||||
#define TPM_IS_CRB(chr) \
|
||||
object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
|
||||
+#define TPM_IS_SPAPR(chr) \
|
||||
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_SPAPR)
|
||||
|
||||
/* returns NULL unless there is exactly one TPM device */
|
||||
static inline TPMIf *tpm_find(void)
|
||||
diff --git a/qapi/tpm.json b/qapi/tpm.json
|
||||
index b30323bb..63878aa0 100644
|
||||
--- a/qapi/tpm.json
|
||||
+++ b/qapi/tpm.json
|
||||
@@ -12,11 +12,11 @@
|
||||
#
|
||||
# @tpm-tis: TPM TIS model
|
||||
# @tpm-crb: TPM CRB model (since 2.12)
|
||||
+# @tpm-spapr: TPM SPAPR model (since 5.0)
|
||||
#
|
||||
# Since: 1.5
|
||||
##
|
||||
-{ 'enum': 'TpmModel', 'data': [ 'tpm-tis', 'tpm-crb' ] }
|
||||
-
|
||||
+{ 'enum': 'TpmModel', 'data': [ 'tpm-tis', 'tpm-crb', 'tpm-spapr' ] }
|
||||
##
|
||||
# @query-tpm-models:
|
||||
#
|
||||
@@ -29,7 +29,7 @@
|
||||
# Example:
|
||||
#
|
||||
# -> { "execute": "query-tpm-models" }
|
||||
-# <- { "return": [ "tpm-tis", "tpm-crb" ] }
|
||||
+# <- { "return": [ "tpm-tis", "tpm-crb", "tpm-spapr" ] }
|
||||
#
|
||||
##
|
||||
{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] }
|
||||
--
|
||||
2.23.0
|
||||
|
||||
119
tpm_spapr-Support-suspend-and-resume.patch
Normal file
119
tpm_spapr-Support-suspend-and-resume.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From 2948d9712a7058bcdca6732101874beb1a6e00a9 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Tue, 21 Jan 2020 10:29:33 -0500
|
||||
Subject: [PATCH 07/19] tpm_spapr: Support suspend and resume
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Extend the tpm_spapr frontend with VM suspend and resume support.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Message-Id: <20200121152935.649898-5-stefanb@linux.ibm.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
|
||||
Signed-off-by: jiangfangjie <jiangfangjie@huawei.com>
|
||||
---
|
||||
hw/tpm/tpm_spapr.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
hw/tpm/trace-events | 2 ++
|
||||
2 files changed, 53 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c
|
||||
index 1db9696a..8ba561f4 100644
|
||||
--- a/hw/tpm/tpm_spapr.c
|
||||
+++ b/hw/tpm/tpm_spapr.c
|
||||
@@ -76,6 +76,8 @@ typedef struct {
|
||||
|
||||
unsigned char *buffer;
|
||||
|
||||
+ uint32_t numbytes; /* number of bytes to deliver on resume */
|
||||
+
|
||||
TPMBackendCmd cmd;
|
||||
|
||||
TPMBackend *be_driver;
|
||||
@@ -240,6 +242,14 @@ static void tpm_spapr_request_completed(TPMIf *ti, int ret)
|
||||
|
||||
/* a max. of be_buffer_size bytes can be transported */
|
||||
len = MIN(tpm_cmd_get_size(s->buffer), s->be_buffer_size);
|
||||
+
|
||||
+ if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
|
||||
+ trace_tpm_spapr_caught_response(len);
|
||||
+ /* defer delivery of response until .post_load */
|
||||
+ s->numbytes = len;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
rc = spapr_vio_dma_write(&s->vdev, be32_to_cpu(crq->data),
|
||||
s->buffer, len);
|
||||
|
||||
@@ -288,6 +298,7 @@ static void tpm_spapr_reset(SpaprVioDevice *dev)
|
||||
SpaprTpmState *s = VIO_SPAPR_VTPM(dev);
|
||||
|
||||
s->state = SPAPR_VTPM_STATE_NONE;
|
||||
+ s->numbytes = 0;
|
||||
|
||||
s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver);
|
||||
|
||||
@@ -309,9 +320,48 @@ static enum TPMVersion tpm_spapr_get_version(TPMIf *ti)
|
||||
return tpm_backend_get_tpm_version(s->be_driver);
|
||||
}
|
||||
|
||||
+/* persistent state handling */
|
||||
+
|
||||
+static int tpm_spapr_pre_save(void *opaque)
|
||||
+{
|
||||
+ SpaprTpmState *s = opaque;
|
||||
+
|
||||
+ tpm_backend_finish_sync(s->be_driver);
|
||||
+ /*
|
||||
+ * we cannot deliver the results to the VM since DMA would touch VM memory
|
||||
+ */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tpm_spapr_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+ SpaprTpmState *s = opaque;
|
||||
+
|
||||
+ if (s->numbytes) {
|
||||
+ trace_tpm_spapr_post_load();
|
||||
+ /* deliver the results to the VM via DMA */
|
||||
+ tpm_spapr_request_completed(TPM_IF(s), 0);
|
||||
+ s->numbytes = 0;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const VMStateDescription vmstate_spapr_vtpm = {
|
||||
.name = "tpm-spapr",
|
||||
- .unmigratable = 1,
|
||||
+ .pre_save = tpm_spapr_pre_save,
|
||||
+ .post_load = tpm_spapr_post_load,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_SPAPR_VIO(vdev, SpaprTpmState),
|
||||
+
|
||||
+ VMSTATE_UINT8(state, SpaprTpmState),
|
||||
+ VMSTATE_UINT32(numbytes, SpaprTpmState),
|
||||
+ VMSTATE_VBUFFER_UINT32(buffer, SpaprTpmState, 0, NULL, numbytes),
|
||||
+ /* remember DMA address */
|
||||
+ VMSTATE_UINT32(crq.data, SpaprTpmState),
|
||||
+ VMSTATE_END_OF_LIST(),
|
||||
+ }
|
||||
};
|
||||
|
||||
static Property tpm_spapr_properties[] = {
|
||||
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
|
||||
index edbe1bd7..b97eea24 100644
|
||||
--- a/hw/tpm/trace-events
|
||||
+++ b/hw/tpm/trace-events
|
||||
@@ -67,3 +67,5 @@ tpm_spapr_do_crq_get_version(uint32_t version) "response: version %u"
|
||||
tpm_spapr_do_crq_prepare_to_suspend(void) "response: preparing to suspend"
|
||||
tpm_spapr_do_crq_unknown_msg_type(uint8_t type) "Unknown message type 0x%02x"
|
||||
tpm_spapr_do_crq_unknown_crq(uint8_t raw1, uint8_t raw2) "unknown CRQ 0x%02x 0x%02x ..."
|
||||
+tpm_spapr_post_load(void) "Delivering TPM response after resume"
|
||||
+tpm_spapr_caught_response(uint32_t v) "Caught response to deliver after resume: %u bytes"
|
||||
--
|
||||
2.23.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user