| 1 | .. _tpm-device: |
| 2 | |
| 3 | =============== |
| 4 | QEMU TPM Device |
| 5 | =============== |
| 6 | |
| 7 | Guest-side hardware interface |
| 8 | ============================= |
| 9 | |
| 10 | TIS interface |
| 11 | ------------- |
| 12 | |
| 13 | The QEMU TPM emulation implements a TPM TIS hardware interface |
| 14 | following the Trusted Computing Group's specification "TCG PC Client |
| 15 | Specific TPM Interface Specification (TIS)", Specification Version |
| 16 | 1.3, 21 March 2013. (see the `TIS specification`_, or a later version |
| 17 | of it). |
| 18 | |
| 19 | The TIS interface makes a memory mapped IO region in the area |
| 20 | 0xfed40000-0xfed44fff available to the guest operating system. |
| 21 | |
| 22 | QEMU files related to TPM TIS interface: |
| 23 | - ``hw/tpm/tpm_tis_common.c`` |
| 24 | - ``hw/tpm/tpm_tis_isa.c`` |
| 25 | - ``hw/tpm/tpm_tis_sysbus.c`` |
| 26 | - ``hw/tpm/tpm_tis_i2c.c`` |
| 27 | - ``hw/tpm/tpm_tis.h`` |
| 28 | |
| 29 | Both an ISA device and a sysbus device are available. The former is |
| 30 | used with pc/q35 machine while the latter can be instantiated in the |
| 31 | Arm virt machine. |
| 32 | |
| 33 | An I2C device support is also provided which can be instantiated in the Arm |
| 34 | based emulation machines. This device only supports the TPM 2 protocol. |
| 35 | |
| 36 | CRB interface |
| 37 | ------------- |
| 38 | |
| 39 | QEMU also implements a TPM CRB interface following the Trusted |
| 40 | Computing Group's specification "TCG PC Client Platform TPM Profile |
| 41 | (PTP) Specification", Family "2.0", Level 00 Revision 01.03 v22, May |
| 42 | 22, 2017. (see the `CRB specification`_, or a later version of it) |
| 43 | |
| 44 | The CRB interface makes a memory mapped IO region in the area |
| 45 | 0xfed40000-0xfed40fff (1 locality) available to the guest |
| 46 | operating system. |
| 47 | |
| 48 | QEMU files related to TPM CRB interface: |
| 49 | - ``hw/tpm/tpm_crb.c`` |
| 50 | |
| 51 | SPAPR interface |
| 52 | --------------- |
| 53 | |
| 54 | pSeries (ppc64) machines offer a tpm-spapr device model. |
| 55 | |
| 56 | QEMU files related to the SPAPR interface: |
| 57 | - ``hw/tpm/tpm_spapr.c`` |
| 58 | |
| 59 | fw_cfg interface |
| 60 | ================ |
| 61 | |
| 62 | The bios/firmware may read the ``"etc/tpm/config"`` fw_cfg entry for |
| 63 | configuring the guest appropriately. |
| 64 | |
| 65 | The entry of 6 bytes has the following content, in little-endian: |
| 66 | |
| 67 | .. code-block:: c |
| 68 | |
| 69 | #define TPM_VERSION_UNSPEC 0 |
| 70 | #define TPM_VERSION_1_2 1 |
| 71 | #define TPM_VERSION_2_0 2 |
| 72 | |
| 73 | #define TPM_PPI_VERSION_NONE 0 |
| 74 | #define TPM_PPI_VERSION_1_30 1 |
| 75 | |
| 76 | struct FwCfgTPMConfig { |
| 77 | uint32_t tpmppi_address; /* PPI memory location */ |
| 78 | uint8_t tpm_version; /* TPM version */ |
| 79 | uint8_t tpmppi_version; /* PPI version */ |
| 80 | }; |
| 81 | |
| 82 | ACPI interface |
| 83 | ============== |
| 84 | |
| 85 | The TPM device is defined with ACPI ID "PNP0C31". QEMU builds a SSDT |
| 86 | and passes it into the guest through the fw_cfg device. The device |
| 87 | description contains the base address of the TIS interface 0xfed40000 |
| 88 | and the size of the MMIO area (0x5000). In case a TPM2 is used by |
| 89 | QEMU, a TPM2 ACPI table is also provided. The device is described to |
| 90 | be used in polling mode rather than interrupt mode primarily because |
| 91 | no unused IRQ could be found. |
| 92 | |
| 93 | To support measurement logs to be written by the firmware, |
| 94 | e.g. SeaBIOS, a TCPA table is implemented. This table provides a 64kb |
| 95 | buffer where the firmware can write its log into. For TPM 2 only a |
| 96 | more recent version of the TPM2 table provides support for |
| 97 | measurements logs and a TCPA table does not need to be created. |
| 98 | |
| 99 | The TCPA and TPM2 ACPI tables follow the Trusted Computing Group |
| 100 | specification "TCG ACPI Specification" Family "1.2" and "2.0", Level |
| 101 | 00 Revision 00.37. (see the `ACPI specification`_, or a later version |
| 102 | of it) |
| 103 | |
| 104 | ACPI PPI Interface |
| 105 | ------------------ |
| 106 | |
| 107 | QEMU supports the Physical Presence Interface (PPI) for TPM 1.2 and |
| 108 | TPM 2. This interface requires ACPI and firmware support. (see the |
| 109 | `PPI specification`_) |
| 110 | |
| 111 | PPI enables a system administrator (root) to request a modification to |
| 112 | the TPM upon reboot. The PPI specification defines the operation |
| 113 | requests and the actions the firmware has to take. The system |
| 114 | administrator passes the operation request number to the firmware |
| 115 | through an ACPI interface which writes this number to a memory |
| 116 | location that the firmware knows. Upon reboot, the firmware finds the |
| 117 | number and sends commands to the TPM. The firmware writes the TPM |
| 118 | result code and the operation request number to a memory location that |
| 119 | ACPI can read from and pass the result on to the administrator. |
| 120 | |
| 121 | The PPI specification defines a set of mandatory and optional |
| 122 | operations for the firmware to implement. The ACPI interface also |
| 123 | allows an administrator to list the supported operations. In QEMU the |
| 124 | ACPI code is generated by QEMU, yet the firmware needs to implement |
| 125 | support on a per-operations basis, and different firmwares may support |
| 126 | a different subset. Therefore, QEMU introduces the virtual memory |
| 127 | device for PPI where the firmware can indicate which operations it |
| 128 | supports and ACPI can enable the ones that are supported and disable |
| 129 | all others. This interface lies in main memory and has the following |
| 130 | layout: |
| 131 | |
| 132 | +-------------+--------+--------+-------------------------------------------+ |
| 133 | | Field | Length | Offset | Description | |
| 134 | +=============+========+========+===========================================+ |
| 135 | | ``func`` | 0x100 | 0x000 | Firmware sets values for each supported | |
| 136 | | | | | operation. See defined values below. | |
| 137 | +-------------+--------+--------+-------------------------------------------+ |
| 138 | | ``ppin`` | 0x1 | 0x100 | SMI interrupt to use. Set by firmware. | |
| 139 | | | | | Not supported. | |
| 140 | +-------------+--------+--------+-------------------------------------------+ |
| 141 | | ``ppip`` | 0x4 | 0x101 | ACPI function index to pass to SMM code. | |
| 142 | | | | | Set by ACPI. Not supported. | |
| 143 | +-------------+--------+--------+-------------------------------------------+ |
| 144 | | ``pprp`` | 0x4 | 0x105 | Result of last executed operation. Set by | |
| 145 | | | | | firmware. See function index 5 for values.| |
| 146 | +-------------+--------+--------+-------------------------------------------+ |
| 147 | | ``pprq`` | 0x4 | 0x109 | Operation request number to execute. See | |
| 148 | | | | | 'Physical Presence Interface Operation | |
| 149 | | | | | Summary' tables in specs. Set by ACPI. | |
| 150 | +-------------+--------+--------+-------------------------------------------+ |
| 151 | | ``pprm`` | 0x4 | 0x10d | Operation request optional parameter. | |
| 152 | | | | | Values depend on operation. Set by ACPI. | |
| 153 | +-------------+--------+--------+-------------------------------------------+ |
| 154 | | ``lppr`` | 0x4 | 0x111 | Last executed operation request number. | |
| 155 | | | | | Copied from pprq field by firmware. | |
| 156 | +-------------+--------+--------+-------------------------------------------+ |
| 157 | | ``fret`` | 0x4 | 0x115 | Result code from SMM function. | |
| 158 | | | | | Not supported. | |
| 159 | +-------------+--------+--------+-------------------------------------------+ |
| 160 | | ``res1`` | 0x40 | 0x119 | Reserved for future use | |
| 161 | +-------------+--------+--------+-------------------------------------------+ |
| 162 | |``next_step``| 0x1 | 0x159 | Operation to execute after reboot by | |
| 163 | | | | | firmware. Used by firmware. | |
| 164 | +-------------+--------+--------+-------------------------------------------+ |
| 165 | | ``movv`` | 0x1 | 0x15a | Memory overwrite variable | |
| 166 | +-------------+--------+--------+-------------------------------------------+ |
| 167 | |
| 168 | The following values are supported for the ``func`` field. They |
| 169 | correspond to the values used by ACPI function index 8. |
| 170 | |
| 171 | +----------+-------------------------------------------------------------+ |
| 172 | | Value | Description | |
| 173 | +==========+=============================================================+ |
| 174 | | 0 | Operation is not implemented. | |
| 175 | +----------+-------------------------------------------------------------+ |
| 176 | | 1 | Operation is only accessible through firmware. | |
| 177 | +----------+-------------------------------------------------------------+ |
| 178 | | 2 | Operation is blocked for OS by firmware configuration. | |
| 179 | +----------+-------------------------------------------------------------+ |
| 180 | | 3 | Operation is allowed and physically present user required. | |
| 181 | +----------+-------------------------------------------------------------+ |
| 182 | | 4 | Operation is allowed and physically present user is not | |
| 183 | | | required. | |
| 184 | +----------+-------------------------------------------------------------+ |
| 185 | |
| 186 | The location of the table is given by the fw_cfg ``tpmppi_address`` |
| 187 | field. The PPI memory region size is 0x400 (``TPM_PPI_ADDR_SIZE``) to |
| 188 | leave enough room for future updates. |
| 189 | |
| 190 | PPI on ARM64 virt |
| 191 | ----------------- |
| 192 | |
| 193 | The ARM virt machine supports PPI for ``tpm-tis-device`` as defined |
| 194 | in the `PPI specification`_. |
| 195 | |
| 196 | Unlike the x86 TIS device where the PPI memory region is mapped at |
| 197 | the fixed address ``0xFED45000`` (within the TIS MMIO range), the |
| 198 | ARM64 sysbus device registers PPI memory as a second MMIO region |
| 199 | on the platform bus. The platform bus assigns the guest physical |
| 200 | address dynamically at device plug time. The ACPI ``_DSM`` method |
| 201 | and PPI operation regions reference this dynamically resolved |
| 202 | address. |
| 203 | |
| 204 | PPI is controlled by the ``ppi`` property (default ``on``):: |
| 205 | |
| 206 | -device tpm-tis-device,tpmdev=tpm0,ppi=on |
| 207 | |
| 208 | Without PPI, guest operating systems such as Windows 11 |
| 209 | ARM64 will log errors when attempting to query TPM Physical |
| 210 | Presence capabilities via the ACPI ``_DSM`` method. |
| 211 | |
| 212 | QEMU files related to TPM ACPI tables: |
| 213 | - ``hw/i386/acpi-build.c`` |
| 214 | - ``hw/arm/virt-acpi-build.c`` |
| 215 | - ``hw/acpi/tpm.c`` |
| 216 | - ``include/hw/acpi/tpm.h`` |
| 217 | |
| 218 | TPM backend devices |
| 219 | =================== |
| 220 | |
| 221 | The TPM implementation is split into two parts, frontend and |
| 222 | backend. The frontend part is the hardware interface, such as the TPM |
| 223 | TIS interface described earlier, and the other part is the TPM backend |
| 224 | interface. The backend interfaces implement the interaction with a TPM |
| 225 | device, which may be a physical or an emulated device. The split |
| 226 | between the front- and backend devices allows a frontend to be |
| 227 | connected with any available backend. This enables the TIS interface |
| 228 | to be used with the passthrough backend or the swtpm backend. |
| 229 | |
| 230 | QEMU files related to TPM backends: |
| 231 | - ``backends/tpm.c`` |
| 232 | - ``include/system/tpm.h`` |
| 233 | - ``include/system/tpm_backend.h`` |
| 234 | |
| 235 | The QEMU TPM passthrough device |
| 236 | ------------------------------- |
| 237 | |
| 238 | In case QEMU is run on Linux as the host operating system it is |
| 239 | possible to make the hardware TPM device available to a single QEMU |
| 240 | guest. In this case the user must make sure that no other program is |
| 241 | using the device, e.g., /dev/tpm0, before trying to start QEMU with |
| 242 | it. |
| 243 | |
| 244 | The passthrough driver uses the host's TPM device for sending TPM |
| 245 | commands and receiving responses from. Besides that it accesses the |
| 246 | TPM device's sysfs entry for support of command cancellation. Since |
| 247 | none of the state of a hardware TPM can be migrated between hosts, |
| 248 | virtual machine migration is disabled when the TPM passthrough driver |
| 249 | is used. |
| 250 | |
| 251 | Since the host's TPM device will already be initialized by the host's |
| 252 | firmware, certain commands, e.g. ``TPM_Startup()``, sent by the |
| 253 | virtual firmware for device initialization, will fail. In this case |
| 254 | the firmware should not use the TPM. |
| 255 | |
| 256 | Sharing the device with the host is generally not a recommended usage |
| 257 | scenario for a TPM device. The primary reason for this is that two |
| 258 | operating systems can then access the device's single set of |
| 259 | resources, such as platform configuration registers |
| 260 | (PCRs). Applications or kernel security subsystems, such as the Linux |
| 261 | Integrity Measurement Architecture (IMA), are not expecting to share |
| 262 | PCRs. |
| 263 | |
| 264 | QEMU files related to the TPM passthrough device: |
| 265 | - ``backends/tpm/tpm_passthrough.c`` |
| 266 | - ``backends/tpm/tpm_util.c`` |
| 267 | - ``include/system/tpm_util.h`` |
| 268 | |
| 269 | |
| 270 | Command line to start QEMU with the TPM passthrough device using the host's |
| 271 | hardware TPM ``/dev/tpm0``: |
| 272 | |
| 273 | .. code-block:: console |
| 274 | |
| 275 | qemu-system-x86_64 -display sdl -accel kvm \ |
| 276 | -m 1024 -boot d -bios bios-256k.bin -boot menu=on \ |
| 277 | -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \ |
| 278 | -device tpm-tis,tpmdev=tpm0 test.img |
| 279 | |
| 280 | |
| 281 | The following commands should result in similar output inside the VM |
| 282 | with a Linux kernel that either has the TPM TIS driver built-in or |
| 283 | available as a module (assuming a TPM 2 is passed through): |
| 284 | |
| 285 | .. code-block:: console |
| 286 | |
| 287 | # dmesg | grep -i tpm |
| 288 | [ 0.012560] ACPI: TPM2 0x000000000BFFD1900 00004C (v04 BOCHS \ |
| 289 | BXPC 0000001 BXPC 00000001) |
| 290 | |
| 291 | # ls -l /dev/tpm* |
| 292 | crw-rw----. 1 tss root 10, 224 Sep 6 12:36 /dev/tpm0 |
| 293 | crw-rw----. 1 tss rss 253, 65536 Sep 6 12:36 /dev/tpmrm0 |
| 294 | |
| 295 | Starting with Linux 5.12 there are PCR entries for TPM 2 in sysfs: |
| 296 | # find /sys/devices/ -type f | grep pcr-sha |
| 297 | ... |
| 298 | /sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/1 |
| 299 | ... |
| 300 | /sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/9 |
| 301 | ... |
| 302 | |
| 303 | The QEMU TPM emulator device |
| 304 | ---------------------------- |
| 305 | |
| 306 | The TPM emulator device uses an external TPM emulator called 'swtpm' |
| 307 | for sending TPM commands to and receiving responses from. The swtpm |
| 308 | program must have been started before trying to access it through the |
| 309 | TPM emulator with QEMU. |
| 310 | |
| 311 | The TPM emulator implements a command channel for transferring TPM |
| 312 | commands and responses as well as a control channel over which control |
| 313 | commands can be sent. (see the `SWTPM protocol`_ specification) |
| 314 | |
| 315 | The control channel serves the purpose of resetting, initializing, and |
| 316 | migrating the TPM state, among other things. |
| 317 | |
| 318 | The swtpm program behaves like a hardware TPM and therefore needs to |
| 319 | be initialized by the firmware running inside the QEMU virtual |
| 320 | machine. One necessary step for initializing the device is to send |
| 321 | the TPM_Startup command to it. SeaBIOS, for example, has been |
| 322 | instrumented to initialize a TPM 1.2 or TPM 2 device using this |
| 323 | command. |
| 324 | |
| 325 | QEMU files related to the TPM emulator device: |
| 326 | - ``backends/tpm/tpm_emulator.c`` |
| 327 | - ``backends/tpm/tpm_util.c`` |
| 328 | - ``include/system/tpm_util.h`` |
| 329 | |
| 330 | The following commands start the swtpm with a UnixIO control channel over |
| 331 | a socket interface. They do not need to be run as root. |
| 332 | |
| 333 | .. code-block:: console |
| 334 | |
| 335 | mkdir /tmp/mytpm1 |
| 336 | swtpm socket --tpmstate dir=/tmp/mytpm1 \ |
| 337 | --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ |
| 338 | --tpm2 \ |
| 339 | --log level=20 |
| 340 | |
| 341 | Command line to start QEMU with the TPM emulator device communicating |
| 342 | with the swtpm (x86): |
| 343 | |
| 344 | .. code-block:: console |
| 345 | |
| 346 | qemu-system-x86_64 -display sdl -accel kvm \ |
| 347 | -m 1024 -boot d -bios bios-256k.bin -boot menu=on \ |
| 348 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 349 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 350 | -device tpm-tis,tpmdev=tpm0 test.img |
| 351 | |
| 352 | In case a pSeries machine is emulated, use the following command line: |
| 353 | |
| 354 | .. code-block:: console |
| 355 | |
| 356 | qemu-system-ppc64 -display sdl -machine pseries,accel=kvm \ |
| 357 | -m 1024 -bios slof.bin -boot menu=on \ |
| 358 | -nodefaults -device VGA -device pci-ohci -device usb-kbd \ |
| 359 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 360 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 361 | -device tpm-spapr,tpmdev=tpm0 \ |
| 362 | -device spapr-vscsi,id=scsi0,reg=0x00002000 \ |
| 363 | -device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,id=virtio-disk0 \ |
| 364 | -drive file=test.img,format=raw,if=none,id=drive-virtio-disk0 |
| 365 | |
| 366 | In case an Arm virt machine is emulated, use the following command line: |
| 367 | |
| 368 | .. code-block:: console |
| 369 | |
| 370 | qemu-system-aarch64 -machine virt,gic-version=3,acpi=off \ |
| 371 | -cpu host -m 4G \ |
| 372 | -nographic -accel kvm \ |
| 373 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 374 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 375 | -device tpm-tis-device,tpmdev=tpm0 \ |
| 376 | -device virtio-blk-pci,drive=drv0 \ |
| 377 | -drive format=qcow2,file=hda.qcow2,if=none,id=drv0 \ |
| 378 | -drive if=pflash,format=raw,file=flash0.img,readonly=on \ |
| 379 | -drive if=pflash,format=raw,file=flash1.img |
| 380 | |
| 381 | In case a ast2600-evb bmc machine is emulated and you want to use a TPM device |
| 382 | attached to I2C bus, use the following command line: |
| 383 | |
| 384 | .. code-block:: console |
| 385 | |
| 386 | qemu-system-arm -M ast2600-evb -nographic \ |
| 387 | -kernel arch/arm/boot/zImage \ |
| 388 | -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \ |
| 389 | -initrd rootfs.cpio \ |
| 390 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 391 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 392 | -device tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e |
| 393 | |
| 394 | For testing, use this command to load the driver to the correct address |
| 395 | |
| 396 | echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device |
| 397 | |
| 398 | In case SeaBIOS is used as firmware, it should show the TPM menu item |
| 399 | after entering the menu with 'ESC'. |
| 400 | |
| 401 | .. code-block:: console |
| 402 | |
| 403 | Select boot device: |
| 404 | 1. DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD] |
| 405 | [...] |
| 406 | 5. Legacy option rom |
| 407 | |
| 408 | t. TPM Configuration |
| 409 | |
| 410 | The following commands should result in similar output inside the VM |
| 411 | with a Linux kernel that either has the TPM TIS driver built-in or |
| 412 | available as a module: |
| 413 | |
| 414 | .. code-block:: console |
| 415 | |
| 416 | # dmesg | grep -i tpm |
| 417 | [ 0.012560] ACPI: TPM2 0x000000000BFFD1900 00004C (v04 BOCHS \ |
| 418 | BXPC 0000001 BXPC 00000001) |
| 419 | |
| 420 | # ls -l /dev/tpm* |
| 421 | crw-rw----. 1 tss root 10, 224 Sep 6 12:36 /dev/tpm0 |
| 422 | crw-rw----. 1 tss rss 253, 65536 Sep 6 12:36 /dev/tpmrm0 |
| 423 | |
| 424 | Starting with Linux 5.12 there are PCR entries for TPM 2 in sysfs: |
| 425 | # find /sys/devices/ -type f | grep pcr-sha |
| 426 | ... |
| 427 | /sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/1 |
| 428 | ... |
| 429 | /sys/devices/LNXSYSTEM:00/LNXSYBUS:00/MSFT0101:00/tpm/tpm0/pcr-sha256/9 |
| 430 | ... |
| 431 | |
| 432 | Migration with the TPM emulator |
| 433 | =============================== |
| 434 | |
| 435 | The TPM emulator supports the following types of virtual machine |
| 436 | migration: |
| 437 | |
| 438 | - VM save / restore (migration into a file) |
| 439 | - Network migration |
| 440 | - Snapshotting (migration into storage like QoW2 or QED) |
| 441 | |
| 442 | The following command sequences can be used to test VM save / restore. |
| 443 | |
| 444 | In a 1st terminal start an instance of a swtpm using the following command: |
| 445 | |
| 446 | .. code-block:: console |
| 447 | |
| 448 | mkdir /tmp/mytpm1 |
| 449 | swtpm socket --tpmstate dir=/tmp/mytpm1 \ |
| 450 | --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ |
| 451 | --tpm2 \ |
| 452 | --log level=20 |
| 453 | |
| 454 | In a 2nd terminal start the VM: |
| 455 | |
| 456 | .. code-block:: console |
| 457 | |
| 458 | qemu-system-x86_64 -display sdl -accel kvm \ |
| 459 | -m 1024 -boot d -bios bios-256k.bin -boot menu=on \ |
| 460 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 461 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 462 | -device tpm-tis,tpmdev=tpm0 \ |
| 463 | -monitor stdio \ |
| 464 | test.img |
| 465 | |
| 466 | Verify that the attached TPM is working as expected using applications |
| 467 | inside the VM. |
| 468 | |
| 469 | To store the state of the VM use the following command in the QEMU |
| 470 | monitor in the 2nd terminal: |
| 471 | |
| 472 | .. code-block:: console |
| 473 | |
| 474 | (qemu) migrate "exec:cat > testvm.bin" |
| 475 | (qemu) quit |
| 476 | |
| 477 | At this point a file called ``testvm.bin`` should exists and the swtpm |
| 478 | and QEMU processes should have ended. |
| 479 | |
| 480 | To test 'VM restore' you have to start the swtpm with the same |
| 481 | parameters as before. If previously a TPM 2 [--tpm2] was saved, --tpm2 |
| 482 | must now be passed again on the command line. |
| 483 | |
| 484 | In the 1st terminal restart the swtpm with the same command line as |
| 485 | before: |
| 486 | |
| 487 | .. code-block:: console |
| 488 | |
| 489 | swtpm socket --tpmstate dir=/tmp/mytpm1 \ |
| 490 | --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \ |
| 491 | --log level=20 --tpm2 |
| 492 | |
| 493 | In the 2nd terminal restore the state of the VM using the additional |
| 494 | '-incoming' option. |
| 495 | |
| 496 | .. code-block:: console |
| 497 | |
| 498 | qemu-system-x86_64 -display sdl -accel kvm \ |
| 499 | -m 1024 -boot d -bios bios-256k.bin -boot menu=on \ |
| 500 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 501 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 502 | -device tpm-tis,tpmdev=tpm0 \ |
| 503 | -incoming "exec:cat < testvm.bin" \ |
| 504 | test.img |
| 505 | |
| 506 | Troubleshooting migration |
| 507 | ------------------------- |
| 508 | |
| 509 | There are several reasons why migration may fail. In case of problems, |
| 510 | please ensure that the command lines adhere to the following rules |
| 511 | and, if possible, that identical versions of QEMU and swtpm are used |
| 512 | at all times. |
| 513 | |
| 514 | VM save and restore: |
| 515 | |
| 516 | - QEMU command line parameters should be identical apart from the |
| 517 | '-incoming' option on VM restore |
| 518 | |
| 519 | - swtpm command line parameters should be identical |
| 520 | |
| 521 | VM migration to 'localhost': |
| 522 | |
| 523 | - QEMU command line parameters should be identical apart from the |
| 524 | '-incoming' option on the destination side |
| 525 | |
| 526 | - swtpm command line parameters should point to two different |
| 527 | directories on the source and destination swtpm (--tpmstate dir=...) |
| 528 | (especially if different versions of libtpms were to be used on the |
| 529 | same machine). |
| 530 | |
| 531 | VM migration across the network: |
| 532 | |
| 533 | - QEMU command line parameters should be identical apart from the |
| 534 | '-incoming' option on the destination side |
| 535 | |
| 536 | - swtpm command line parameters should be identical |
| 537 | |
| 538 | VM Snapshotting: |
| 539 | - QEMU command line parameters should be identical |
| 540 | |
| 541 | - swtpm command line parameters should be identical |
| 542 | |
| 543 | |
| 544 | Besides that, migration failure reasons on the swtpm level may include |
| 545 | the following: |
| 546 | |
| 547 | - the versions of the swtpm on the source and destination sides are |
| 548 | incompatible |
| 549 | |
| 550 | - downgrading of TPM state may not be supported |
| 551 | |
| 552 | - the source and destination libtpms were compiled with different |
| 553 | compile-time options and the destination side refuses to accept the |
| 554 | state |
| 555 | |
| 556 | - different migration keys are used on the source and destination side |
| 557 | and the destination side cannot decrypt the migrated state |
| 558 | (swtpm ... --migration-key ... ) |
| 559 | |
| 560 | |
| 561 | .. _TIS specification: |
| 562 | https://trustedcomputinggroup.org/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis/ |
| 563 | |
| 564 | .. _CRB specification: |
| 565 | https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/ |
| 566 | |
| 567 | |
| 568 | .. _ACPI specification: |
| 569 | https://trustedcomputinggroup.org/tcg-acpi-specification/ |
| 570 | |
| 571 | .. _PPI specification: |
| 572 | https://trustedcomputinggroup.org/resource/tcg-physical-presence-interface-specification/ |
| 573 | |
| 574 | .. _SWTPM protocol: |
| 575 | https://github.com/stefanberger/swtpm/blob/master/man/man3/swtpm_ioctls.pod |