xref: /openbmc/qemu/docs/specs/vmgenid.rst (revision 806f71ee)
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