summary refs log tree commit diff stats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/devel/memory.txt5
-rw-r--r--docs/devel/qapi-code-gen.txt11
-rw-r--r--docs/interop/firmware.json540
-rw-r--r--docs/specs/tpm.txt106
4 files changed, 658 insertions, 4 deletions
diff --git a/docs/devel/memory.txt b/docs/devel/memory.txt
index 8ed810f8b9..c1dee1252c 100644
--- a/docs/devel/memory.txt
+++ b/docs/devel/memory.txt
@@ -77,9 +77,8 @@ MemoryRegion):
 - reservation region: a reservation region is primarily for debugging.
   It claims I/O space that is not supposed to be handled by QEMU itself.
   The typical use is to track parts of the address space which will be
-  handled by the host kernel when KVM is enabled.
-  You initialize these with memory_region_init_reservation(), or by
-  passing a NULL callback parameter to memory_region_init_io().
+  handled by the host kernel when KVM is enabled.  You initialize these
+  by passing a NULL callback parameter to memory_region_init_io().
 
 It is valid to add subregions to a region which is not a pure container
 (that is, to an MMIO, RAM or ROM region). This means that the region
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index b9b6eabd08..1366228b2a 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -559,7 +559,7 @@ following example objects:
 Usage: { 'command': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
          '*returns': TYPE-NAME, '*boxed': true,
          '*gen': false, '*success-response': false,
-         '*allow-oob': true }
+         '*allow-oob': true, '*allow-preconfig': true }
 
 Commands are defined by using a dictionary containing several members,
 where three members are most common.  The 'command' member is a
@@ -683,6 +683,15 @@ OOB command handlers must satisfy the following conditions:
 
 If in doubt, do not implement OOB execution support.
 
+A command may use the optional 'allow-preconfig' key to permit its execution
+at early runtime configuration stage (preconfig runstate).
+If not specified then a command defaults to 'allow-preconfig': false.
+
+An example of declaring a command that is enabled during preconfig:
+ { 'command': 'qmp_capabilities',
+   'data': { '*enable': [ 'QMPCapability' ] },
+   'allow-preconfig': true }
+
 === Events ===
 
 Usage: { 'event': STRING, '*data': COMPLEX-TYPE-NAME-OR-DICT,
diff --git a/docs/interop/firmware.json b/docs/interop/firmware.json
new file mode 100644
index 0000000000..28f9bc1591
--- /dev/null
+++ b/docs/interop/firmware.json
@@ -0,0 +1,540 @@
+# -*- Mode: Python -*-
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# Authors:
+#  Daniel P. Berrange <berrange@redhat.com>
+#  Laszlo Ersek <lersek@redhat.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.
+
+##
+# = Firmware
+##
+
+{ 'include' : 'common.json' }
+{ 'include' : 'block-core.json' }
+
+##
+# @FirmwareOSInterface:
+#
+# Lists the firmware-OS interface types provided by various firmware
+# that is commonly used with QEMU virtual machines.
+#
+# @bios: Traditional x86 BIOS interface. For example, firmware built
+#        from the SeaBIOS project usually provides this interface.
+#
+# @openfirmware: The interface is defined by the (historical) IEEE
+#                1275-1994 standard. Examples for firmware projects that
+#                provide this interface are: OpenBIOS, OpenHackWare,
+#                SLOF.
+#
+# @uboot: Firmware interface defined by the U-Boot project.
+#
+# @uefi: Firmware interface defined by the UEFI specification. For
+#        example, firmware built from the edk2 (EFI Development Kit II)
+#        project usually provides this interface.
+#
+# Since: 3.0
+##
+{ 'enum' : 'FirmwareOSInterface',
+  'data' : [ 'bios', 'openfirmware', 'uboot', 'uefi' ] }
+
+##
+# @FirmwareDevice:
+#
+# Defines the device types that firmware can be mapped into.
+#
+# @flash: The firmware executable and its accompanying NVRAM file are to
+#         be mapped into a pflash chip each.
+#
+# @kernel: The firmware is to be loaded like a Linux kernel. This is
+#          similar to @memory but may imply additional processing that
+#          is specific to the target architecture and machine type.
+#
+# @memory: The firmware is to be mapped into memory.
+#
+# Since: 3.0
+##
+{ 'enum' : 'FirmwareDevice',
+  'data' : [ 'flash', 'kernel', 'memory' ] }
+
+##
+# @FirmwareTarget:
+#
+# Defines the machine types that firmware may execute on.
+#
+# @architecture: Determines the emulation target (the QEMU system
+#                emulator) that can execute the firmware.
+#
+# @machines: Lists the machine types (known by the emulator that is
+#            specified through @architecture) that can execute the
+#            firmware. Elements of @machines are supposed to be concrete
+#            machine types, not aliases. Glob patterns are understood,
+#            which is especially useful for versioned machine types.
+#            (For example, the glob pattern "pc-i440fx-*" matches
+#            "pc-i440fx-2.12".) On the QEMU command line, "-machine
+#            type=..." specifies the requested machine type (but that
+#            option does not accept glob patterns).
+#
+# Since: 3.0
+##
+{ 'struct' : 'FirmwareTarget',
+  'data'   : { 'architecture' : 'SysEmuTarget',
+               'machines'     : [ 'str' ] } }
+
+##
+# @FirmwareFeature:
+#
+# Defines the features that firmware may support, and the platform
+# requirements that firmware may present.
+#
+# @acpi-s3: The firmware supports S3 sleep (suspend to RAM), as defined
+#           in the ACPI specification. On the "pc-i440fx-*" machine
+#           types of the @i386 and @x86_64 emulation targets, S3 can be
+#           enabled with "-global PIIX4_PM.disable_s3=0" and disabled
+#           with "-global PIIX4_PM.disable_s3=1". On the "pc-q35-*"
+#           machine types of the @i386 and @x86_64 emulation targets, S3
+#           can be enabled with "-global ICH9-LPC.disable_s3=0" and
+#           disabled with "-global ICH9-LPC.disable_s3=1".
+#
+# @acpi-s4: The firmware supports S4 hibernation (suspend to disk), as
+#           defined in the ACPI specification. On the "pc-i440fx-*"
+#           machine types of the @i386 and @x86_64 emulation targets, S4
+#           can be enabled with "-global PIIX4_PM.disable_s4=0" and
+#           disabled with "-global PIIX4_PM.disable_s4=1". On the
+#           "pc-q35-*" machine types of the @i386 and @x86_64 emulation
+#           targets, S4 can be enabled with "-global
+#           ICH9-LPC.disable_s4=0" and disabled with "-global
+#           ICH9-LPC.disable_s4=1".
+#
+# @amd-sev: The firmware supports running under AMD Secure Encrypted
+#           Virtualization, as specified in the AMD64 Architecture
+#           Programmer's Manual. QEMU command line options related to
+#           this feature are documented in
+#           "docs/amd-memory-encryption.txt".
+#
+# @enrolled-keys: The variable store (NVRAM) template associated with
+#                 the firmware binary has the UEFI Secure Boot
+#                 operational mode turned on, with certificates
+#                 enrolled.
+#
+# @requires-smm: The firmware requires the platform to emulate SMM
+#                (System Management Mode), as defined in the AMD64
+#                Architecture Programmer's Manual, and in the Intel(R)64
+#                and IA-32 Architectures Software Developer's Manual. On
+#                the "pc-q35-*" machine types of the @i386 and @x86_64
+#                emulation targets, SMM emulation can be enabled with
+#                "-machine smm=on". (On the "pc-q35-*" machine types of
+#                the @i386 emulation target, @requires-smm presents
+#                further CPU requirements; one combination known to work
+#                is "-cpu coreduo,-nx".) If the firmware is marked as
+#                both @secure-boot and @requires-smm, then write
+#                accesses to the pflash chip (NVRAM) that holds the UEFI
+#                variable store must be restricted to code that executes
+#                in SMM, using the additional option "-global
+#                driver=cfi.pflash01,property=secure,value=on".
+#                Furthermore, a large guest-physical address space
+#                (comprising guest RAM, memory hotplug range, and 64-bit
+#                PCI MMIO aperture), and/or a high VCPU count, may
+#                present high SMRAM requirements from the firmware. On
+#                the "pc-q35-*" machine types of the @i386 and @x86_64
+#                emulation targets, the SMRAM size may be increased
+#                above the default 16MB with the "-global
+#                mch.extended-tseg-mbytes=uint16" option. As a rule of
+#                thumb, the default 16MB size suffices for 1TB of
+#                guest-phys address space and a few tens of VCPUs; for
+#                every further TB of guest-phys address space, add 8MB
+#                of SMRAM. 48MB should suffice for 4TB of guest-phys
+#                address space and 2-3 hundred VCPUs.
+#
+# @secure-boot: The firmware implements the software interfaces for UEFI
+#               Secure Boot, as defined in the UEFI specification. Note
+#               that without @requires-smm, guest code running with
+#               kernel privileges can undermine the security of Secure
+#               Boot.
+#
+# @verbose-dynamic: When firmware log capture is enabled, the firmware
+#                   logs a large amount of debug messages, which may
+#                   impact boot performance. With log capture disabled,
+#                   there is no boot performance impact. On the
+#                   "pc-i440fx-*" and "pc-q35-*" machine types of the
+#                   @i386 and @x86_64 emulation targets, firmware log
+#                   capture can be enabled with the QEMU command line
+#                   options "-chardev file,id=fwdebug,path=LOGFILEPATH
+#                   -device isa-debugcon,iobase=0x402,chardev=fwdebug".
+#                   @verbose-dynamic is mutually exclusive with
+#                   @verbose-static.
+#
+# @verbose-static: The firmware unconditionally produces a large amount
+#                  of debug messages, which may impact boot performance.
+#                  This feature may typically be carried by certain UEFI
+#                  firmware for the "virt-*" machine types of the @arm
+#                  and @aarch64 emulation targets, where the debug
+#                  messages are written to the first (always present)
+#                  PL011 UART. @verbose-static is mutually exclusive
+#                  with @verbose-dynamic.
+#
+# Since: 3.0
+##
+{ 'enum' : 'FirmwareFeature',
+  'data' : [ 'acpi-s3', 'acpi-s4', 'amd-sev', 'enrolled-keys',
+             'requires-smm', 'secure-boot', 'verbose-dynamic',
+             'verbose-static' ] }
+
+##
+# @FirmwareFlashFile:
+#
+# Defines common properties that are necessary for loading a firmware
+# file into a pflash chip. The corresponding QEMU command line option is
+# "-drive file=@filename,format=@format". Note however that the
+# option-argument shown here is incomplete; it is completed under
+# @FirmwareMappingFlash.
+#
+# @filename: Specifies the filename on the host filesystem where the
+#            firmware file can be found.
+#
+# @format: Specifies the block format of the file pointed-to by
+#          @filename, such as @raw or @qcow2.
+#
+# Since: 3.0
+##
+{ 'struct' : 'FirmwareFlashFile',
+  'data'   : { 'filename' : 'str',
+               'format'   : 'BlockdevDriver' } }
+
+##
+# @FirmwareMappingFlash:
+#
+# Describes loading and mapping properties for the firmware executable
+# and its accompanying NVRAM file, when @FirmwareDevice is @flash.
+#
+# @executable: Identifies the firmware executable. The firmware
+#              executable may be shared by multiple virtual machine
+#              definitions. The corresponding QEMU command line option
+#              is "-drive
+#              if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format".
+#
+# @nvram-template: Identifies the NVRAM template compatible with
+#                  @executable. Management software instantiates an
+#                  individual copy -- a specific NVRAM file -- from
+#                  @nvram-template.@filename for each new virtual
+#                  machine definition created. @nvram-template.@filename
+#                  itself is never mapped into virtual machines, only
+#                  individual copies of it are. An NVRAM file is
+#                  typically used for persistently storing the
+#                  non-volatile UEFI variables of a virtual machine
+#                  definition. The corresponding QEMU command line
+#                  option is "-drive
+#                  if=pflash,unit=1,readonly=off,file=FILENAME_OF_PRIVATE_NVRAM_FILE,format=@nvram-template.@format".
+#
+# Since: 3.0
+##
+{ 'struct' : 'FirmwareMappingFlash',
+  'data'   : { 'executable'     : 'FirmwareFlashFile',
+               'nvram-template' : 'FirmwareFlashFile' } }
+
+##
+# @FirmwareMappingKernel:
+#
+# Describes loading and mapping properties for the firmware executable,
+# when @FirmwareDevice is @kernel.
+#
+# @filename: Identifies the firmware executable. The firmware executable
+#            may be shared by multiple virtual machine definitions. The
+#            corresponding QEMU command line option is "-kernel
+#            @filename".
+#
+# Since: 3.0
+##
+{ 'struct' : 'FirmwareMappingKernel',
+  'data'   : { 'filename' : 'str' } }
+
+##
+# @FirmwareMappingMemory:
+#
+# Describes loading and mapping properties for the firmware executable,
+# when @FirmwareDevice is @memory.
+#
+# @filename: Identifies the firmware executable. The firmware executable
+#            may be shared by multiple virtual machine definitions. The
+#            corresponding QEMU command line option is "-bios
+#            @filename".
+#
+# Since: 3.0
+##
+{ 'struct' : 'FirmwareMappingMemory',
+  'data'   : { 'filename' : 'str' } }
+
+##
+# @FirmwareMapping:
+#
+# Provides a discriminated structure for firmware to describe its
+# loading / mapping properties.
+#
+# @device: Selects the device type that the firmware must be mapped
+#          into.
+#
+# Since: 3.0
+##
+{ 'union'         : 'FirmwareMapping',
+  'base'          : { 'device' : 'FirmwareDevice' },
+  'discriminator' : 'device',
+  'data'          : { 'flash'  : 'FirmwareMappingFlash',
+                      'kernel' : 'FirmwareMappingKernel',
+                      'memory' : 'FirmwareMappingMemory' } }
+
+##
+# @Firmware:
+#
+# Describes a firmware (or a firmware use case) to management software.
+#
+# It is possible for multiple @Firmware elements to match the search
+# criteria of management software. Applications thus need rules to pick
+# one of the many matches, and users need the ability to override distro
+# defaults.
+#
+# It is recommended to create firmware JSON files (each containing a
+# single @Firmware root element) with a double-digit prefix, for example
+# "50-ovmf.json", "50-seabios-256k.json", etc, so they can be sorted in
+# predictable order. The firmware JSON files should be searched for in
+# three directories:
+#
+#   - /usr/share/qemu/firmware -- populated by distro-provided firmware
+#                                 packages (XDG_DATA_DIRS covers
+#                                 /usr/share by default),
+#
+#   - /etc/qemu/firmware -- exclusively for sysadmins' local additions,
+#
+#   - $XDG_CONFIG_HOME/qemu/firmware -- exclusively for per-user local
+#                                       additions (XDG_CONFIG_HOME
+#                                       defaults to $HOME/.config).
+#
+# Top-down, the list of directories goes from general to specific.
+#
+# Management software should build a list of files from all three
+# locations, then sort the list by filename (i.e., last pathname
+# component). Management software should choose the first JSON file on
+# the sorted list that matches the search criteria. If a more specific
+# directory has a file with same name as a less specific directory, then
+# the file in the more specific directory takes effect. If the more
+# specific file is zero length, it hides the less specific one.
+#
+# For example, if a distro ships
+#
+#   - /usr/share/qemu/firmware/50-ovmf.json
+#
+#   - /usr/share/qemu/firmware/50-seabios-256k.json
+#
+# then the sysadmin can prevent the default OVMF being used at all with
+#
+#   $ touch /etc/qemu/firmware/50-ovmf.json
+#
+# The sysadmin can replace/alter the distro default OVMF with
+#
+#   $ vim /etc/qemu/firmware/50-ovmf.json
+#
+# or they can provide a parallel OVMF with higher priority
+#
+#   $ vim /etc/qemu/firmware/10-ovmf.json
+#
+# or they can provide a parallel OVMF with lower priority
+#
+#   $ vim /etc/qemu/firmware/99-ovmf.json
+#
+# @description: Provides a human-readable description of the firmware.
+#               Management software may or may not display @description.
+#
+# @interface-types: Lists the types of interfaces that the firmware can
+#                   expose to the guest OS. This is a non-empty, ordered
+#                   list; entries near the beginning of @interface-types
+#                   are considered more native to the firmware, and/or
+#                   to have a higher quality implementation in the
+#                   firmware, than entries near the end of
+#                   @interface-types.
+#
+# @mapping: Describes the loading / mapping properties of the firmware.
+#
+# @targets: Collects the target architectures (QEMU system emulators)
+#           and their machine types that may execute the firmware.
+#
+# @features: Lists the features that the firmware supports, and the
+#            platform requirements it presents.
+#
+# @tags: A list of auxiliary strings associated with the firmware for
+#        which @description is not appropriate, due to the latter's
+#        possible exposure to the end-user. @tags serves development and
+#        debugging purposes only, and management software shall
+#        explicitly ignore it.
+#
+# Since: 3.0
+#
+# Examples:
+#
+# {
+#     "description": "SeaBIOS",
+#     "interface-types": [
+#         "bios"
+#     ],
+#     "mapping": {
+#         "device": "memory",
+#         "filename": "/usr/share/seabios/bios-256k.bin"
+#     },
+#     "targets": [
+#         {
+#             "architecture": "i386",
+#             "machines": [
+#                 "pc-i440fx-*",
+#                 "pc-q35-*"
+#             ]
+#         },
+#         {
+#             "architecture": "x86_64",
+#             "machines": [
+#                 "pc-i440fx-*",
+#                 "pc-q35-*"
+#             ]
+#         }
+#     ],
+#     "features": [
+#         "acpi-s3",
+#         "acpi-s4"
+#     ],
+#     "tags": [
+#         "CONFIG_BOOTSPLASH=n",
+#         "CONFIG_ROM_SIZE=256",
+#         "CONFIG_USE_SMM=n"
+#     ]
+# }
+#
+# {
+#     "description": "OVMF with SB+SMM, empty varstore",
+#     "interface-types": [
+#         "uefi"
+#     ],
+#     "mapping": {
+#         "device": "flash",
+#         "executable": {
+#             "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
+#             "format": "raw"
+#         },
+#         "nvram-template": {
+#             "filename": "/usr/share/OVMF/OVMF_VARS.fd",
+#             "format": "raw"
+#         }
+#     },
+#     "targets": [
+#         {
+#             "architecture": "x86_64",
+#             "machines": [
+#                 "pc-q35-*"
+#             ]
+#         }
+#     ],
+#     "features": [
+#         "acpi-s3",
+#         "amd-sev",
+#         "requires-smm",
+#         "secure-boot",
+#         "verbose-dynamic"
+#     ],
+#     "tags": [
+#         "-a IA32",
+#         "-a X64",
+#         "-p OvmfPkg/OvmfPkgIa32X64.dsc",
+#         "-t GCC48",
+#         "-b DEBUG",
+#         "-D SMM_REQUIRE",
+#         "-D SECURE_BOOT_ENABLE",
+#         "-D FD_SIZE_4MB"
+#     ]
+# }
+#
+# {
+#     "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled",
+#     "interface-types": [
+#         "uefi"
+#     ],
+#     "mapping": {
+#         "device": "flash",
+#         "executable": {
+#             "filename": "/usr/share/OVMF/OVMF_CODE.secboot.fd",
+#             "format": "raw"
+#         },
+#         "nvram-template": {
+#             "filename": "/usr/share/OVMF/OVMF_VARS.secboot.fd",
+#             "format": "raw"
+#         }
+#     },
+#     "targets": [
+#         {
+#             "architecture": "x86_64",
+#             "machines": [
+#                 "pc-q35-*"
+#             ]
+#         }
+#     ],
+#     "features": [
+#         "acpi-s3",
+#         "amd-sev",
+#         "enrolled-keys",
+#         "requires-smm",
+#         "secure-boot",
+#         "verbose-dynamic"
+#     ],
+#     "tags": [
+#         "-a IA32",
+#         "-a X64",
+#         "-p OvmfPkg/OvmfPkgIa32X64.dsc",
+#         "-t GCC48",
+#         "-b DEBUG",
+#         "-D SMM_REQUIRE",
+#         "-D SECURE_BOOT_ENABLE",
+#         "-D FD_SIZE_4MB"
+#     ]
+# }
+#
+# {
+#     "description": "UEFI firmware for ARM64 virtual machines",
+#     "interface-types": [
+#         "uefi"
+#     ],
+#     "mapping": {
+#         "device": "flash",
+#         "executable": {
+#             "filename": "/usr/share/AAVMF/AAVMF_CODE.fd",
+#             "format": "raw"
+#         },
+#         "nvram-template": {
+#             "filename": "/usr/share/AAVMF/AAVMF_VARS.fd",
+#             "format": "raw"
+#         }
+#     },
+#     "targets": [
+#         {
+#             "architecture": "aarch64",
+#             "machines": [
+#                 "virt-*"
+#             ]
+#         }
+#     ],
+#     "features": [
+#
+#     ],
+#     "tags": [
+#         "-a AARCH64",
+#         "-p ArmVirtPkg/ArmVirtQemu.dsc",
+#         "-t GCC48",
+#         "-b DEBUG",
+#         "-D DEBUG_PRINT_ERROR_LEVEL=0x80000000"
+#     ]
+# }
+##
+{ 'struct' : 'Firmware',
+  'data'   : { 'description'     : 'str',
+               'interface-types' : [ 'FirmwareOSInterface' ],
+               'mapping'         : 'FirmwareMapping',
+               'targets'         : [ 'FirmwareTarget' ],
+               'features'        : [ 'FirmwareFeature' ],
+               'tags'            : [ 'str' ] } }
diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
index d1d71571e9..c230c4c93e 100644
--- a/docs/specs/tpm.txt
+++ b/docs/specs/tpm.txt
@@ -200,3 +200,109 @@ crw-------. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
 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 -enable-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 additonal
+'-incoming' option.
+
+qemu-system-x86_64 -display sdl -enable-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 ... )