> On 31-Oct-2023, at 9:13 PM, Philippe Mathieu-Daudé <phi...@linaro.org> wrote:
>
> On 27/9/23 17:12, Peter Maydell wrote:
>> Convert docs/specs/vmgenid.txt to rST format.
>> Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
>> ---
>> MAINTAINERS | 2 +-
>> docs/specs/index.rst | 1 +
>> docs/specs/vmgenid.rst | 246 +++++++++++++++++++++++++++++++++++++++++
>> docs/specs/vmgenid.txt | 245 ----------------------------------------
>> 4 files changed, 248 insertions(+), 246 deletions(-)
>> create mode 100644 docs/specs/vmgenid.rst
>> delete mode 100644 docs/specs/vmgenid.txt
>
> Cc'ing Ani.
Thanks Phil. I looked at the rendering here:
https://gitlab.com/anisinha/qemu/-/blob/review/docs/specs/vmgenid.rst?ref_type=heads
And it looks good.
Based on this
Reviewed-by: Ani Sinha <anisi...@redhat.com>
>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 23ee617acaf..d2338e3beb6 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2369,7 +2369,7 @@ S: Orphan
>> R: Ani Sinha <a...@anisinha.ca>
>> F: hw/acpi/vmgenid.c
>> F: include/hw/acpi/vmgenid.h
>> -F: docs/specs/vmgenid.txt
>> +F: docs/specs/vmgenid.rst
>> F: tests/qtest/vmgenid-test.c
>> LED
>> diff --git a/docs/specs/index.rst b/docs/specs/index.rst
>> index 7a56ccb2155..b3f482b0aa5 100644
>> --- a/docs/specs/index.rst
>> +++ b/docs/specs/index.rst
>> @@ -31,3 +31,4 @@ guest hardware that is specific to QEMU.
>> standard-vga
>> virt-ctlr
>> vmcoreinfo
>> + vmgenid
>> diff --git a/docs/specs/vmgenid.rst b/docs/specs/vmgenid.rst
>> new file mode 100644
>> index 00000000000..9a3cefcd828
>> --- /dev/null
>> +++ b/docs/specs/vmgenid.rst
>> @@ -0,0 +1,246 @@
>> +Virtual Machine Generation ID Device
>> +====================================
>> +
>> +..
>> + Copyright (C) 2016 Red Hat, Inc.
>> + Copyright (C) 2017 Skyport Systems, Inc.
>> +
>> + This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + See the COPYING file in the top-level directory.
>> +
>> +The VM generation ID (``vmgenid``) device is an emulated device which
>> +exposes a 128-bit, cryptographically random, integer value identifier,
>> +referred to as a Globally Unique Identifier, or GUID.
>> +
>> +This allows management applications (e.g. libvirt) to notify the guest
>> +operating system when the virtual machine is executed with a different
>> +configuration (e.g. snapshot execution or creation from a template). The
>> +guest operating system notices the change, and is then able to react as
>> +appropriate by marking its copies of distributed databases as dirty,
>> +re-initializing its random number generator etc.
>> +
>> +
>> +Requirements
>> +------------
>> +
>> +These requirements are extracted from the "How to implement virtual machine
>> +generation ID support in a virtualization platform" section of
>> +`the Microsoft Virtual Machine Generation ID specification
>> +<http://go.microsoft.com/fwlink/?LinkId=260709>`_ dated August 1, 2012.
>> +
>> +- **R1a** The generation ID shall live in an 8-byte aligned buffer.
>> +
>> +- **R1b** The buffer holding the generation ID shall be in guest RAM,
>> + ROM, or device MMIO range.
>> +
>> +- **R1c** The buffer holding the generation ID shall be kept separate from
>> + areas used by the operating system.
>> +
>> +- **R1d** The buffer shall not be covered by an AddressRangeMemory or
>> + AddressRangeACPI entry in the E820 or UEFI memory map.
>> +
>> +- **R1e** The generation ID shall not live in a page frame that could be
>> + mapped with caching disabled. (In other words, regardless of whether the
>> + generation ID lives in RAM, ROM or MMIO, it shall only be mapped as
>> + cacheable.)
>> +
>> +- **R2** to **R5** [These AML requirements are isolated well enough in the
>> + Microsoft specification for us to simply refer to them here.]
>> +
>> +- **R6** The hypervisor shall expose a _HID (hardware identifier) object
>> + in the VMGenId device's scope that is unique to the hypervisor vendor.
>> +
>> +
>> +QEMU Implementation
>> +-------------------
>> +
>> +The above-mentioned specification does not dictate which ACPI descriptor
>> table
>> +will contain the VM Generation ID device. Other implementations (Hyper-V
>> and
>> +Xen) put it in the main descriptor table (Differentiated System Description
>> +Table or DSDT). For ease of debugging and implementation, we have decided
>> to
>> +put it in its own Secondary System Description Table, or SSDT.
>> +
>> +The following is a dump of the contents from a running system::
>> +
>> + # iasl -p ./SSDT -d /sys/firmware/acpi/tables/SSDT
>> +
>> + Intel ACPI Component Architecture
>> + ASL+ Optimizing Compiler version 20150717-64
>> + Copyright (c) 2000 - 2015 Intel Corporation
>> +
>> + Reading ACPI table from file /sys/firmware/acpi/tables/SSDT - Length
>> + 00000198 (0x0000C6)
>> + ACPI: SSDT 0x0000000000000000 0000C6 (v01 BOCHS VMGENID 00000001 BXPC
>> 00000001)
>> + Acpi table [SSDT] successfully installed and loaded
>> + Pass 1 parse of [SSDT]
>> + Pass 2 parse of [SSDT]
>> + Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
>> +
>> + Parsing completed
>> + Disassembly completed
>> + ASL Output: ./SSDT.dsl - 1631 bytes
>> + # cat SSDT.dsl
>> + /*
>> + * Intel ACPI Component Architecture
>> + * AML/ASL+ Disassembler version 20150717-64
>> + * Copyright (c) 2000 - 2015 Intel Corporation
>> + *
>> + * Disassembling to symbolic ASL+ operators
>> + *
>> + * Disassembly of /sys/firmware/acpi/tables/SSDT, Sun Feb 5 00:19:37 2017
>> + *
>> + * Original Table Header:
>> + * Signature "SSDT"
>> + * Length 0x000000CA (202)
>> + * Revision 0x01
>> + * Checksum 0x4B
>> + * OEM ID "BOCHS "
>> + * OEM Table ID "VMGENID"
>> + * OEM Revision 0x00000001 (1)
>> + * Compiler ID "BXPC"
>> + * Compiler Version 0x00000001 (1)
>> + */
>> + DefinitionBlock ("/sys/firmware/acpi/tables/SSDT.aml", "SSDT", 1, "BOCHS
>> ", "VMGENID", 0x00000001)
>> + {
>> + Name (VGIA, 0x07FFF000)
>> + Scope (\_SB)
>> + {
>> + Device (VGEN)
>> + {
>> + Name (_HID, "QEMUVGID") // _HID: Hardware ID
>> + Name (_CID, "VM_Gen_Counter") // _CID: Compatible ID
>> + Name (_DDN, "VM_Gen_Counter") // _DDN: DOS Device Name
>> + Method (_STA, 0, NotSerialized) // _STA: Status
>> + {
>> + Local0 = 0x0F
>> + If ((VGIA == Zero))
>> + {
>> + Local0 = Zero
>> + }
>> +
>> + Return (Local0)
>> + }
>> +
>> + Method (ADDR, 0, NotSerialized)
>> + {
>> + Local0 = Package (0x02) {}
>> + Index (Local0, Zero) = (VGIA + 0x28)
>> + Index (Local0, One) = Zero
>> + Return (Local0)
>> + }
>> + }
>> + }
>> +
>> + Method (\_GPE._E05, 0, NotSerialized) // _Exx: Edge-Triggered GPE
>> + {
>> + Notify (\_SB.VGEN, 0x80) // Status Change
>> + }
>> + }
>> +
>> +
>> +Design Details:
>> +---------------
>> +
>> +Requirements R1a through R1e dictate that the memory holding the
>> +VM Generation ID must be allocated and owned by the guest firmware,
>> +in this case BIOS or UEFI. However, to be useful, QEMU must be able to
>> +change the contents of the memory at runtime, specifically when starting a
>> +backed-up or snapshotted image. In order to do this, QEMU must know the
>> +address that has been allocated.
>> +
>> +The mechanism chosen for this memory sharing is writable fw_cfg blobs.
>> +These are data object that are visible to both QEMU and guests, and are
>> +addressable as sequential files.
>> +
>> +More information about fw_cfg can be found in :doc:`fw_cfg`.
>> +
>> +Two fw_cfg blobs are used in this case:
>> +
>> +``/etc/vmgenid_guid``
>> +
>> +- contains the actual VM Generation ID GUID
>> +- read-only to the guest
>> +
>> +``/etc/vmgenid_addr``
>> +
>> +- contains the address of the downloaded vmgenid blob
>> +- writable by the guest
>> +
>> +
>> +QEMU sends the following commands to the guest at startup:
>> +
>> +1. Allocate memory for vmgenid_guid fw_cfg blob.
>> +2. Write the address of vmgenid_guid into the SSDT (VGIA ACPI variable as
>> + shown above in the iasl dump). Note that this change is not propagated
>> + back to QEMU.
>> +3. Write the address of vmgenid_guid back to QEMU's copy of vmgenid_addr
>> + via the fw_cfg DMA interface.
>> +
>> +After step 3, QEMU is able to update the contents of vmgenid_guid at will.
>> +
>> +Since BIOS or UEFI does not necessarily run when we wish to change the GUID,
>> +the value of VGIA is persisted via the VMState mechanism.
>> +
>> +As spelled out in the specification, any change to the GUID executes an
>> +ACPI notification. The exact handler to use is not specified, so the
>> vmgenid
>> +device uses the first unused one: ``\_GPE._E05``.
>> +
>> +
>> +Endian-ness Considerations:
>> +---------------------------
>> +
>> +Although not specified in Microsoft's document, it is assumed that the
>> +device is expected to use little-endian format.
>> +
>> +All GUID passed in via command line or monitor are treated as big-endian.
>> +GUID values displayed via monitor are shown in big-endian format.
>> +
>> +
>> +GUID Storage Format:
>> +--------------------
>> +
>> +In order to implement an OVMF "SDT Header Probe Suppressor", the contents of
>> +the vmgenid_guid fw_cfg blob are not simply a 128-bit GUID. There is also
>> +significant padding in order to align and fill a memory page, as shown in
>> the
>> +following diagram::
>> +
>> + +----------------------------------+
>> + | SSDT with OEM Table ID = VMGENID |
>> + +----------------------------------+
>> + | ... | TOP OF PAGE
>> + | VGIA dword object ---------------|-----> +---------------------------+
>> + | ... | | fw-allocated array for |
>> + | _STA method referring to VGIA | | "etc/vmgenid_guid" |
>> + | ... | +---------------------------+
>> + | ADDR method referring to VGIA | | 0: OVMF SDT Header probe |
>> + | ... | | suppressor |
>> + +----------------------------------+ | 36: padding for 8-byte |
>> + | alignment |
>> + | 40: GUID |
>> + | 56: padding to page size |
>> + +---------------------------+
>> + END OF PAGE
>> +
>> +
>> +Device Usage:
>> +-------------
>> +
>> +The device has one property, which may be only be set using the command
>> line:
>> +
>> +``guid``
>> + sets the value of the GUID. A special value ``auto`` instructs
>> + QEMU to generate a new random GUID.
>> +
>> +For example::
>> +
>> + QEMU -device vmgenid,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
>> + QEMU -device vmgenid,guid=auto
>> +
>> +The property may be queried via QMP/HMP::
>> +
>> + (QEMU) query-vm-generation-id
>> + {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
>> +
>> +Setting of this parameter is intentionally left out from the QMP/HMP
>> +interfaces. There are no known use cases for changing the GUID once QEMU is
>> +running, and adding this capability would greatly increase the complexity.
>> diff --git a/docs/specs/vmgenid.txt b/docs/specs/vmgenid.txt
>> deleted file mode 100644
>> index 80ff69f31cc..00000000000
>> --- a/docs/specs/vmgenid.txt
>> +++ /dev/null
>> @@ -1,245 +0,0 @@
>> -VIRTUAL MACHINE GENERATION ID
>> -=============================
>> -
>> -Copyright (C) 2016 Red Hat, Inc.
>> -Copyright (C) 2017 Skyport Systems, Inc.
>> -
>> -This work is licensed under the terms of the GNU GPL, version 2 or later.
>> -See the COPYING file in the top-level directory.
>> -
>> -===
>> -
>> -The VM generation ID (vmgenid) device is an emulated device which
>> -exposes a 128-bit, cryptographically random, integer value identifier,
>> -referred to as a Globally Unique Identifier, or GUID.
>> -
>> -This allows management applications (e.g. libvirt) to notify the guest
>> -operating system when the virtual machine is executed with a different
>> -configuration (e.g. snapshot execution or creation from a template). The
>> -guest operating system notices the change, and is then able to react as
>> -appropriate by marking its copies of distributed databases as dirty,
>> -re-initializing its random number generator etc.
>> -
>> -
>> -Requirements
>> -------------
>> -
>> -These requirements are extracted from the "How to implement virtual machine
>> -generation ID support in a virtualization platform" section of the
>> -specification, dated August 1, 2012.
>> -
>> -
>> -The document may be found on the web at:
>> - http://go.microsoft.com/fwlink/?LinkId=260709
>> -
>> -R1a. The generation ID shall live in an 8-byte aligned buffer.
>> -
>> -R1b. The buffer holding the generation ID shall be in guest RAM, ROM, or
>> device
>> - MMIO range.
>> -
>> -R1c. The buffer holding the generation ID shall be kept separate from areas
>> - used by the operating system.
>> -
>> -R1d. The buffer shall not be covered by an AddressRangeMemory or
>> - AddressRangeACPI entry in the E820 or UEFI memory map.
>> -
>> -R1e. The generation ID shall not live in a page frame that could be mapped
>> with
>> - caching disabled. (In other words, regardless of whether the
>> generation ID
>> - lives in RAM, ROM or MMIO, it shall only be mapped as cacheable.)
>> -
>> -R2 to R5. [These AML requirements are isolated well enough in the Microsoft
>> - specification for us to simply refer to them here.]
>> -
>> -R6. The hypervisor shall expose a _HID (hardware identifier) object in the
>> - VMGenId device's scope that is unique to the hypervisor vendor.
>> -
>> -
>> -QEMU Implementation
>> --------------------
>> -
>> -The above-mentioned specification does not dictate which ACPI descriptor
>> table
>> -will contain the VM Generation ID device. Other implementations (Hyper-V
>> and
>> -Xen) put it in the main descriptor table (Differentiated System Description
>> -Table or DSDT). For ease of debugging and implementation, we have decided
>> to
>> -put it in its own Secondary System Description Table, or SSDT.
>> -
>> -The following is a dump of the contents from a running system:
>> -
>> -# iasl -p ./SSDT -d /sys/firmware/acpi/tables/SSDT
>> -
>> -Intel ACPI Component Architecture
>> -ASL+ Optimizing Compiler version 20150717-64
>> -Copyright (c) 2000 - 2015 Intel Corporation
>> -
>> -Reading ACPI table from file /sys/firmware/acpi/tables/SSDT - Length
>> -00000198 (0x0000C6)
>> -ACPI: SSDT 0x0000000000000000 0000C6 (v01 BOCHS VMGENID 00000001 BXPC
>> -00000001)
>> -Acpi table [SSDT] successfully installed and loaded
>> -Pass 1 parse of [SSDT]
>> -Pass 2 parse of [SSDT]
>> -Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
>> -
>> -Parsing completed
>> -Disassembly completed
>> -ASL Output: ./SSDT.dsl - 1631 bytes
>> -# cat SSDT.dsl
>> -/*
>> - * Intel ACPI Component Architecture
>> - * AML/ASL+ Disassembler version 20150717-64
>> - * Copyright (c) 2000 - 2015 Intel Corporation
>> - *
>> - * Disassembling to symbolic ASL+ operators
>> - *
>> - * Disassembly of /sys/firmware/acpi/tables/SSDT, Sun Feb 5 00:19:37 2017
>> - *
>> - * Original Table Header:
>> - * Signature "SSDT"
>> - * Length 0x000000CA (202)
>> - * Revision 0x01
>> - * Checksum 0x4B
>> - * OEM ID "BOCHS "
>> - * OEM Table ID "VMGENID"
>> - * OEM Revision 0x00000001 (1)
>> - * Compiler ID "BXPC"
>> - * Compiler Version 0x00000001 (1)
>> - */
>> -DefinitionBlock ("/sys/firmware/acpi/tables/SSDT.aml", "SSDT", 1, "BOCHS ",
>> -"VMGENID", 0x00000001)
>> -{
>> - Name (VGIA, 0x07FFF000)
>> - Scope (\_SB)
>> - {
>> - Device (VGEN)
>> - {
>> - Name (_HID, "QEMUVGID") // _HID: Hardware ID
>> - Name (_CID, "VM_Gen_Counter") // _CID: Compatible ID
>> - Name (_DDN, "VM_Gen_Counter") // _DDN: DOS Device Name
>> - Method (_STA, 0, NotSerialized) // _STA: Status
>> - {
>> - Local0 = 0x0F
>> - If ((VGIA == Zero))
>> - {
>> - Local0 = Zero
>> - }
>> -
>> - Return (Local0)
>> - }
>> -
>> - Method (ADDR, 0, NotSerialized)
>> - {
>> - Local0 = Package (0x02) {}
>> - Index (Local0, Zero) = (VGIA + 0x28)
>> - Index (Local0, One) = Zero
>> - Return (Local0)
>> - }
>> - }
>> - }
>> -
>> - Method (\_GPE._E05, 0, NotSerialized) // _Exx: Edge-Triggered GPE
>> - {
>> - Notify (\_SB.VGEN, 0x80) // Status Change
>> - }
>> -}
>> -
>> -
>> -Design Details:
>> ----------------
>> -
>> -Requirements R1a through R1e dictate that the memory holding the
>> -VM Generation ID must be allocated and owned by the guest firmware,
>> -in this case BIOS or UEFI. However, to be useful, QEMU must be able to
>> -change the contents of the memory at runtime, specifically when starting a
>> -backed-up or snapshotted image. In order to do this, QEMU must know the
>> -address that has been allocated.
>> -
>> -The mechanism chosen for this memory sharing is writable fw_cfg blobs.
>> -These are data object that are visible to both QEMU and guests, and are
>> -addressable as sequential files.
>> -
>> -More information about fw_cfg can be found in "docs/specs/fw_cfg.txt"
>> -
>> -Two fw_cfg blobs are used in this case:
>> -
>> -/etc/vmgenid_guid - contains the actual VM Generation ID GUID
>> - - read-only to the guest
>> -/etc/vmgenid_addr - contains the address of the downloaded vmgenid blob
>> - - writable by the guest
>> -
>> -
>> -QEMU sends the following commands to the guest at startup:
>> -
>> -1. Allocate memory for vmgenid_guid fw_cfg blob.
>> -2. Write the address of vmgenid_guid into the SSDT (VGIA ACPI variable as
>> - shown above in the iasl dump). Note that this change is not propagated
>> - back to QEMU.
>> -3. Write the address of vmgenid_guid back to QEMU's copy of vmgenid_addr
>> - via the fw_cfg DMA interface.
>> -
>> -After step 3, QEMU is able to update the contents of vmgenid_guid at will.
>> -
>> -Since BIOS or UEFI does not necessarily run when we wish to change the GUID,
>> -the value of VGIA is persisted via the VMState mechanism.
>> -
>> -As spelled out in the specification, any change to the GUID executes an
>> -ACPI notification. The exact handler to use is not specified, so the
>> vmgenid
>> -device uses the first unused one: \_GPE._E05.
>> -
>> -
>> -Endian-ness Considerations:
>> ----------------------------
>> -
>> -Although not specified in Microsoft's document, it is assumed that the
>> -device is expected to use little-endian format.
>> -
>> -All GUID passed in via command line or monitor are treated as big-endian.
>> -GUID values displayed via monitor are shown in big-endian format.
>> -
>> -
>> -GUID Storage Format:
>> ---------------------
>> -
>> -In order to implement an OVMF "SDT Header Probe Suppressor", the contents of
>> -the vmgenid_guid fw_cfg blob are not simply a 128-bit GUID. There is also
>> -significant padding in order to align and fill a memory page, as shown in
>> the
>> -following diagram:
>> -
>> -+----------------------------------+
>> -| SSDT with OEM Table ID = VMGENID |
>> -+----------------------------------+
>> -| ... | TOP OF PAGE
>> -| VGIA dword object ---------------|-----> +---------------------------+
>> -| ... | | fw-allocated array for |
>> -| _STA method referring to VGIA | | "etc/vmgenid_guid" |
>> -| ... | +---------------------------+
>> -| ADDR method referring to VGIA | | 0: OVMF SDT Header probe |
>> -| ... | | suppressor |
>> -+----------------------------------+ | 36: padding for 8-byte |
>> - | alignment |
>> - | 40: GUID |
>> - | 56: padding to page size |
>> - +---------------------------+
>> - END OF PAGE
>> -
>> -
>> -Device Usage:
>> --------------
>> -
>> -The device has one property, which may be only be set using the command
>> line:
>> -
>> - guid - sets the value of the GUID. A special value "auto" instructs
>> - QEMU to generate a new random GUID.
>> -
>> -For example:
>> -
>> - QEMU -device vmgenid,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
>> - QEMU -device vmgenid,guid=auto
>> -
>> -The property may be queried via QMP/HMP:
>> -
>> - (QEMU) query-vm-generation-id
>> - {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
>> -
>> -Setting of this parameter is intentionally left out from the QMP/HMP
>> -interfaces. There are no known use cases for changing the GUID once QEMU is
>> -running, and adding this capability would greatly increase the complexity.
>