qemu/docs/specs/vmgenid.txt
<<
>>
Prefs
   1VIRTUAL MACHINE GENERATION ID
   2=============================
   3
   4Copyright (C) 2016 Red Hat, Inc.
   5Copyright (C) 2017 Skyport Systems, Inc.
   6
   7This work is licensed under the terms of the GNU GPL, version 2 or later.
   8See the COPYING file in the top-level directory.
   9
  10===
  11
  12The VM generation ID (vmgenid) device is an emulated device which
  13exposes a 128-bit, cryptographically random, integer value identifier,
  14referred to as a Globally Unique Identifier, or GUID.
  15
  16This allows management applications (e.g. libvirt) to notify the guest
  17operating system when the virtual machine is executed with a different
  18configuration (e.g. snapshot execution or creation from a template).  The
  19guest operating system notices the change, and is then able to react as
  20appropriate by marking its copies of distributed databases as dirty,
  21re-initializing its random number generator etc.
  22
  23
  24Requirements
  25------------
  26
  27These requirements are extracted from the "How to implement virtual machine
  28generation ID support in a virtualization platform" section of the
  29specification, dated August 1, 2012.
  30
  31
  32The document may be found on the web at:
  33  http://go.microsoft.com/fwlink/?LinkId=260709
  34
  35R1a. The generation ID shall live in an 8-byte aligned buffer.
  36
  37R1b. The buffer holding the generation ID shall be in guest RAM, ROM, or device
  38     MMIO range.
  39
  40R1c. The buffer holding the generation ID shall be kept separate from areas
  41     used by the operating system.
  42
  43R1d. The buffer shall not be covered by an AddressRangeMemory or
  44     AddressRangeACPI entry in the E820 or UEFI memory map.
  45
  46R1e. The generation ID shall not live in a page frame that could be mapped with
  47     caching disabled. (In other words, regardless of whether the generation ID
  48     lives in RAM, ROM or MMIO, it shall only be mapped as cacheable.)
  49
  50R2 to R5. [These AML requirements are isolated well enough in the Microsoft
  51          specification for us to simply refer to them here.]
  52
  53R6. The hypervisor shall expose a _HID (hardware identifier) object in the
  54    VMGenId device's scope that is unique to the hypervisor vendor.
  55
  56
  57QEMU Implementation
  58-------------------
  59
  60The above-mentioned specification does not dictate which ACPI descriptor table
  61will contain the VM Generation ID device.  Other implementations (Hyper-V and
  62Xen) put it in the main descriptor table (Differentiated System Description
  63Table or DSDT).  For ease of debugging and implementation, we have decided to
  64put it in its own Secondary System Description Table, or SSDT.
  65
  66The following is a dump of the contents from a running system:
  67
  68# iasl -p ./SSDT -d /sys/firmware/acpi/tables/SSDT
  69
  70Intel ACPI Component Architecture
  71ASL+ Optimizing Compiler version 20150717-64
  72Copyright (c) 2000 - 2015 Intel Corporation
  73
  74Reading ACPI table from file /sys/firmware/acpi/tables/SSDT - Length
  7500000198 (0x0000C6)
  76ACPI: SSDT 0x0000000000000000 0000C6 (v01 BOCHS  VMGENID  00000001 BXPC
  7700000001)
  78Acpi table [SSDT] successfully installed and loaded
  79Pass 1 parse of [SSDT]
  80Pass 2 parse of [SSDT]
  81Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
  82
  83Parsing completed
  84Disassembly completed
  85ASL Output:    ./SSDT.dsl - 1631 bytes
  86# cat SSDT.dsl
  87/*
  88 * Intel ACPI Component Architecture
  89 * AML/ASL+ Disassembler version 20150717-64
  90 * Copyright (c) 2000 - 2015 Intel Corporation
  91 *
  92 * Disassembling to symbolic ASL+ operators
  93 *
  94 * Disassembly of /sys/firmware/acpi/tables/SSDT, Sun Feb  5 00:19:37 2017
  95 *
  96 * Original Table Header:
  97 *     Signature        "SSDT"
  98 *     Length           0x000000CA (202)
  99 *     Revision         0x01
 100 *     Checksum         0x4B
 101 *     OEM ID           "BOCHS "
 102 *     OEM Table ID     "VMGENID"
 103 *     OEM Revision     0x00000001 (1)
 104 *     Compiler ID      "BXPC"
 105 *     Compiler Version 0x00000001 (1)
 106 */
 107DefinitionBlock ("/sys/firmware/acpi/tables/SSDT.aml", "SSDT", 1, "BOCHS ",
 108"VMGENID", 0x00000001)
 109{
 110    Name (VGIA, 0x07FFF000)
 111    Scope (\_SB)
 112    {
 113        Device (VGEN)
 114        {
 115            Name (_HID, "QEMUVGID")  // _HID: Hardware ID
 116            Name (_CID, "VM_Gen_Counter")  // _CID: Compatible ID
 117            Name (_DDN, "VM_Gen_Counter")  // _DDN: DOS Device Name
 118            Method (_STA, 0, NotSerialized)  // _STA: Status
 119            {
 120                Local0 = 0x0F
 121                If ((VGIA == Zero))
 122                {
 123                    Local0 = Zero
 124                }
 125
 126                Return (Local0)
 127            }
 128
 129            Method (ADDR, 0, NotSerialized)
 130            {
 131                Local0 = Package (0x02) {}
 132                Index (Local0, Zero) = (VGIA + 0x28)
 133                Index (Local0, One) = Zero
 134                Return (Local0)
 135            }
 136        }
 137    }
 138
 139    Method (\_GPE._E05, 0, NotSerialized)  // _Exx: Edge-Triggered GPE
 140    {
 141        Notify (\_SB.VGEN, 0x80) // Status Change
 142    }
 143}
 144
 145
 146Design Details:
 147---------------
 148
 149Requirements R1a through R1e dictate that the memory holding the
 150VM Generation ID must be allocated and owned by the guest firmware,
 151in this case BIOS or UEFI.  However, to be useful, QEMU must be able to
 152change the contents of the memory at runtime, specifically when starting a
 153backed-up or snapshotted image.  In order to do this, QEMU must know the
 154address that has been allocated.
 155
 156The mechanism chosen for this memory sharing is writeable fw_cfg blobs.
 157These are data object that are visible to both QEMU and guests, and are
 158addressable as sequential files.
 159
 160More information about fw_cfg can be found in "docs/specs/fw_cfg.txt"
 161
 162Two fw_cfg blobs are used in this case:
 163
 164/etc/vmgenid_guid - contains the actual VM Generation ID GUID
 165                  - read-only to the guest
 166/etc/vmgenid_addr - contains the address of the downloaded vmgenid blob
 167                  - writeable by the guest
 168
 169
 170QEMU sends the following commands to the guest at startup:
 171
 1721. Allocate memory for vmgenid_guid fw_cfg blob.
 1732. Write the address of vmgenid_guid into the SSDT (VGIA ACPI variable as
 174   shown above in the iasl dump).  Note that this change is not propagated
 175   back to QEMU.
 1763. Write the address of vmgenid_guid back to QEMU's copy of vmgenid_addr
 177   via the fw_cfg DMA interface.
 178
 179After step 3, QEMU is able to update the contents of vmgenid_guid at will.
 180
 181Since BIOS or UEFI does not necessarily run when we wish to change the GUID,
 182the value of VGIA is persisted via the VMState mechanism.
 183
 184As spelled out in the specification, any change to the GUID executes an
 185ACPI notification.  The exact handler to use is not specified, so the vmgenid
 186device uses the first unused one:  \_GPE._E05.
 187
 188
 189Endian-ness Considerations:
 190---------------------------
 191
 192Although not specified in Microsoft's document, it is assumed that the
 193device is expected to use little-endian format.
 194
 195All GUID passed in via command line or monitor are treated as big-endian.
 196GUID values displayed via monitor are shown in big-endian format.
 197
 198
 199GUID Storage Format:
 200--------------------
 201
 202In order to implement an OVMF "SDT Header Probe Suppressor", the contents of
 203the vmgenid_guid fw_cfg blob are not simply a 128-bit GUID.  There is also
 204significant padding in order to align and fill a memory page, as shown in the
 205following diagram:
 206
 207+----------------------------------+
 208| SSDT with OEM Table ID = VMGENID |
 209+----------------------------------+
 210| ...                              |       TOP OF PAGE
 211| VGIA dword object ---------------|-----> +---------------------------+
 212| ...                              |       | fw-allocated array for    |
 213| _STA method referring to VGIA    |       | "etc/vmgenid_guid"        |
 214| ...                              |       +---------------------------+
 215| ADDR method referring to VGIA    |       |  0: OVMF SDT Header probe |
 216| ...                              |       |     suppressor            |
 217+----------------------------------+       | 36: padding for 8-byte    |
 218                                           |     alignment             |
 219                                           | 40: GUID                  |
 220                                           | 56: padding to page size  |
 221                                           +---------------------------+
 222                                           END OF PAGE
 223
 224
 225Device Usage:
 226-------------
 227
 228The device has one property, which may be only be set using the command line:
 229
 230  guid - sets the value of the GUID.  A special value "auto" instructs
 231         QEMU to generate a new random GUID.
 232
 233For example:
 234
 235  QEMU  -device vmgenid,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
 236  QEMU  -device vmgenid,guid=auto
 237
 238The property may be queried via QMP/HMP:
 239
 240  (QEMU) query-vm-generation-id
 241  {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
 242
 243Setting of this parameter is intentionally left out from the QMP/HMP
 244interfaces.  There are no known use cases for changing the GUID once QEMU is
 245running, and adding this capability would greatly increase the complexity.
 246