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.