1Virtual Machine Generation ID Device 2==================================== 3 4.. 5 Copyright (C) 2016 Red Hat, Inc. 6 Copyright (C) 2017 Skyport Systems, Inc. 7 8 This work is licensed under the terms of the GNU GPL, version 2 or later. 9 See the COPYING file in the top-level directory. 10 11The VM generation ID (``vmgenid``) device is an emulated device which 12exposes a 128-bit, cryptographically random, integer value identifier, 13referred to as a Globally Unique Identifier, or GUID. 14 15This allows management applications (e.g. libvirt) to notify the guest 16operating system when the virtual machine is executed with a different 17configuration (e.g. snapshot execution or creation from a template). The 18guest operating system notices the change, and is then able to react as 19appropriate by marking its copies of distributed databases as dirty, 20re-initializing its random number generator etc. 21 22 23Requirements 24------------ 25 26These requirements are extracted from the "How to implement virtual machine 27generation ID support in a virtualization platform" section of 28`the Microsoft Virtual Machine Generation ID specification 29<http://go.microsoft.com/fwlink/?LinkId=260709>`_ dated August 1, 2012. 30 31- **R1a** The generation ID shall live in an 8-byte aligned buffer. 32 33- **R1b** The buffer holding the generation ID shall be in guest RAM, 34 ROM, or device MMIO range. 35 36- **R1c** The buffer holding the generation ID shall be kept separate from 37 areas used by the operating system. 38 39- **R1d** The buffer shall not be covered by an AddressRangeMemory or 40 AddressRangeACPI entry in the E820 or UEFI memory map. 41 42- **R1e** The generation ID shall not live in a page frame that could be 43 mapped with caching disabled. (In other words, regardless of whether the 44 generation ID lives in RAM, ROM or MMIO, it shall only be mapped as 45 cacheable.) 46 47- **R2** to **R5** [These AML requirements are isolated well enough in the 48 Microsoft specification for us to simply refer to them here.] 49 50- **R6** The hypervisor shall expose a _HID (hardware identifier) object 51 in the VMGenId device's scope that is unique to the hypervisor vendor. 52 53 54QEMU Implementation 55------------------- 56 57The above-mentioned specification does not dictate which ACPI descriptor table 58will contain the VM Generation ID device. Other implementations (Hyper-V and 59Xen) put it in the main descriptor table (Differentiated System Description 60Table or DSDT). For ease of debugging and implementation, we have decided to 61put it in its own Secondary System Description Table, or SSDT. 62 63The following is a dump of the contents from a running system:: 64 65 # iasl -p ./SSDT -d /sys/firmware/acpi/tables/SSDT 66 67 Intel ACPI Component Architecture 68 ASL+ Optimizing Compiler version 20150717-64 69 Copyright (c) 2000 - 2015 Intel Corporation 70 71 Reading ACPI table from file /sys/firmware/acpi/tables/SSDT - Length 72 00000198 (0x0000C6) 73 ACPI: SSDT 0x0000000000000000 0000C6 (v01 BOCHS VMGENID 00000001 BXPC 00000001) 74 Acpi table [SSDT] successfully installed and loaded 75 Pass 1 parse of [SSDT] 76 Pass 2 parse of [SSDT] 77 Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions) 78 79 Parsing completed 80 Disassembly completed 81 ASL Output: ./SSDT.dsl - 1631 bytes 82 # cat SSDT.dsl 83 /* 84 * Intel ACPI Component Architecture 85 * AML/ASL+ Disassembler version 20150717-64 86 * Copyright (c) 2000 - 2015 Intel Corporation 87 * 88 * Disassembling to symbolic ASL+ operators 89 * 90 * Disassembly of /sys/firmware/acpi/tables/SSDT, Sun Feb 5 00:19:37 2017 91 * 92 * Original Table Header: 93 * Signature "SSDT" 94 * Length 0x000000CA (202) 95 * Revision 0x01 96 * Checksum 0x4B 97 * OEM ID "BOCHS " 98 * OEM Table ID "VMGENID" 99 * OEM Revision 0x00000001 (1) 100 * Compiler ID "BXPC" 101 * Compiler Version 0x00000001 (1) 102 */ 103 DefinitionBlock ("/sys/firmware/acpi/tables/SSDT.aml", "SSDT", 1, "BOCHS ", "VMGENID", 0x00000001) 104 { 105 Name (VGIA, 0x07FFF000) 106 Scope (\_SB) 107 { 108 Device (VGEN) 109 { 110 Name (_HID, "QEMUVGID") // _HID: Hardware ID 111 Name (_CID, "VM_Gen_Counter") // _CID: Compatible ID 112 Name (_DDN, "VM_Gen_Counter") // _DDN: DOS Device Name 113 Method (_STA, 0, NotSerialized) // _STA: Status 114 { 115 Local0 = 0x0F 116 If ((VGIA == Zero)) 117 { 118 Local0 = Zero 119 } 120 121 Return (Local0) 122 } 123 124 Method (ADDR, 0, NotSerialized) 125 { 126 Local0 = Package (0x02) {} 127 Index (Local0, Zero) = (VGIA + 0x28) 128 Index (Local0, One) = Zero 129 Return (Local0) 130 } 131 } 132 } 133 134 Method (\_GPE._E05, 0, NotSerialized) // _Exx: Edge-Triggered GPE 135 { 136 Notify (\_SB.VGEN, 0x80) // Status Change 137 } 138 } 139 140 141Design Details: 142--------------- 143 144Requirements R1a through R1e dictate that the memory holding the 145VM Generation ID must be allocated and owned by the guest firmware, 146in this case BIOS or UEFI. However, to be useful, QEMU must be able to 147change the contents of the memory at runtime, specifically when starting a 148backed-up or snapshotted image. In order to do this, QEMU must know the 149address that has been allocated. 150 151The mechanism chosen for this memory sharing is writable fw_cfg blobs. 152These are data object that are visible to both QEMU and guests, and are 153addressable as sequential files. 154 155More information about fw_cfg can be found in :doc:`fw_cfg`. 156 157Two fw_cfg blobs are used in this case: 158 159``/etc/vmgenid_guid`` 160 161- contains the actual VM Generation ID GUID 162- read-only to the guest 163 164``/etc/vmgenid_addr`` 165 166- contains the address of the downloaded vmgenid blob 167- writable 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`` 231 sets the value of the GUID. A special value ``auto`` instructs 232 QEMU to generate a new random GUID. 233 234For example:: 235 236 QEMU -device vmgenid,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87" 237 QEMU -device vmgenid,guid=auto 238 239The property may be queried via QMP/HMP:: 240 241 (QEMU) query-vm-generation-id 242 {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}} 243 244Setting of this parameter is intentionally left out from the QMP/HMP 245interfaces. There are no known use cases for changing the GUID once QEMU is 246running, and adding this capability would greatly increase the complexity. 247