From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487139720187456.88325595236915; Tue, 14 Feb 2017 22:22:00 -0800 (PST) Received: from localhost ([::1]:38709 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsyU-0006P2-Rp for importer@patchew.org; Wed, 15 Feb 2017 01:21:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42520) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssu-00023D-7w for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssq-0007DD-Pa for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:12 -0500 Received: from mail-pg0-x22f.google.com ([2607:f8b0:400e:c05::22f]:36595) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssq-0007Ch-Hp for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:08 -0500 Received: by mail-pg0-x22f.google.com with SMTP id v184so34070435pgv.3 for ; Tue, 14 Feb 2017 22:16:07 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.05 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=D/MVAaQRLDQOSkvx1dblY7eZ8zk7D/XEZqd9/NZOcwU=; b=avP/r1mCwXIf8WLRNHzeb7AftMlOw0oJtRya2OqVvfnWXkpkcWvKS5H7901/yX/gtN UK83ZpEbqPwLJoj7rQF7U14SY/rh75FAOu86U1SmyBi9qbyoiPKNTTOflwdWcHc09ysE 6UZDiTb8VwMjV4u+fLGX0FSYhVLaKNHB6jGzk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=D/MVAaQRLDQOSkvx1dblY7eZ8zk7D/XEZqd9/NZOcwU=; b=LbXZjzM3FNQYjO51qH5N+09gDE46EmBCrYiYDDnyK27TPa6fSmryqzpkzLGTomRDw9 Uw8itwy9SXAjnGOk3pba2rN9iqe5dmZkWGLAhUW/KNvL58NN5OrSGnpaeFAOWq+ui/E6 n3QkYh7n0yo1W+83SCJ068NQioiEcBH8xTFRnHGYGXIg3iMG/s+bQUHUNaQoND8PAL6s /bdsLm7ja5T7ET/hvKke+IIMXY9LL50E/oTqwqmOroD0CN2cYNDSJGLb+tlvhcRvXy3t j6k9JyPB8eWF0uEQzizXXCX1klKTzWepePm7+ALQTgTFSUedLK1Uox6WR7QNRnO59FuQ rCKQ== X-Gm-Message-State: AMke39m/GSYRTfm9h396k17JrsOsK7Yuq429cKP6lPTA/UjOVdIexs6hv1N3TQft7m12n/WX X-Received: by 10.99.227.5 with SMTP id f5mr37129682pgh.102.1487139366109; Tue, 14 Feb 2017 22:16:06 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:43 -0800 Message-Id: <9dffe31a245cf6a717eef8227fe80ca666b168b5.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::22f Subject: [Qemu-devel] [PATCH v6 1/7] linker-loader: Add new 'write pointer' command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren This is similar to the existing 'add pointer' functionality, but instead of instructing the guest (BIOS or UEFI) to patch memory, it instructs the guest to write the pointer back to QEMU via a writeable fw_cfg file. Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Tested-by: Laszlo Ersek --- hw/acpi/bios-linker-loader.c | 58 ++++++++++++++++++++++++++++++++= ++-- include/hw/acpi/bios-linker-loader.h | 6 ++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c index d963ebe..5030cf1 100644 --- a/hw/acpi/bios-linker-loader.c +++ b/hw/acpi/bios-linker-loader.c @@ -78,6 +78,19 @@ struct BiosLinkerLoaderEntry { uint32_t length; } cksum; =20 + /* + * COMMAND_WRITE_POINTER - write the fw_cfg file (originating from + * @dest_file) at @wr_pointer.offset, by adding a pointer to the t= able + * originating from @src_file. 1,2,4 or 8 byte unsigned + * addition is used depending on @wr_pointer.size. + */ + struct { + char dest_file[BIOS_LINKER_LOADER_FILESZ]; + char src_file[BIOS_LINKER_LOADER_FILESZ]; + uint32_t offset; + uint8_t size; + } wr_pointer; + /* padding */ char pad[124]; }; @@ -85,9 +98,10 @@ struct BiosLinkerLoaderEntry { typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry; =20 enum { - BIOS_LINKER_LOADER_COMMAND_ALLOCATE =3D 0x1, - BIOS_LINKER_LOADER_COMMAND_ADD_POINTER =3D 0x2, - BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM =3D 0x3, + BIOS_LINKER_LOADER_COMMAND_ALLOCATE =3D 0x1, + BIOS_LINKER_LOADER_COMMAND_ADD_POINTER =3D 0x2, + BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM =3D 0x3, + BIOS_LINKER_LOADER_COMMAND_WRITE_POINTER =3D 0x4, }; =20 enum { @@ -278,3 +292,41 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker, =20 g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } + +/* + * bios_linker_loader_write_pointer: ask guest to write a pointer to the + * source file into the destination file, and write it back to QEMU via + * fw_cfg DMA. + * + * @linker: linker object instance + * @dest_file: destination file that must be written + * @dst_patched_offset: location within destination file blob to be patched + * with the pointer to @src_file, in bytes + * @dst_patched_offset_size: size of the pointer to be patched + * at @dst_patched_offset in @dest_file blob, in bytes + * @src_file: source file who's address must be taken + */ +void bios_linker_loader_write_pointer(BIOSLinker *linker, + const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, + const char *src_file) +{ + BiosLinkerLoaderEntry entry; + const BiosLinkerFileEntry *source_file =3D + bios_linker_find_file(linker, src_file); + + assert(source_file); + memset(&entry, 0, sizeof entry); + strncpy(entry.wr_pointer.dest_file, dest_file, + sizeof entry.wr_pointer.dest_file - 1); + strncpy(entry.wr_pointer.src_file, src_file, + sizeof entry.wr_pointer.src_file - 1); + entry.command =3D cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_WRITE_POINTER= ); + entry.wr_pointer.offset =3D cpu_to_le32(dst_patched_offset); + entry.wr_pointer.size =3D dst_patched_size; + assert(dst_patched_size =3D=3D 1 || dst_patched_size =3D=3D 2 || + dst_patched_size =3D=3D 4 || dst_patched_size =3D=3D 8); + + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); +} diff --git a/include/hw/acpi/bios-linker-loader.h b/include/hw/acpi/bios-li= nker-loader.h index fa1e5d1..f9ba5d6 100644 --- a/include/hw/acpi/bios-linker-loader.h +++ b/include/hw/acpi/bios-linker-loader.h @@ -26,5 +26,11 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker, const char *src_file, uint32_t src_offset); =20 +void bios_linker_loader_write_pointer(BIOSLinker *linker, + const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, + const char *src_file); + void bios_linker_loader_cleanup(BIOSLinker *linker); #endif --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 148713949779460.86153850889934; Tue, 14 Feb 2017 22:18:17 -0800 (PST) Received: from localhost ([::1]:38685 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsut-0003DY-UW for importer@patchew.org; Wed, 15 Feb 2017 01:18:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssu-00023E-8I for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssq-0007D2-DQ for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:12 -0500 Received: from mail-pg0-x231.google.com ([2607:f8b0:400e:c05::231]:34203) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssq-0007Cl-4x for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:08 -0500 Received: by mail-pg0-x231.google.com with SMTP id z67so2172705pgb.1 for ; Tue, 14 Feb 2017 22:16:08 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.06 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=oocJfy5goAgw9vxmT2FfYpp8miKm2WL9+sxe+eyvCLQ=; b=XBc+9/9PnqP9V/wuuIcqjUZGoi6eVuGIWS1MjHFrWvjJJOsgwLp0Mdzt3maCl00h/7 PnAMqskkqpAzwo1b3cmL0Kny2kVDVM28Z9jYR+6tTSE8E+mxl/yptgYizwDVJ7++o73O /hDtgn/m4lkQDKvMgZisaQCriMxKZaKl6NJ58= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=oocJfy5goAgw9vxmT2FfYpp8miKm2WL9+sxe+eyvCLQ=; b=iq2qr8WLUnZTr03wGEh33wvxLU41h3Jzy3IknwGwMcLytcpa4o73JDGPm/K74fdFqU iWo0cEFKRNUwPBOB+iDPee91NTRq5Sy4maEw1w7rSasL3/Eqi+7y9q+MCVE4OfVGAVWn 5Ap9EUHk3dyOuPjSKZ4wQterMVM/br3SnWWzlvXTDmnLAGCltMOynDB6S3YIL8C7s2Uj 0iiR4MIpwN/qUDyYPV/pDmtfMGglwl5mq0Vzk7gmjtS9tGx3PXPwa/z+zFPTB18DECZR ztIZ4sQ7KHHx3qDeFXcKhMKzqlJxkvhd+lkWph9g7RL5f60SxFjB9tgsj0K3nwJ5xk2r TgfA== X-Gm-Message-State: AMke39m2SRALj9QVQxMeD92Zx8tU9DwNSPaMTO0SRAZi2dc3NUsmxXr0c5Nlqpfka+6x4lLD X-Received: by 10.99.94.198 with SMTP id s189mr36900348pgb.211.1487139367104; Tue, 14 Feb 2017 22:16:07 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:44 -0800 Message-Id: <1cf6435fc49709114f935abf86d73d8b538f5c0f.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::231 Subject: [Qemu-devel] [PATCH v6 2/7] docs: VM Generation ID device description X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gal Hammer , imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren This patch is based off an earlier version by Gal Hammer (ghammer@redhat.com) Requirements section, ASCII diagrams and overall help provided by Laszlo Ersek (lersek@redhat.com) Signed-off-by: Gal Hammer Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Reviewed-by: Igor Mammedov Tested-by: Laszlo Ersek --- docs/specs/vmgenid.txt | 245 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 245 insertions(+) create mode 100644 docs/specs/vmgenid.txt diff --git a/docs/specs/vmgenid.txt b/docs/specs/vmgenid.txt new file mode 100644 index 0000000..aa9f518 --- /dev/null +++ b/docs/specs/vmgenid.txt @@ -0,0 +1,245 @@ +VIRTUAL MACHINE GENERATION ID +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D + +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. + +=3D=3D=3D + +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=3D260709 + +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 d= evice + 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 generati= on 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 t= able +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 =3D 0x0F + If ((VGIA =3D=3D Zero)) + { + Local0 =3D Zero + } + + Return (Local0) + } + + Method (ADDR, 0, NotSerialized) + { + Local0 =3D Package (0x02) {} + Index (Local0, Zero) =3D (VGIA + 0x28) + Index (Local0, One) =3D 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 writeable 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 + - writeable 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 GUI= D, +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 vmge= nid +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 =3D 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 li= ne: + + 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=3D"324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87" + QEMU -device vmgenid,guid=3Dauto + +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. --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487139488900347.30226102137294; Tue, 14 Feb 2017 22:18:08 -0800 (PST) Received: from localhost ([::1]:38684 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsuk-00037s-Iw for importer@patchew.org; Wed, 15 Feb 2017 01:18:06 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42526) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssu-00023G-A2 for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdsss-0007DT-Cs for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:12 -0500 Received: from mail-pf0-x235.google.com ([2607:f8b0:400e:c00::235]:33264) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdsss-0007DL-6r for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:10 -0500 Received: by mail-pf0-x235.google.com with SMTP id c73so25593662pfb.0 for ; Tue, 14 Feb 2017 22:16:10 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.07 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=xI9yNj/AdNLbuKActthWBf3JikGO539hMq+RqAg0YVU=; b=39fC1LqakeTK8SohXuJ2WQkmcaDjW4bkCwZdEVXFLDf3E+si3FRcclgY2MPhHFyyuh j9OHZgMjA3+hXOFYXvxPQDxZUZw6XRadasAGIoDZWznQc24FAtVyYfgbczNsWkmgXZJg sEX1v7P4tIA3aWvvobeCuzzJNGCCxFgL9kGTQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=xI9yNj/AdNLbuKActthWBf3JikGO539hMq+RqAg0YVU=; b=cGBAgncTQ4sAIEq1afo9gwv400RneP6HeBjY9bdWmg8M/HXLc1TyAPyj1nIR1iRGSv GJ5lZnSybiHOqyWed+pzj00+68ONrndmsulCCrXI3gVr4OelDJ0YivOnjsUOKU2oWYn7 X2ASKu3tfc4ppcT4GspVlt9KBtfdVZcyaPl9ZrHGyXxBqP+QBK96ZFWr/wZy1xV00POV TH5vvP+I2212UYqKqwai39GATGwjTSnv/UVj9X6hxDu/K0n35E7yMdKonPHfqIvEEcyj /411+okUQbv7MiuU559y/2r6Sqg6q/vgbj14lJ8WMPjoMvvokPSMHSvUg34Az80cfHsu nHNA== X-Gm-Message-State: AMke39loiE5FKsqvfaXSMIXpI2qA18OGNPgTSImfiYMBAqrbZAEMLGGpwNe31H198TYaORCE X-Received: by 10.99.2.4 with SMTP id 4mr18316832pgc.5.1487139369403; Tue, 14 Feb 2017 22:16:09 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:45 -0800 Message-Id: <60b6ece3ce0a24aec79c1061627fa2e6ab058fc2.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::235 Subject: [Qemu-devel] [PATCH v6 3/7] ACPI: Add vmgenid blob storage to the build tables X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren This allows them to be centrally initialized and destroyed The "AcpiBuildTables.vmgenid" array will be used to construct the "etc/vmgenid" fw_cfg blob. Its contents will be linked into fw_cfg after being built on the pc_machine_done() -> acpi_setup() -> acpi_build() call path, and dropped without use on the subsequent, guest triggered, acpi_build_update() -> acpi_build() call path. Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Reviewed-by: Igor Mammedov Tested-by: Laszlo Ersek --- hw/acpi/aml-build.c | 2 ++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 3 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index b2a1e40..c6f2032 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1559,6 +1559,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables) tables->rsdp =3D g_array_new(false, true /* clear */, 1); tables->table_data =3D g_array_new(false, true /* clear */, 1); tables->tcpalog =3D g_array_new(false, true /* clear */, 1); + tables->vmgenid =3D g_array_new(false, true /* clear */, 1); tables->linker =3D bios_linker_loader_init(); } =20 @@ -1568,6 +1569,7 @@ void acpi_build_tables_cleanup(AcpiBuildTables *table= s, bool mfre) g_array_free(tables->rsdp, true); g_array_free(tables->table_data, true); g_array_free(tables->tcpalog, mfre); + g_array_free(tables->vmgenid, mfre); } =20 /* Build rsdt table */ diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 559326c..00c21f1 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -210,6 +210,7 @@ struct AcpiBuildTables { GArray *table_data; GArray *rsdp; GArray *tcpalog; + GArray *vmgenid; BIOSLinker *linker; } AcpiBuildTables; =20 --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487139713579451.3417589742137; Tue, 14 Feb 2017 22:21:53 -0800 (PST) Received: from localhost ([::1]:38708 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsyO-0006Kk-96 for importer@patchew.org; Wed, 15 Feb 2017 01:21:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssw-00023R-4f for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdsst-0007Dj-Hh for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: from mail-pg0-x22d.google.com ([2607:f8b0:400e:c05::22d]:36606) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdsst-0007DY-8e for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:11 -0500 Received: by mail-pg0-x22d.google.com with SMTP id v184so34070944pgv.3 for ; Tue, 14 Feb 2017 22:16:11 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.09 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=DoWyUcbuPQMPh1wjALx+y7QQIZknucUbSEVeyiGQfqA=; b=wE798d+ALzg70+WSLlxCiAdmHWr7QUa+OzmQNJ1pljryZ+nhEMeRE+ZYJk85pqcTru 6ydh017lXlnzpnApwVSgx4xICpA5Sqd2uG4XK3fQ9IRlpVuPT3FVBLZjkrcwOtidXQJD qhbux4GqPrd5/mb96Ve++QZIRYic5GMzogoTk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=DoWyUcbuPQMPh1wjALx+y7QQIZknucUbSEVeyiGQfqA=; b=OrdtSmcQdERclub2HY4lGEAk5JUWXOPlathjSvfpyuSsjFX71tyo/QFPKd552NlJNF udPYWjYVKHWqWPO7gYkF1Yf/tef3m4DpuFfu6cpVqMjROZ1TW51o6uQ6hxijlmo040NP nCAMJmlfoKuoDmPgkSgBuRNdusR6m1H85O1XrOjILK3u3dTfAIESJhIVXyxc9Ll3ZZal oQuKooa7p4xq4WfkfaZwUqWKhOA795usqEovAGlqP1y0pWmGijX+ls15b3Fm34M79Hv/ knPEzSEAJIskFCh+XZP+a0gbp5KfVFaKrh9ArhACDW4yJT+mhzPtS4XFVdu2WafSXXWW rr1w== X-Gm-Message-State: AMke39nOnBD/1/W420U7QZ45DDwmYypxC00uwle0LWfeNlS95cc8SqIV97vTIecZl5t40N2T X-Received: by 10.84.208.227 with SMTP id c32mr41077388plj.71.1487139370267; Tue, 14 Feb 2017 22:16:10 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:46 -0800 Message-Id: <111628dff0803a21b75cc390858f0c288decee22.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::22d Subject: [Qemu-devel] [PATCH v6 4/7] ACPI: Add Virtual Machine Generation ID support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren This implements the VM Generation ID feature by passing a 128-bit GUID to the guest via a fw_cfg blob. Any time the GUID changes, an ACPI notify event is sent to the guest The user interface is a simple device with one parameter: - guid (string, must be "auto" or in UUID format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Tested-by: Laszlo Ersek --- default-configs/i386-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 1 + hw/acpi/Makefile.objs | 1 + hw/acpi/vmgenid.c | 237 +++++++++++++++++++++++++++++++= ++++ hw/i386/acpi-build.c | 16 +++ include/hw/acpi/acpi_dev_interface.h | 1 + include/hw/acpi/vmgenid.h | 35 ++++++ 7 files changed, 292 insertions(+) create mode 100644 hw/acpi/vmgenid.c create mode 100644 include/hw/acpi/vmgenid.h diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmm= u.mak index 48b07a4..029e952 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -59,3 +59,4 @@ CONFIG_I82801B11=3Dy CONFIG_SMBIOS=3Dy CONFIG_HYPERV_TESTDEV=3D$(CONFIG_KVM) CONFIG_PXB=3Dy +CONFIG_ACPI_VMGENID=3Dy diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-so= ftmmu.mak index fd96345..d1d7432 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -59,3 +59,4 @@ CONFIG_I82801B11=3Dy CONFIG_SMBIOS=3Dy CONFIG_HYPERV_TESTDEV=3D$(CONFIG_KVM) CONFIG_PXB=3Dy +CONFIG_ACPI_VMGENID=3Dy diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index 6acf798..11c35bc 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -5,6 +5,7 @@ common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) +=3D cpu_hotplug.o common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) +=3D memory_hotplug.o common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) +=3D cpu.o common-obj-$(CONFIG_ACPI_NVDIMM) +=3D nvdimm.o +common-obj-$(CONFIG_ACPI_VMGENID) +=3D vmgenid.o common-obj-$(call lnot,$(CONFIG_ACPI_X86)) +=3D acpi-stub.o =20 common-obj-y +=3D acpi_interface.o diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c new file mode 100644 index 0000000..b1b7b32 --- /dev/null +++ b/hw/acpi/vmgenid.c @@ -0,0 +1,237 @@ +/* + * Virtual Machine Generation ID Device + * + * Copyright (C) 2017 Skyport Systems. + * + * Author: Ben Warren + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qmp-commands.h" +#include "hw/acpi/acpi.h" +#include "hw/acpi/aml-build.h" +#include "hw/acpi/vmgenid.h" +#include "hw/nvram/fw_cfg.h" +#include "sysemu/sysemu.h" + +void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *gui= d, + BIOSLinker *linker) +{ + Aml *ssdt, *dev, *scope, *method, *addr, *if_ctx; + uint32_t vgia_offset; + QemuUUID guid_le; + + /* Fill in the GUID values. These need to be converted to little-endi= an + * first, since that's what the guest expects + */ + g_array_set_size(guid, VMGENID_FW_CFG_SIZE); + memcpy(&guid_le.data, &vms->guid.data, sizeof(vms->guid.data)); + qemu_uuid_bswap(&guid_le); + /* The GUID is written at a fixed offset into the fw_cfg file + * in order to implement the "OVMF SDT Header probe suppressor" + * see docs/specs/vmgenid.txt for more details + */ + g_array_insert_vals(guid, VMGENID_GUID_OFFSET, guid_le.data, + ARRAY_SIZE(guid_le.data)); + + /* Put this in a separate SSDT table */ + ssdt =3D init_aml_allocator(); + + /* Reserve space for header */ + acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader)); + + /* Storage for the GUID address */ + vgia_offset =3D table_data->len + + build_append_named_dword(ssdt->buf, "VGIA"); + scope =3D aml_scope("\\_SB"); + dev =3D aml_device("VGEN"); + aml_append(dev, aml_name_decl("_HID", aml_string("QEMUVGID"))); + aml_append(dev, aml_name_decl("_CID", aml_string("VM_Gen_Counter"))); + aml_append(dev, aml_name_decl("_DDN", aml_string("VM_Gen_Counter"))); + + /* Simple status method to check that address is linked and non-zero */ + method =3D aml_method("_STA", 0, AML_NOTSERIALIZED); + addr =3D aml_local(0); + aml_append(method, aml_store(aml_int(0xf), addr)); + if_ctx =3D aml_if(aml_equal(aml_name("VGIA"), aml_int(0))); + aml_append(if_ctx, aml_store(aml_int(0), addr)); + aml_append(method, if_ctx); + aml_append(method, aml_return(addr)); + aml_append(dev, method); + + /* the ADDR method returns two 32-bit words representing the lower and + * upper halves * of the physical address of the fw_cfg blob + * (holding the GUID) + */ + method =3D aml_method("ADDR", 0, AML_NOTSERIALIZED); + + addr =3D aml_local(0); + aml_append(method, aml_store(aml_package(2), addr)); + + aml_append(method, aml_store(aml_add(aml_name("VGIA"), + aml_int(VMGENID_GUID_OFFSET), NUL= L), + aml_index(addr, aml_int(0)))); + aml_append(method, aml_store(aml_int(0), aml_index(addr, aml_int(1)))); + aml_append(method, aml_return(addr)); + + aml_append(dev, method); + aml_append(scope, dev); + aml_append(ssdt, scope); + + /* attach an ACPI notify */ + method =3D aml_method("\\_GPE._E05", 0, AML_NOTSERIALIZED); + aml_append(method, aml_notify(aml_name("\\_SB.VGEN"), aml_int(0x80))); + aml_append(ssdt, method); + + g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len); + + /* Allocate guest memory for the Data fw_cfg blob */ + bios_linker_loader_alloc(linker, VMGENID_GUID_FW_CFG_FILE, guid, 4096, + false /* page boundary, high memory */); + + /* Patch address of GUID fw_cfg blob into the ADDR fw_cfg blob + * so QEMU can write the GUID there. The address is expected to be + * < 4GB, but write 64 bits anyway. + */ + bios_linker_loader_write_pointer(linker, + VMGENID_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), + VMGENID_GUID_FW_CFG_FILE); + + /* Patch address of GUID fw_cfg blob into the AML so OSPM can retrieve + * and read it. Note that while we provide storage for 64 bits, only + * the least-signficant 32 get patched into AML. + */ + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, vgia_offset, sizeof(uint32_t), + VMGENID_GUID_FW_CFG_FILE, 0); + + build_header(linker, table_data, + (void *)(table_data->data + table_data->len - ssdt->buf->len), + "SSDT", ssdt->buf->len, 1, NULL, "VMGENID"); + free_aml_allocator(); +} + +void vmgenid_add_fw_cfg(VmGenIdState *vms, FWCfgState *s, GArray *guid) +{ + /* Create a read-only fw_cfg file for GUID */ + fw_cfg_add_file(s, VMGENID_GUID_FW_CFG_FILE, guid->data, + VMGENID_FW_CFG_SIZE); + /* Create a read-write fw_cfg file for Address */ + fw_cfg_add_file_callback(s, VMGENID_ADDR_FW_CFG_FILE, NULL, NULL, + vms->vmgenid_addr_le, + ARRAY_SIZE(vms->vmgenid_addr_le), false); +} + +static void vmgenid_update_guest(VmGenIdState *vms) +{ + Object *obj =3D object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL= ); + uint32_t vmgenid_addr; + QemuUUID guid_le; + + if (obj) { + /* Write the GUID to guest memory */ + memcpy(&vmgenid_addr, vms->vmgenid_addr_le, sizeof(vmgenid_addr)); + vmgenid_addr =3D le32_to_cpu(vmgenid_addr); + /* A zero value in vmgenid_addr means that BIOS has not yet written + * the address + */ + if (vmgenid_addr) { + /* QemuUUID has the first three words as big-endian, and expect + * that any GUIDs passed in will always be BE. The guest, + * however, will expect the fields to be little-endian. + * Perform a byte swap immediately before writing. + */ + memcpy(&guid_le.data, &vms->guid.data, sizeof(vms->guid.data)); + qemu_uuid_bswap(&guid_le); + /* The GUID is written at a fixed offset into the fw_cfg file + * in order to implement the "OVMF SDT Header probe suppressor" + * see docs/specs/vmgenid.txt for more details + */ + cpu_physical_memory_write(vmgenid_addr + VMGENID_GUID_OFFSET, + guid_le.data, sizeof(guid_le.data)); + /* Send _GPE.E05 event */ + acpi_send_event(DEVICE(obj), ACPI_VMGENID_CHANGE_STATUS); + } + } +} + +static void vmgenid_set_guid(Object *obj, const char *value, Error **errp) +{ + VmGenIdState *vms =3D VMGENID(obj); + + if (!strcmp(value, "auto")) { + qemu_uuid_generate(&vms->guid); + } else if (qemu_uuid_parse(value, &vms->guid) < 0) { + error_setg(errp, "'%s. %s': Failed to parse GUID string: %s", + object_get_typename(OBJECT(vms)), VMGENID_GUID, value); + return; + } + + vmgenid_update_guest(vms); +} + +/* After restoring an image, we need to update the guest memory and notify + * it of a potential change to VM Generation ID + */ +static int vmgenid_post_load(void *opaque, int version_id) +{ + VmGenIdState *vms =3D opaque; + vmgenid_update_guest(vms); + return 0; +} + +static const VMStateDescription vmstate_vmgenid =3D { + .name =3D "vmgenid", + .version_id =3D 1, + .minimum_version_id =3D 1, + .post_load =3D vmgenid_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_UINT8_ARRAY(vmgenid_addr_le, VmGenIdState, sizeof(uint64_t= )), + VMSTATE_END_OF_LIST() + }, +}; + +static void vmgenid_initfn(Object *obj) +{ + object_property_add_str(obj, VMGENID_GUID, NULL, vmgenid_set_guid, NUL= L); +} + +static void vmgenid_handle_reset(void *opaque) +{ + VmGenIdState *vms =3D VMGENID(opaque); + /* Clear the guest-allocated GUID address when the VM resets */ + memset(vms->vmgenid_addr_le, 0, ARRAY_SIZE(vms->vmgenid_addr_le)); +} + +static void vmgenid_realize(DeviceState *dev, Error **errp) +{ + VmGenIdState *vms =3D VMGENID(dev); + qemu_register_reset(vmgenid_handle_reset, vms); +} + +static void vmgenid_device_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &vmstate_vmgenid; + dc->realize =3D vmgenid_realize; +} + +static const TypeInfo vmgenid_device_info =3D { + .name =3D VMGENID_DEVICE, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(VmGenIdState), + .instance_init =3D vmgenid_initfn, + .class_init =3D vmgenid_device_class_init, +}; + +static void vmgenid_register_types(void) +{ + type_register_static(&vmgenid_device_info); +} + +type_init(vmgenid_register_types) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 1c928ab..db04cf5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -42,6 +42,7 @@ #include "hw/acpi/memory_hotplug.h" #include "sysemu/tpm.h" #include "hw/acpi/tpm.h" +#include "hw/acpi/vmgenid.h" #include "sysemu/tpm_backend.h" #include "hw/timer/mc146818rtc_regs.h" #include "sysemu/numa.h" @@ -2610,6 +2611,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState= *machine) size_t aml_len =3D 0; GArray *tables_blob =3D tables->table_data; AcpiSlicOem slic_oem =3D { .id =3D NULL, .table_id =3D NULL }; + Object *vmgenid_dev; =20 acpi_get_pm_info(&pm); acpi_get_misc_info(&misc); @@ -2653,6 +2655,13 @@ void acpi_build(AcpiBuildTables *tables, MachineStat= e *machine) acpi_add_table(table_offsets, tables_blob); build_madt(tables_blob, tables->linker, pcms); =20 + vmgenid_dev =3D find_vmgenid_dev(); + if (vmgenid_dev) { + acpi_add_table(table_offsets, tables_blob); + vmgenid_build_acpi(VMGENID(vmgenid_dev), tables_blob, + tables->vmgenid, tables->linker); + } + if (misc.has_hpet) { acpi_add_table(table_offsets, tables_blob); build_hpet(tables_blob, tables->linker); @@ -2823,6 +2832,7 @@ void acpi_setup(void) PCMachineClass *pcmc =3D PC_MACHINE_GET_CLASS(pcms); AcpiBuildTables tables; AcpiBuildState *build_state; + Object *vmgenid_dev; =20 if (!pcms->fw_cfg) { ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); @@ -2859,6 +2869,12 @@ void acpi_setup(void) fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); =20 + vmgenid_dev =3D find_vmgenid_dev(); + if (vmgenid_dev) { + vmgenid_add_fw_cfg(VMGENID(vmgenid_dev), pcms->fw_cfg, + tables.vmgenid); + } + if (!pcmc->rsdp_in_ram) { /* * Keep for compatibility with old machine types. diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_de= v_interface.h index 71d3c48..3c2e4e9 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -11,6 +11,7 @@ typedef enum { ACPI_CPU_HOTPLUG_STATUS =3D 4, ACPI_MEMORY_HOTPLUG_STATUS =3D 8, ACPI_NVDIMM_HOTPLUG_STATUS =3D 16, + ACPI_VMGENID_CHANGE_STATUS =3D 32, } AcpiEventStatusBits; =20 #define TYPE_ACPI_DEVICE_IF "acpi-device-interface" diff --git a/include/hw/acpi/vmgenid.h b/include/hw/acpi/vmgenid.h new file mode 100644 index 0000000..db7fa0e --- /dev/null +++ b/include/hw/acpi/vmgenid.h @@ -0,0 +1,35 @@ +#ifndef ACPI_VMGENID_H +#define ACPI_VMGENID_H + +#include "hw/acpi/bios-linker-loader.h" +#include "hw/qdev.h" +#include "qemu/uuid.h" + +#define VMGENID_DEVICE "vmgenid" +#define VMGENID_GUID "guid" +#define VMGENID_GUID_FW_CFG_FILE "etc/vmgenid_guid" +#define VMGENID_ADDR_FW_CFG_FILE "etc/vmgenid_addr" + +#define VMGENID_FW_CFG_SIZE 4096 /* Occupy a page of memory */ +#define VMGENID_GUID_OFFSET 40 /* allow space for + * OVMF SDT Header Probe Supressor + */ + +#define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj), VMGENID_DEVICE) + +typedef struct VmGenIdState { + DeviceClass parent_obj; + QemuUUID guid; /* The 128-bit GUID seen by the guest */ + uint8_t vmgenid_addr_le[8]; /* Address of the GUID (little-endian) */ +} VmGenIdState; + +static inline Object *find_vmgenid_dev(void) +{ + return object_resolve_path_type("", VMGENID_DEVICE, NULL); +} + +void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *gui= d, + BIOSLinker *linker); +void vmgenid_add_fw_cfg(VmGenIdState *vms, FWCfgState *s, GArray *guid); + +#endif --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 14871394986298.061883713013344; Tue, 14 Feb 2017 22:18:18 -0800 (PST) Received: from localhost ([::1]:38686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsuu-0003FV-Uu for importer@patchew.org; Wed, 15 Feb 2017 01:18:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42554) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssv-00023M-T3 for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssu-0007Dv-8w for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:13 -0500 Received: from mail-pf0-x230.google.com ([2607:f8b0:400e:c00::230]:35337) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssu-0007Dn-3C for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:12 -0500 Received: by mail-pf0-x230.google.com with SMTP id 202so25897290pfx.2 for ; Tue, 14 Feb 2017 22:16:12 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.10 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=8p+S3V3fG7ItXDKfhTB6k5Q2XUCS//oTlpInGM3SMUI=; b=QIKmPL4Gvk0P+U2g1jFZS4DSKL2eagmXOFx+XsffnY1vw3sLlk26BgxUVfxheTI6iz 6lYzhb0Qd9L7Db8+NiFEIZLYw0vm2LtSfSEPp2EGOWvacekslHSqUfWo2jnVzecaMWsK 9vcTlArjpLJAq7UYInwvSRMV6e00sJoNa0s1E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=8p+S3V3fG7ItXDKfhTB6k5Q2XUCS//oTlpInGM3SMUI=; b=h+/RJM74ybC8SV7ofMzkt0kYs9iutjv45LFWlCkEJnmKPFXdskFgvtXx9IzIYM23Xq FhxRaZMqCud0PQ1lOKYKYWI4dMDU4VFeKG2W2PpWiZWAaGQyyUU23oNv7eSNP808Y/PA 4IHmZFiP4pbGo3cjIDzhbiYeITia+D/7Z9trEnXZWpkb02cjdBu2RX6FVx6ZgoMPrDlI FXeWUOHQaqXGuIJP5FwUgM3PQAdnqK3ZrzNB4nDX2R4AV2FsfK23H/DvZBUGcvw7IJ/8 pkc2C+DjS4kQkHlQ2vsoCkBIsGemUMT0w6qVvptBeEfpnYxbL7Sn+Sf9qrtUL+F/7cg0 woQg== X-Gm-Message-State: AMke39nShlEz2ZJmxYadkKWDAtmIDyN6GOeKmHCrOQ9+zGhJijapmaTEnYUEV5IZVuA3xpkB X-Received: by 10.84.232.202 with SMTP id x10mr14839995plm.119.1487139371223; Tue, 14 Feb 2017 22:16:11 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:47 -0800 Message-Id: X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::230 Subject: [Qemu-devel] [PATCH v6 5/7] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Igor Mammedov Add commands to query Virtual Machine Generation ID counter. QMP command example: { "execute": "query-vm-generation-id" } HMP command example: info vm-generation-id Signed-off-by: Igor Mammedov Reviewed-by: Eric Blake Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Tested-by: Laszlo Ersek --- hmp-commands-info.hx | 13 +++++++++++++ hmp.c | 9 +++++++++ hmp.h | 1 + hw/acpi/vmgenid.c | 16 ++++++++++++++++ qapi-schema.json | 20 ++++++++++++++++++++ stubs/Makefile.objs | 1 + stubs/vmgenid.c | 8 ++++++++ 7 files changed, 68 insertions(+) create mode 100644 stubs/vmgenid.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index b0f35e6..f3df793 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -802,6 +802,19 @@ Show information about hotpluggable CPUs ETEXI =20 STEXI +@item info vm-generation-id +Show Virtual Machine Generation ID +ETEXI + + { + .name =3D "vm-generation-id", + .args_type =3D "", + .params =3D "", + .help =3D "Show Virtual Machine Generation ID", + .cmd =3D hmp_info_vm_generation_id, + }, + +STEXI @end table ETEXI =20 diff --git a/hmp.c b/hmp.c index 2bc4f06..535613d 100644 --- a/hmp.c +++ b/hmp.c @@ -2565,3 +2565,12 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict= *qdict) =20 qapi_free_HotpluggableCPUList(saved); } + +void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict) +{ + GuidInfo *info =3D qmp_query_vm_generation_id(NULL); + if (info) { + monitor_printf(mon, "%s\n", info->guid); + } + qapi_free_GuidInfo(info); +} diff --git a/hmp.h b/hmp.h index 05daf7c..799fd37 100644 --- a/hmp.h +++ b/hmp.h @@ -137,5 +137,6 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict = *qdict); void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict); void hmp_info_dump(Monitor *mon, const QDict *qdict); void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict); +void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); =20 #endif diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index b1b7b32..c159c76 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -235,3 +235,19 @@ static void vmgenid_register_types(void) } =20 type_init(vmgenid_register_types) + +GuidInfo *qmp_query_vm_generation_id(Error **errp) +{ + GuidInfo *info; + VmGenIdState *vms; + Object *obj =3D find_vmgenid_dev(); + + if (!obj) { + return NULL; + } + vms =3D VMGENID(obj); + + info =3D g_malloc0(sizeof(*info)); + info->guid =3D qemu_uuid_unparse_strdup(&vms->guid); + return info; +} diff --git a/qapi-schema.json b/qapi-schema.json index 61151f3..5e2a47f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -6051,3 +6051,23 @@ # ## { 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'] } + +## +# @GuidInfo: +# +# GUID information. +# +# @guid: the globally unique identifier +# +# Since: 2.9 +## +{ 'struct': 'GuidInfo', 'data': {'guid': 'str'} } + +## +# @query-vm-generation-id: +# +# Show Virtual Machine Generation ID +# +# Since 2.9 +## +{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' } diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index a187295..0bffca6 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -35,3 +35,4 @@ stub-obj-y +=3D qmp_pc_dimm_device_list.o stub-obj-y +=3D target-monitor-defs.o stub-obj-y +=3D target-get-monitor-def.o stub-obj-y +=3D pc_madt_cpu_entry.o +stub-obj-y +=3D vmgenid.o diff --git a/stubs/vmgenid.c b/stubs/vmgenid.c new file mode 100644 index 0000000..8c448ac --- /dev/null +++ b/stubs/vmgenid.c @@ -0,0 +1,8 @@ +#include "qemu/osdep.h" +#include "qmp-commands.h" + +GuidInfo *qmp_query_vm_generation_id(Error **errp) +{ + error_setg(errp, "this command is not currently supported"); + return NULL; +} --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487140066680285.3089299390133; Tue, 14 Feb 2017 22:27:46 -0800 (PST) Received: from localhost ([::1]:38737 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdt45-0004Xm-B4 for importer@patchew.org; Wed, 15 Feb 2017 01:27:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssw-00023Z-Ml for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssv-0007Ea-3q for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: from mail-pf0-x22f.google.com ([2607:f8b0:400e:c00::22f]:34414) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssu-0007EB-Sr for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:13 -0500 Received: by mail-pf0-x22f.google.com with SMTP id e4so28940755pfg.1 for ; Tue, 14 Feb 2017 22:16:12 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.11 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ugP5NXfnQv77+SNcFjKodK/DY4T2KPyCbclNk+ptxlo=; b=5PZqqvuzAeWhzazYo4tRyAR5RdCXBq1x6eEKBvqiLZMp4VteZl+RwDd0occLSCR+Cf LsbSlWXvNKTiKifEhWtYxiha4lp6BcqJlfDwx4Zd62XgxuGLXfDDsWQL1XUVcRGCnf4H BirKHQPRXKB1okR4jChg9U0pqTwekeM+wJAZ8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ugP5NXfnQv77+SNcFjKodK/DY4T2KPyCbclNk+ptxlo=; b=XA/DKCdCg+wqqh8LyaUQOFadD/bVbCW7R7L3JsPR5lg9i67E+H9YfCWhNRsTLFTnX2 kZ6XSmtAVtrabANtcuNhkiwS/L00xVMkzlf8DrNNBPB8r8BrnCJ3IUzspAQGaZK402Zc t0E+BMrIul4XNRs71v6h3qqYZA2RFrk7HXsBav+HZwMCNo7YtFeIVWZR6KGJk6W3rT3C ulFZNQbiSWdSIQQiaEoRSTCIydDh5x+aZoiPJROhXQU58nRoPNsIG/b+3H4pz8B1c/wa eTcjKgo1TWgxL8VlQS7g95/O578B6nJYf7PetSjmhS7i539eAKuIfH5y7TmtjLFzwYjp JAIQ== X-Gm-Message-State: AMke39kr9OGc+RM4NyDU1Cb1UrDBaSK8BqQaHqnwwFdrFfAL5mdFeSnt1poXNjITacqKYfuS X-Received: by 10.84.136.34 with SMTP id 31mr41069752plk.52.1487139372027; Tue, 14 Feb 2017 22:16:12 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:48 -0800 Message-Id: <96c621a0c1588234e473bf0c0d068af8812f3225.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c00::22f Subject: [Qemu-devel] [PATCH v6 6/7] tests: Move reusable ACPI macros into a new header file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren Also usable by upcoming VM Generation ID tests Signed-off-by: Ben Warren Tested-by: Laszlo Ersek --- tests/acpi-utils.h | 75 ++++++++++++++++++++++++++++++++++++++++++++= ++++ tests/bios-tables-test.c | 72 +-------------------------------------------= -- 2 files changed, 76 insertions(+), 71 deletions(-) create mode 100644 tests/acpi-utils.h diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h new file mode 100644 index 0000000..d5e5eff --- /dev/null +++ b/tests/acpi-utils.h @@ -0,0 +1,75 @@ +#ifndef TEST_ACPI_UTILS_H +#define TEST_ACPI_UTILS_H + +/* DSDT and SSDTs format */ +typedef struct { + AcpiTableHeader header; + gchar *aml; /* aml bytecode from guest */ + gsize aml_len; + gchar *aml_file; + gchar *asl; /* asl code generated from aml */ + gsize asl_len; + gchar *asl_file; + bool tmp_files_retain; /* do not delete the temp asl/aml */ +} QEMU_PACKED AcpiSdtTable; + +#define ACPI_READ_FIELD(field, addr) \ + do { \ + switch (sizeof(field)) { \ + case 1: \ + field =3D readb(addr); \ + break; \ + case 2: \ + field =3D readw(addr); \ + break; \ + case 4: \ + field =3D readl(addr); \ + break; \ + case 8: \ + field =3D readq(addr); \ + break; \ + default: \ + g_assert(false); \ + } \ + addr +=3D sizeof(field); \ + } while (0); + +#define ACPI_READ_ARRAY_PTR(arr, length, addr) \ + do { \ + int idx; \ + for (idx =3D 0; idx < length; ++idx) { \ + ACPI_READ_FIELD(arr[idx], addr); \ + } \ + } while (0); + +#define ACPI_READ_ARRAY(arr, addr) \ + ACPI_READ_ARRAY_PTR(arr, sizeof(arr) / sizeof(arr[0]), addr) + +#define ACPI_READ_TABLE_HEADER(table, addr) \ + do { \ + ACPI_READ_FIELD((table)->signature, addr); \ + ACPI_READ_FIELD((table)->length, addr); \ + ACPI_READ_FIELD((table)->revision, addr); \ + ACPI_READ_FIELD((table)->checksum, addr); \ + ACPI_READ_ARRAY((table)->oem_id, addr); \ + ACPI_READ_ARRAY((table)->oem_table_id, addr); \ + ACPI_READ_FIELD((table)->oem_revision, addr); \ + ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \ + ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \ + } while (0); + +#define ACPI_ASSERT_CMP(actual, expected) do { \ + uint32_t ACPI_ASSERT_CMP_le =3D cpu_to_le32(actual); \ + char ACPI_ASSERT_CMP_str[5] =3D {}; \ + memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 4); \ + g_assert_cmpstr(ACPI_ASSERT_CMP_str, =3D=3D, expected); \ +} while (0) + +#define ACPI_ASSERT_CMP64(actual, expected) do { \ + uint64_t ACPI_ASSERT_CMP_le =3D cpu_to_le64(actual); \ + char ACPI_ASSERT_CMP_str[9] =3D {}; \ + memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 8); \ + g_assert_cmpstr(ACPI_ASSERT_CMP_str, =3D=3D, expected); \ +} while (0) + +#endif /* TEST_ACPI_UTILS_H */ diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 5404805..c642f7f 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -17,6 +17,7 @@ #include "hw/acpi/acpi-defs.h" #include "hw/smbios/smbios.h" #include "qemu/bitmap.h" +#include "acpi-utils.h" #include "boot-sector.h" =20 #define MACHINE_PC "pc" @@ -24,18 +25,6 @@ =20 #define ACPI_REBUILD_EXPECTED_AML "TEST_ACPI_REBUILD_AML" =20 -/* DSDT and SSDTs format */ -typedef struct { - AcpiTableHeader header; - gchar *aml; /* aml bytecode from guest */ - gsize aml_len; - gchar *aml_file; - gchar *asl; /* asl code generated from aml */ - gsize asl_len; - gchar *asl_file; - bool tmp_files_retain; /* do not delete the temp asl/aml */ -} QEMU_PACKED AcpiSdtTable; - typedef struct { const char *machine; const char *variant; @@ -53,65 +42,6 @@ typedef struct { int required_struct_types_len; } test_data; =20 -#define ACPI_READ_FIELD(field, addr) \ - do { \ - switch (sizeof(field)) { \ - case 1: \ - field =3D readb(addr); \ - break; \ - case 2: \ - field =3D readw(addr); \ - break; \ - case 4: \ - field =3D readl(addr); \ - break; \ - case 8: \ - field =3D readq(addr); \ - break; \ - default: \ - g_assert(false); \ - } \ - addr +=3D sizeof(field); \ - } while (0); - -#define ACPI_READ_ARRAY_PTR(arr, length, addr) \ - do { \ - int idx; \ - for (idx =3D 0; idx < length; ++idx) { \ - ACPI_READ_FIELD(arr[idx], addr); \ - } \ - } while (0); - -#define ACPI_READ_ARRAY(arr, addr) \ - ACPI_READ_ARRAY_PTR(arr, sizeof(arr)/sizeof(arr[0]), addr) - -#define ACPI_READ_TABLE_HEADER(table, addr) \ - do { \ - ACPI_READ_FIELD((table)->signature, addr); \ - ACPI_READ_FIELD((table)->length, addr); \ - ACPI_READ_FIELD((table)->revision, addr); \ - ACPI_READ_FIELD((table)->checksum, addr); \ - ACPI_READ_ARRAY((table)->oem_id, addr); \ - ACPI_READ_ARRAY((table)->oem_table_id, addr); \ - ACPI_READ_FIELD((table)->oem_revision, addr); \ - ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \ - ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \ - } while (0); - -#define ACPI_ASSERT_CMP(actual, expected) do { \ - uint32_t ACPI_ASSERT_CMP_le =3D cpu_to_le32(actual); \ - char ACPI_ASSERT_CMP_str[5] =3D {}; \ - memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 4); \ - g_assert_cmpstr(ACPI_ASSERT_CMP_str, =3D=3D, expected); \ -} while (0) - -#define ACPI_ASSERT_CMP64(actual, expected) do { \ - uint64_t ACPI_ASSERT_CMP_le =3D cpu_to_le64(actual); \ - char ACPI_ASSERT_CMP_str[9] =3D {}; \ - memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 8); \ - g_assert_cmpstr(ACPI_ASSERT_CMP_str, =3D=3D, expected); \ -} while (0) - static char disk[] =3D "tests/acpi-test-disk-XXXXXX"; static const char *data_dir =3D "tests/acpi-test-data"; #ifdef CONFIG_IASL --=20 2.7.4 From nobody Mon Apr 29 14:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487139505308490.39624516255583; Tue, 14 Feb 2017 22:18:25 -0800 (PST) Received: from localhost ([::1]:38687 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsv1-0003K8-Jv for importer@patchew.org; Wed, 15 Feb 2017 01:18:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42585) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssx-00024U-Ti for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssw-0007FO-Co for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:15 -0500 Received: from mail-pg0-x231.google.com ([2607:f8b0:400e:c05::231]:36616) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssw-0007En-5M for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: by mail-pg0-x231.google.com with SMTP id v184so34071392pgv.3 for ; Tue, 14 Feb 2017 22:16:14 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.12 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=t1tEKdAD/Ngns9PmmceEMrLDA+2Z8oO7GJItkohCkNo=; b=Lu0nCqoIZ4QCCeb23DOYgSyK9riPSxYsBs8+o+UrmRchL2zWUsFCJDSLCrNP9i8jb1 6RlPEeK/iXAmZuyY3hSJIvy572FSND6W6YR9gNslbfagbQ9O4XTVxq2y1eBFPqi6wVTl vrNgfkVBxzRcBxE3UKyCumKb4vNZfHQnlTwR8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=t1tEKdAD/Ngns9PmmceEMrLDA+2Z8oO7GJItkohCkNo=; b=cUsA7Gb+9l1MynOpjTrZ9pDSfP1XUX7cycjkswKI1MmRYRCzHQx0gmi1r4BLuX0e7+ M5Jgme4zSJLH4smAVZEcnNYqYeZxi5gjrEp5hMtE5vZIIBpa+3dotM9+K+K4Rxier3l0 YhjKZtHzJGT2EgduUtRwCmRiou0fQMhsxfeqGDlkJjJkBO+KKjEo5fmmrV2heI5QWrCj LmMFsh6xYxCSPcf4RoUHCRKG9fG790naGdjKiSFObgZkzumuQlZpb82C0u747rL0f6Do tFFzVhMUwsyDpGIUI4yHP7ziVYDiDAv3BaYge7vQa6MbBbMSa5uAahSs/re0UXwmeDLt TV2g== X-Gm-Message-State: AMke39kWs0u6hMG2r8uhHgsTivuClLmATTINLq7Pq+5oWhgTuWl+l9zgCMbb5eVvAIpDbnu0 X-Received: by 10.84.169.36 with SMTP id g33mr41294847plb.36.1487139373341; Tue, 14 Feb 2017 22:16:13 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:49 -0800 Message-Id: X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::231 Subject: [Qemu-devel] [PATCH v6 7/7] tests: Add unit tests for the VM Generation ID feature X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Ben Warren The following tests are implemented: * test that a GUID passed in by command line is propagated to the guest. * test that changing the GUID at runtime via the monitor is reflected in the guest. * test that the "auto" argument to the GUID generates a different, and correct GUID as seen by the guest. This patch is loosely based on a previous patch from: Gal Hammer and Igor Mammedov Signed-off-by: Ben Warren Tested-by: Laszlo Ersek --- tests/Makefile.include | 2 + tests/vmgenid-test.c | 195 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 197 insertions(+) create mode 100644 tests/vmgenid-test.c diff --git a/tests/Makefile.include b/tests/Makefile.include index 634394a..ca4b3f7 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -241,6 +241,7 @@ check-qtest-i386-y +=3D tests/usb-hcd-xhci-test$(EXESUF) gcov-files-i386-y +=3D hw/usb/hcd-xhci.c check-qtest-i386-y +=3D tests/pc-cpu-test$(EXESUF) check-qtest-i386-y +=3D tests/q35-test$(EXESUF) +check-qtest-i386-y +=3D tests/vmgenid-test$(EXESUF) gcov-files-i386-y +=3D hw/pci-host/q35.c check-qtest-i386-$(CONFIG_VHOST_NET_TEST_i386) +=3D tests/vhost-user-test$= (EXESUF) ifeq ($(CONFIG_VHOST_NET_TEST_i386),) @@ -726,6 +727,7 @@ tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contr= ib/ivshmem-server/ivshmem tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o contrib/libvho= st-user/libvhost-user.o $(test-util-obj-y) tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y) tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o +tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o =20 tests/migration/stress$(EXESUF): tests/migration/stress.o $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"L= INK","$(TARGET_DIR)$@") diff --git a/tests/vmgenid-test.c b/tests/vmgenid-test.c new file mode 100644 index 0000000..721ba05 --- /dev/null +++ b/tests/vmgenid-test.c @@ -0,0 +1,195 @@ +/* + * QTest testcase for VM Generation ID + * + * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2017 Skyport Systems + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include "qemu/osdep.h" +#include "qemu/bitmap.h" +#include "qemu/uuid.h" +#include "hw/acpi/acpi-defs.h" +#include "acpi-utils.h" +#include "libqtest.h" + +#define VGID_GUID "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87" +#define VMGENID_GUID_OFFSET 40 /* allow space for + * OVMF SDT Header Probe Supressor + */ + +static uint32_t vgia; + +typedef struct { + AcpiTableHeader header; + gchar name_op; + gchar vgia[4]; + gchar val_op; + uint32_t vgia_val; +} QEMU_PACKED VgidTable; + +static uint32_t find_vgia(void) +{ + uint32_t off; + AcpiRsdpDescriptor rsdp_table; + uint32_t rsdt; + AcpiRsdtDescriptorRev1 rsdt_table; + int tables_nr; + uint32_t *tables; + AcpiTableHeader ssdt_table; + VgidTable vgid_table; + int i; + + /* First, find the RSDP */ + for (off =3D 0xf0000; off < 0x100000; off +=3D 0x10) { + uint8_t sig[] =3D "RSD PTR "; + + for (i =3D 0; i < sizeof sig - 1; ++i) { + sig[i] =3D readb(off + i); + } + + if (!memcmp(sig, "RSD PTR ", sizeof sig)) { + break; + } + } + g_assert_cmphex(off, <, 0x100000); + + /* Parse the RSDP header so we can find the RSDT */ + ACPI_READ_FIELD(rsdp_table.signature, off); + ACPI_ASSERT_CMP64(rsdp_table.signature, "RSD PTR "); + + ACPI_READ_FIELD(rsdp_table.checksum, off); + ACPI_READ_ARRAY(rsdp_table.oem_id, off); + ACPI_READ_FIELD(rsdp_table.revision, off); + ACPI_READ_FIELD(rsdp_table.rsdt_physical_address, off); + + rsdt =3D rsdp_table.rsdt_physical_address; + /* read the header */ + ACPI_READ_TABLE_HEADER(&rsdt_table, rsdt); + ACPI_ASSERT_CMP(rsdt_table.signature, "RSDT"); + + /* compute the table entries in rsdt */ + tables_nr =3D (rsdt_table.length - sizeof(AcpiRsdtDescriptorRev1)) / + sizeof(uint32_t); + g_assert_cmpint(tables_nr, >, 0); + + /* get the addresses of the tables pointed by rsdt */ + tables =3D g_new0(uint32_t, tables_nr); + ACPI_READ_ARRAY_PTR(tables, tables_nr, rsdt); + + for (i =3D 0; i < tables_nr; i++) { + ACPI_READ_TABLE_HEADER(&ssdt_table, tables[i]); + if (!strncmp((char *)ssdt_table.oem_table_id, "VMGENID", 7)) { + /* the first entry in the table should be VGIA + * That's all we need + */ + ACPI_READ_FIELD(vgid_table.name_op, tables[i]); + g_assert(vgid_table.name_op =3D=3D 0x08); /* name */ + ACPI_READ_ARRAY(vgid_table.vgia, tables[i]); + g_assert(memcmp(vgid_table.vgia, "VGIA", 4) =3D=3D 0); + ACPI_READ_FIELD(vgid_table.val_op, tables[i]); + g_assert(vgid_table.val_op =3D=3D 0x0C); /* dword */ + ACPI_READ_FIELD(vgid_table.vgia_val, tables[i]); + /* The GUID is written at a fixed offset into the fw_cfg file + * in order to implement the "OVMF SDT Header probe suppressor" + * see docs/specs/vmgenid.txt for more details + */ + return vgid_table.vgia_val + VMGENID_GUID_OFFSET; + } + } + return 0; +} + +static void vmgenid_read_guid(QemuUUID *guid) +{ + int i; + + if (vgia =3D=3D 0) { + vgia =3D find_vgia(); + } + g_assert(vgia); + + /* Read the GUID directly from guest memory */ + for (i =3D 0; i < 16; i++) { + guid->data[i] =3D readb(vgia + i); + } + /* The GUID is in little-endian format in the guest, while QEMU + * uses big-endian. Swap after reading. + */ + qemu_uuid_bswap(guid); +} + +static void vmgenid_test(void) +{ + QemuUUID expected, measured; + g_assert(qemu_uuid_parse(VGID_GUID, &expected) =3D=3D 0); + vmgenid_read_guid(&measured); + g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) = =3D=3D 0); +} + +static void vmgenid_set_guid_test(void) +{ + QDict *response; + gchar *cmd; + QemuUUID expected, measured; + g_assert(qemu_uuid_parse(VGID_GUID, &expected) =3D=3D 0); + /* Change the GUID slightly */ + expected.data[0] +=3D 1; + + cmd =3D g_strdup_printf("{ 'execute': 'qom-set', 'arguments': { " + "'path': '/machine/peripheral/testvgid', " + "'property': 'guid', 'value': '%s' } }", + qemu_uuid_unparse_strdup(&expected)); + response =3D qmp(cmd); + g_assert(qdict_haskey(response, "return")); + QDECREF(response); + + vmgenid_read_guid(&measured); + g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) = =3D=3D 0); +} + +static void vmgenid_set_guid_auto_test(void) +{ + QDict *response; + QemuUUID expected, measured; + + /* Read the initial value */ + vmgenid_read_guid(&expected); + + /* Setting to 'auto' generates a random GUID */ + response =3D qmp("{ 'execute': 'qom-set', 'arguments': { " + "'path': '/machine/peripheral/testvgid', " + "'property': 'guid', 'value': 'auto' } }"); + + g_assert(qdict_haskey(response, "return")); + QDECREF(response); + + vmgenid_read_guid(&measured); + g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) != =3D 0); +} + +int main(int argc, char **argv) +{ + int ret; + gchar *cmd; + + g_test_init(&argc, &argv, NULL); + + cmd =3D g_strdup_printf("-machine accel=3Dtcg -device vmgenid,id=3Dtes= tvgid," + "guid=3D%s", VGID_GUID); + qtest_start(cmd); + qtest_add_func("/vmgenid/vmgenid", vmgenid_test); + qtest_add_func("/vmgenid/vmgenid/set-guid", vmgenid_set_guid_test); + qtest_add_func("/vmgenid/vmgenid/set-guid-auto", + vmgenid_set_guid_auto_test); + ret =3D g_test_run(); + + qtest_end(); + + return ret; +} --=20 2.7.4