qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vmgenid.txt (8850B)


      1 VIRTUAL MACHINE GENERATION ID
      2 =============================
      3 
      4 Copyright (C) 2016 Red Hat, Inc.
      5 Copyright (C) 2017 Skyport Systems, Inc.
      6 
      7 This work is licensed under the terms of the GNU GPL, version 2 or later.
      8 See the COPYING file in the top-level directory.
      9 
     10 ===
     11 
     12 The VM generation ID (vmgenid) device is an emulated device which
     13 exposes a 128-bit, cryptographically random, integer value identifier,
     14 referred to as a Globally Unique Identifier, or GUID.
     15 
     16 This allows management applications (e.g. libvirt) to notify the guest
     17 operating system when the virtual machine is executed with a different
     18 configuration (e.g. snapshot execution or creation from a template).  The
     19 guest operating system notices the change, and is then able to react as
     20 appropriate by marking its copies of distributed databases as dirty,
     21 re-initializing its random number generator etc.
     22 
     23 
     24 Requirements
     25 ------------
     26 
     27 These requirements are extracted from the "How to implement virtual machine
     28 generation ID support in a virtualization platform" section of the
     29 specification, dated August 1, 2012.
     30 
     31 
     32 The document may be found on the web at:
     33   http://go.microsoft.com/fwlink/?LinkId=260709
     34 
     35 R1a. The generation ID shall live in an 8-byte aligned buffer.
     36 
     37 R1b. The buffer holding the generation ID shall be in guest RAM, ROM, or device
     38      MMIO range.
     39 
     40 R1c. The buffer holding the generation ID shall be kept separate from areas
     41      used by the operating system.
     42 
     43 R1d. The buffer shall not be covered by an AddressRangeMemory or
     44      AddressRangeACPI entry in the E820 or UEFI memory map.
     45 
     46 R1e. 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 
     50 R2 to R5. [These AML requirements are isolated well enough in the Microsoft
     51           specification for us to simply refer to them here.]
     52 
     53 R6. 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 
     57 QEMU Implementation
     58 -------------------
     59 
     60 The above-mentioned specification does not dictate which ACPI descriptor table
     61 will contain the VM Generation ID device.  Other implementations (Hyper-V and
     62 Xen) put it in the main descriptor table (Differentiated System Description
     63 Table or DSDT).  For ease of debugging and implementation, we have decided to
     64 put it in its own Secondary System Description Table, or SSDT.
     65 
     66 The following is a dump of the contents from a running system:
     67 
     68 # iasl -p ./SSDT -d /sys/firmware/acpi/tables/SSDT
     69 
     70 Intel ACPI Component Architecture
     71 ASL+ Optimizing Compiler version 20150717-64
     72 Copyright (c) 2000 - 2015 Intel Corporation
     73 
     74 Reading ACPI table from file /sys/firmware/acpi/tables/SSDT - Length
     75 00000198 (0x0000C6)
     76 ACPI: SSDT 0x0000000000000000 0000C6 (v01 BOCHS  VMGENID  00000001 BXPC
     77 00000001)
     78 Acpi table [SSDT] successfully installed and loaded
     79 Pass 1 parse of [SSDT]
     80 Pass 2 parse of [SSDT]
     81 Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
     82 
     83 Parsing completed
     84 Disassembly completed
     85 ASL 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  */
    107 DefinitionBlock ("/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 
    146 Design Details:
    147 ---------------
    148 
    149 Requirements R1a through R1e dictate that the memory holding the
    150 VM Generation ID must be allocated and owned by the guest firmware,
    151 in this case BIOS or UEFI.  However, to be useful, QEMU must be able to
    152 change the contents of the memory at runtime, specifically when starting a
    153 backed-up or snapshotted image.  In order to do this, QEMU must know the
    154 address that has been allocated.
    155 
    156 The mechanism chosen for this memory sharing is writable fw_cfg blobs.
    157 These are data object that are visible to both QEMU and guests, and are
    158 addressable as sequential files.
    159 
    160 More information about fw_cfg can be found in "docs/specs/fw_cfg.txt"
    161 
    162 Two 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                   - writable by the guest
    168 
    169 
    170 QEMU sends the following commands to the guest at startup:
    171 
    172 1. Allocate memory for vmgenid_guid fw_cfg blob.
    173 2. 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.
    176 3. Write the address of vmgenid_guid back to QEMU's copy of vmgenid_addr
    177    via the fw_cfg DMA interface.
    178 
    179 After step 3, QEMU is able to update the contents of vmgenid_guid at will.
    180 
    181 Since BIOS or UEFI does not necessarily run when we wish to change the GUID,
    182 the value of VGIA is persisted via the VMState mechanism.
    183 
    184 As spelled out in the specification, any change to the GUID executes an
    185 ACPI notification.  The exact handler to use is not specified, so the vmgenid
    186 device uses the first unused one:  \_GPE._E05.
    187 
    188 
    189 Endian-ness Considerations:
    190 ---------------------------
    191 
    192 Although not specified in Microsoft's document, it is assumed that the
    193 device is expected to use little-endian format.
    194 
    195 All GUID passed in via command line or monitor are treated as big-endian.
    196 GUID values displayed via monitor are shown in big-endian format.
    197 
    198 
    199 GUID Storage Format:
    200 --------------------
    201 
    202 In order to implement an OVMF "SDT Header Probe Suppressor", the contents of
    203 the vmgenid_guid fw_cfg blob are not simply a 128-bit GUID.  There is also
    204 significant padding in order to align and fill a memory page, as shown in the
    205 following 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 
    225 Device Usage:
    226 -------------
    227 
    228 The 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 
    233 For example:
    234 
    235   QEMU  -device vmgenid,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
    236   QEMU  -device vmgenid,guid=auto
    237 
    238 The property may be queried via QMP/HMP:
    239 
    240   (QEMU) query-vm-generation-id
    241   {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
    242 
    243 Setting of this parameter is intentionally left out from the QMP/HMP
    244 interfaces.  There are no known use cases for changing the GUID once QEMU is
    245 running, and adding this capability would greatly increase the complexity.