From nobody Sun Apr 28 03:18:29 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 1487287325838485.6592743985884; Thu, 16 Feb 2017 15:22:05 -0800 (PST) Received: from localhost ([::1]:50771 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVND-0006Da-OS for importer@patchew.org; Thu, 16 Feb 2017 18:22:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42921) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHA-0000R0-D0 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVH8-0000tZ-1q for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:48 -0500 Received: from mail-pf0-x22b.google.com ([2607:f8b0:400e:c00::22b]:33026) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVH7-0000sE-IQ for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:45 -0500 Received: by mail-pf0-x22b.google.com with SMTP id c73so8711345pfb.0 for ; Thu, 16 Feb 2017 15:15:45 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.43 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:43 -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=jXQCT/kPvJtkjZX3tIvfPLZlD0I0WdNoSXWwb51HPnE=; b=huXLZOSuAPbe6LJqXek6hllrbN3ISk5sbUTGSYucbkM3w93NPmEzYdeVyKozLZ0C7i bagXTzG2aR4OJvQqtwImPrxZxWsTyN3ld7SPU/S6PDv6IjlbpGttCeAAE2QYH+LMP2zJ uCrnBPZ1P7Qyb8AyMjMlF4Z1sVS1e40eqpn0Q= 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=jXQCT/kPvJtkjZX3tIvfPLZlD0I0WdNoSXWwb51HPnE=; b=oKMf7jgflxas/le6EpPjfyro2uiQXyyq5XqEpQtBpiae48EAwB5voHRo/0sDGvNlxA QqTHjt3XyAxDfRutRIcAhh8HzrAHfmFq34SHnvWrBO5LaitdXfFfoU+f74Odp3RWPSVJ 3yOJtsrHjfi7n4QZ1s6DGoSdiSPKq2OsCzGeBiq8MKfc1vIcuQzG0L9d8FN1oepiKO/k 8Oi3GzZMe4BQcFlJhcg+Jki2UKaVGmUHs0YUyc8sO8WC1wucGL9KJkaK32UEhGrSf5NK yslgXZ+/HyvDRRAVyb3hYYPH7g+XbYvQLNQtTRd50hl1GqVX2bSSq2w82CUN2Rx2Tgur hipA== X-Gm-Message-State: AMke39n9FIml9u7gIcsGLWgSXzhBrimgxyRQXzngTQOElVKxbCIGCDPBOSUnYMu3aH5uwy4u X-Received: by 10.98.14.84 with SMTP id w81mr5693691pfi.168.1487286944624; Thu, 16 Feb 2017 15:15:44 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:33 -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::22b Subject: [Qemu-devel] [PATCH v8 1/8] 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 Reviewed-by: Igor Mammedov Tested-by: Laszlo Ersek --- hw/acpi/bios-linker-loader.c | 66 ++++++++++++++++++++++++++++++++= ++-- include/hw/acpi/bios-linker-loader.h | 7 ++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c index d963ebe..046183a 100644 --- a/hw/acpi/bios-linker-loader.c +++ b/hw/acpi/bios-linker-loader.c @@ -78,6 +78,21 @@ 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 + * @src_offset within the table 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 dst_offset; + uint32_t src_offset; + uint8_t size; + } wr_pointer; + /* padding */ char pad[124]; }; @@ -85,9 +100,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 +294,47 @@ 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 + * @src_offset: location within source file blob to which + * @dest_file+@dst_patched_offset will point to after + * firmware's executed WRITE_POINTER command + */ +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, + uint32_t src_offset) +{ + BiosLinkerLoaderEntry entry; + const BiosLinkerFileEntry *source_file =3D + bios_linker_find_file(linker, src_file); + + assert(source_file); + assert(src_offset < source_file->blob->len); + 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.dst_offset =3D cpu_to_le32(dst_patched_offset); + entry.wr_pointer.src_offset =3D cpu_to_le32(src_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..efe17b0 100644 --- a/include/hw/acpi/bios-linker-loader.h +++ b/include/hw/acpi/bios-linker-loader.h @@ -26,5 +26,12 @@ 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, + uint32_t src_offset); + void bios_linker_loader_cleanup(BIOSLinker *linker); #endif --=20 2.7.4 From nobody Sun Apr 28 03:18:29 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 1487287077201100.66204160044106; Thu, 16 Feb 2017 15:17:57 -0800 (PST) Received: from localhost ([::1]:50744 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVJD-0001qg-Ur for importer@patchew.org; Thu, 16 Feb 2017 18:17:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42929) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHA-0000R6-Fc for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVH8-0000uD-LM for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:48 -0500 Received: from mail-pf0-x22e.google.com ([2607:f8b0:400e:c00::22e]:36783) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVH8-0000tS-DI for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:46 -0500 Received: by mail-pf0-x22e.google.com with SMTP id 189so8658389pfu.3 for ; Thu, 16 Feb 2017 15:15:46 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.44 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:44 -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=gSIFLHzPVQDCEeCLHubrulpnBKgxW6aeRBS2fyYxEzk=; b=NYrBQkChyHEEkMD0aOTE5tBEYWOVXPMtj35KWOaUiFZkN7jhZ+rfGeziYBXHjotj9j DoI3p6H1iybM9i/UFUMhdtAt1SAhD/rVB+jpfOT0hchuayzXK0RmyInUQDg7BnI79Rrj HvDWPCUhjXI81y+gV760Tk/edOt7owVTDSFww= 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=gSIFLHzPVQDCEeCLHubrulpnBKgxW6aeRBS2fyYxEzk=; b=XavaZI99oaJs3jGOKsBI/tvo5ISurhXqWyStircVLc6Qem4bPPv+H9IkUlka9YuEbn IzYK5jAFhtD9i0pw6VevWEcqFws1xQsni/H0zumcK00osLxBYDla2ysH3ZplGxa5lLUC b6qYSe0RbyeVBwTT0Rm2+ViYSlVKojBP5W71xGLBvDtig3UReA8GtoWpLRnzwFMYXO6y E3gwLOyvvz1Q+vnb28o3rM9pnMyooZ8FFpByOwPjFR/QJ+wquKs7Ei4rz6Ek+Hthm3gY KU/dMMp6Gvpoumhf88fOidq9RuXLLfcIC5c8eGbG1i5Ih9ZK2aVUoQmK6mYtAsSUt6Df o+Tg== X-Gm-Message-State: AMke39laMI9nblzmiffDWgSdd5B4iheqVM30cJZLHXKLvb6PXf2diskHQeRYNg59u3kOJHTj X-Received: by 10.98.150.70 with SMTP id c67mr5677818pfe.84.1487286945424; Thu, 16 Feb 2017 15:15:45 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:34 -0800 Message-Id: <9f3604bb0f1ab5572d5add739a0c85eb5dbadeb8.1487286467.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::22e Subject: [Qemu-devel] [PATCH v8 2/8] 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 --- 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 Sun Apr 28 03:18:29 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 1487287074275415.8066766851399; Thu, 16 Feb 2017 15:17:54 -0800 (PST) Received: from localhost ([::1]:50743 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVJA-0001jt-MO for importer@patchew.org; Thu, 16 Feb 2017 18:17:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42925) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHA-0000R5-EV for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVH9-0000ub-4c for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:48 -0500 Received: from mail-pg0-x234.google.com ([2607:f8b0:400e:c05::234]:33437) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVH8-0000tp-Vd for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:47 -0500 Received: by mail-pg0-x234.google.com with SMTP id y6so6221678pgy.0 for ; Thu, 16 Feb 2017 15:15:46 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.45 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:45 -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=57oeOrvNjdo3rgxeMp+/qaJr9en41kB1rqT9NpkwZ90=; b=1sNkCKNPmshrAhbevjLn7N+Qd3CsSQ6YbYjflTG6/S3Fbea6TDnptZ19fewJNPLQZZ k5mxqmw9Jp5PeLPbpRrIYqFERDEJlV7cHxRToSKR+OAET/VjsZnZYaeC2bnYyP/oTo71 6NbSbNGqD2oRJqKCMnkDZrtUP6dZgztit5Rt4= 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=57oeOrvNjdo3rgxeMp+/qaJr9en41kB1rqT9NpkwZ90=; b=C+weqtBHmOeDugFUVIdNnaHPu1QyL6LULAcRITmDhTuhBnqLeRyzwSoKoR0TMgGXLi eVLupqN7VaLHyU5pYDeAAGCp/pKqjOZaGbcHxoaQtuA/jkcAbJ62iTDVmpgCc0ZLicu4 oxa/wcLuHrep8jGtU+0MYeZqHYspRc4iNam8xZch44oj8JbWRlAXaxVxgr+x2PX+yG6o VcwQt60fydL42tLizLGlUsEKLIAsN9Fug+g/UfO+mjtGZpbK4UP2BtIf8TAG+2pT0zLe 5ZvzAXeLPHlgJT3nD32TQdeF+e7mqfug/YjytpaCSOerChW+PKemZoItpTyMFoRNXQe3 FaSQ== X-Gm-Message-State: AMke39lTfUXVX8Ol3lCBzEklPOOzpWyxSWvREdfZZvK+6U6uAIbjeiCE/cC23DeKKyPsFCLX X-Received: by 10.99.36.7 with SMTP id k7mr6081612pgk.201.1487286946190; Thu, 16 Feb 2017 15:15:46 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:35 -0800 Message-Id: <7c0c0ce878bdba95f08d3c7385e07ab2c654b9d7.1487286467.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::234 Subject: [Qemu-devel] [PATCH v8 3/8] 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_guid" 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 Sun Apr 28 03:18:29 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 148728761429688.39604080423987; Thu, 16 Feb 2017 15:26:54 -0800 (PST) Received: from localhost ([::1]:50794 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVRt-0002Wl-4r for importer@patchew.org; Thu, 16 Feb 2017 18:26:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42975) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHC-0000SQ-RW for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVHA-0000vu-GB for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:50 -0500 Received: from mail-pg0-x229.google.com ([2607:f8b0:400e:c05::229]:35128) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVHA-0000vG-6J for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:48 -0500 Received: by mail-pg0-x229.google.com with SMTP id t188so9834685pgt.2 for ; Thu, 16 Feb 2017 15:15:48 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.46 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:46 -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=MiKN7d4s6r7g5eXXwWPkQuXl11nMY4NdUAzeCLNnwZU=; b=ARSlhFsyuuKNii037jMq+/O7fujMbhwJiGKNr7K+I3ed8GavMxq6QbEvI0l0UKl8kP 2PTzPxTYYfdF6jdCeHMlKkCmYPuBoFxhnx0/fVQwIf4PxFXwW0nG/Kui4W903o5pPJlO N3YFfNXWSVGuXUhxfuf3isSYLYauyF2Juwh5Y= 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=MiKN7d4s6r7g5eXXwWPkQuXl11nMY4NdUAzeCLNnwZU=; b=bGAnjPyZVGYaOeRXV1Mjx0vxsVAzyulQhJaLpSqRpvAkRwKFsAIhrQSspm6AsBUba8 JEcclVsWE4O4eidtI0yrwLwgEAlikYA16Hllif07PHyTDdKeud5VS5lDB4qtVx6Fcsjd uIUR8QhfNE5k+nrwsBVeMhLjDh9cjENRu7o+blmw0l8yo61KvhHxCpFmX7ocTuOnVu0k RKD+a7JvuSKDKobkLfxH6MCVttT8dwDnEwaNeos3RPDAF1hDpBCCVoBewHWis/C2tVm6 zohVgjHDOCosAlvOYQlC2IEn8iet3HeKG4Xrvyrz0AjCp5S5UZ7meeIjj0PW4MG6xI6v TOfQ== X-Gm-Message-State: AMke39mwHyr9hKCIr9xXeD767YlqYG+fFiD442o+tZ6ozv6ge4ckU3IDFlBcMrwCN7p9ifNK X-Received: by 10.99.55.91 with SMTP id g27mr6098786pgn.65.1487286947194; Thu, 16 Feb 2017 15:15:47 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:36 -0800 Message-Id: <88232638f9ff3b17b54987624468678ea14a3037.1487286467.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::229 Subject: [Qemu-devel] [PATCH v8 4/8] 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: Igor Mammedov 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 | 242 +++++++++++++++++++++++++++++++= ++++ hw/i386/acpi-build.c | 16 +++ include/hw/acpi/acpi_dev_interface.h | 1 + include/hw/acpi/vmgenid.h | 35 +++++ 7 files changed, 297 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..c8465df --- /dev/null +++ b/hw/acpi/vmgenid.c @@ -0,0 +1,242 @@ +/* + * 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 - ARRAY_SIZE(guid_le.data)); + guid_le =3D vms->guid; + 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. + * The address that is patched in is offset in order to implement + * the "OVMF SDT Header probe suppressor" + * see docs/specs/vmgenid.txt for more details. + */ + bios_linker_loader_write_pointer(linker, + VMGENID_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), + VMGENID_GUID_FW_CFG_FILE, VMGENID_GUID_OFFSET); + + /* 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. + */ + guid_le =3D vms->guid; + 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, 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_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; + dc->hotpluggable =3D false; + + object_class_property_add_str(klass, VMGENID_GUID, NULL, + vmgenid_set_guid, NULL); + object_class_property_set_description(klass, VMGENID_GUID, + "Set Global Unique Identifier " + "(big-endian) or auto for random value= ", + NULL); +} + +static const TypeInfo vmgenid_device_info =3D { + .name =3D VMGENID_DEVICE, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(VmGenIdState), + .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 Sun Apr 28 03:18:29 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 1487287084265948.8495705711186; Thu, 16 Feb 2017 15:18:04 -0800 (PST) Received: from localhost ([::1]:50746 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVJL-0002Bd-4i for importer@patchew.org; Thu, 16 Feb 2017 18:18:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42971) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHC-0000S7-E9 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVHB-0000wN-0W for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:50 -0500 Received: from mail-pg0-x22d.google.com ([2607:f8b0:400e:c05::22d]:36526) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVHA-0000vb-RL for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:48 -0500 Received: by mail-pg0-x22d.google.com with SMTP id v184so9799533pgv.3 for ; Thu, 16 Feb 2017 15:15:48 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.47 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:47 -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=gyHjqZnXzbyvjhes/Jj4Pi9sHX7eKK/i5wKmAW0ZREM=; b=qaiHcTyiQXSGZXZhbrufWTVJ3Iu0BhBc8poFEGK/QNfljo2El3rVJYzAanlCXTqeen aOyR753nBHqJ8EwPoLTSeqpGcUrl86bnHqWk/8FlmBw3mFYwU2CxIXb6Tss1aWo+vui+ gw4E095d9k9bhyjy1kw7fn/ll9BC1bWYlwZ4Y= 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=gyHjqZnXzbyvjhes/Jj4Pi9sHX7eKK/i5wKmAW0ZREM=; b=Nu5CvdQULWviyb/U57Rdwa5K9KRe+WqLndcVac6LvTzldxifkYI4wFRfTvLS/wy5ZW acmX2XuH9DFAbQs1iEo+llYADGyTMjE2Z3IN1spp95tq78x7FW3cmWsoNdzDXInz6NfD HNyahlcFD777gYu50bVGK2Sc9XmxeoGULTFuiea2BBomO3rIjQ890rapRtQSKFKHcPHB o3vLPq5niKumSdvtK0ZWNjZx8pC9L2UYdCI6bmn91ar8dcghdKHROylQbDK6f27V41+7 6jJz6AdzdrdkXT9rx76Wjjb4K3xMR/l0k8vCLFmT6Ch67EW35W5kdHWKQOoY3vr2GiyH xEBw== X-Gm-Message-State: AMke39kIzBsyaKzU5Fk8cRRpOYFkTRk4La8R/yo2fJFw/U7uXJHI+eiJrs5dGPnDEXFhcqf/ X-Received: by 10.99.156.2 with SMTP id f2mr6088159pge.189.1487286947998; Thu, 16 Feb 2017 15:15:47 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:37 -0800 Message-Id: <76fbc5294cefdcbd4c6344d77357f845868079e3.1487286467.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 v8 5/8] 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 | 14 ++++++++++++++ hmp.c | 9 +++++++++ hmp.h | 1 + hw/acpi/vmgenid.c | 16 ++++++++++++++++ qapi-schema.json | 20 ++++++++++++++++++++ stubs/Makefile.objs | 1 + stubs/vmgenid.c | 9 +++++++++ 7 files changed, 70 insertions(+) create mode 100644 stubs/vmgenid.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index b0f35e6..a53f105 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -802,6 +802,20 @@ Show information about hotpluggable CPUs ETEXI =20 STEXI +@item info vm-generation-id +@findex 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 c8465df..744f284 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -240,3 +240,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 5edb08d..396e49c 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -6056,3 +6056,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..c64eb7a --- /dev/null +++ b/stubs/vmgenid.c @@ -0,0 +1,9 @@ +#include "qemu/osdep.h" +#include "qmp-commands.h" +#include "qapi/qmp/qerror.h" + +GuidInfo *qmp_query_vm_generation_id(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} --=20 2.7.4 From nobody Sun Apr 28 03:18:29 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 148728733616482.68297376847863; Thu, 16 Feb 2017 15:22:16 -0800 (PST) Received: from localhost ([::1]:50772 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVNP-0006Re-2K for importer@patchew.org; Thu, 16 Feb 2017 18:22:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43009) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHE-0000Tm-Dm for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVHC-0000xV-G6 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:52 -0500 Received: from mail-pg0-x22e.google.com ([2607:f8b0:400e:c05::22e]:34766) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVHC-0000wp-7L for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:50 -0500 Received: by mail-pg0-x22e.google.com with SMTP id z67so9828349pgb.1 for ; Thu, 16 Feb 2017 15:15:50 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.48 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:48 -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=9EF1EMtygXV98L2XCotWBPXSO5eb9QR1nV8Pgv6kEBU=; b=aA6Hm2EiCGOCyL3oM5UYjhTDZtiOKHQ/cEvmnSkfrMH520WYY5zizeJpSo+fs+JtaV jzkfFIxTl3WkMhfsATL1BEYEMSIIz7o3lVdNLlClZCWsBSK3SG3SbkJ2T7+mq2G/e1DZ 0KgZ896xakBC95aUQp1ENthnYhVd8dP2apgms= 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=9EF1EMtygXV98L2XCotWBPXSO5eb9QR1nV8Pgv6kEBU=; b=hN4UHx2PUTJI79YTcxOhYrlFy3YM8iCsP0OhwYFo4Np64ZYFyz8uJ2NSUs4vMkqptD NzEwuNA22eaDJPsp3SCgStUyR9RaQx5sqI3CjTgqC5v65OyHbDGoGizHc4Oxv2G0DSBi 8sMB2kNA4N2+gbRVwm24osVbCA4ZBd687/xJH7hBD12OI408FVg/fjrul54tA90P4BNX /FwZDRVKxXfkm3PQxb5M0MUwOiLldn4h2mRMscLnuDQNXYgxHK5Hld3j1PhmC/rH9cAi 0kR8zxgn/8I8Xyn+eSUJ+mtiVKhg4sAJxggXFLu4x8UPaKiso6+VVzmlC+99GmtAAZLk VqUg== X-Gm-Message-State: AMke39nCkHMehh5fWqvpqZHIS9//2FMRg0aloGYWjIgSwt0xstcYpWb3ImznHQDkMWrNuUyU X-Received: by 10.99.168.2 with SMTP id o2mr5926615pgf.159.1487286948922; Thu, 16 Feb 2017 15:15:48 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:38 -0800 Message-Id: <0349b18610175568b72545bcd1e2b476c93477ac.1487286467.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::22e Subject: [Qemu-devel] [PATCH v8 6/8] tests: Move reusable ACPI code into a utility 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 Reviewed-by: Igor Mammedov --- MAINTAINERS | 2 + tests/Makefile.include | 2 +- tests/acpi-utils.c | 65 +++++++++++++++++++++++ tests/acpi-utils.h | 94 +++++++++++++++++++++++++++++++++ tests/bios-tables-test.c | 132 ++++++-------------------------------------= ---- 5 files changed, 177 insertions(+), 118 deletions(-) create mode 100644 tests/acpi-utils.c create mode 100644 tests/acpi-utils.h diff --git a/MAINTAINERS b/MAINTAINERS index fb57d8e..81d4baf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -909,6 +909,8 @@ F: hw/acpi/* F: hw/smbios/* F: hw/i386/acpi-build.[hc] F: hw/arm/virt-acpi-build.c +F: tests/bios-tables-test.c +F: tests/acpi-utils.[hc] =20 ppc4xx M: Alexander Graf diff --git a/tests/Makefile.include b/tests/Makefile.include index 634394a..143507e 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -667,7 +667,7 @@ tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y) tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ - tests/boot-sector.o $(libqos-obj-y) + tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y) tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj= -y) tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y) diff --git a/tests/acpi-utils.c b/tests/acpi-utils.c new file mode 100644 index 0000000..41dc1ea --- /dev/null +++ b/tests/acpi-utils.c @@ -0,0 +1,65 @@ +/* + * ACPI Utility Functions + * + * Copyright (c) 2013 Red Hat Inc. + * Copyright (c) 2017 Skyport Systems + * + * Authors: + * Michael S. Tsirkin , + * 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 +#include "qemu-common.h" +#include "hw/smbios/smbios.h" +#include "qemu/bitmap.h" +#include "acpi-utils.h" +#include "boot-sector.h" + +uint8_t acpi_calc_checksum(const uint8_t *data, int len) +{ + int i; + uint8_t sum =3D 0; + + for (i =3D 0; i < len; i++) { + sum +=3D data[i]; + } + + return sum; +} + +uint32_t acpi_find_rsdp_address(void) +{ + uint32_t off; + + /* RSDP location can vary across a narrow range */ + for (off =3D 0xf0000; off < 0x100000; off +=3D 0x10) { + uint8_t sig[] =3D "RSD PTR "; + int i; + + for (i =3D 0; i < sizeof sig - 1; ++i) { + sig[i] =3D readb(off + i); + } + + if (!memcmp(sig, "RSD PTR ", sizeof sig)) { + break; + } + } + return off; +} + +void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table) +{ + ACPI_READ_FIELD(rsdp_table->signature, addr); + ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR "); + + ACPI_READ_FIELD(rsdp_table->checksum, addr); + ACPI_READ_ARRAY(rsdp_table->oem_id, addr); + ACPI_READ_FIELD(rsdp_table->revision, addr); + ACPI_READ_FIELD(rsdp_table->rsdt_physical_address, addr); + ACPI_READ_FIELD(rsdp_table->length, addr); +} diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h new file mode 100644 index 0000000..9f9a2d5 --- /dev/null +++ b/tests/acpi-utils.h @@ -0,0 +1,94 @@ +/* + * Utilities for working with ACPI tables + * + * Copyright (c) 2013 Red Hat Inc. + * + * Authors: + * Michael S. Tsirkin , + * + * 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. + */ + +#ifndef TEST_ACPI_UTILS_H +#define TEST_ACPI_UTILS_H + +#include "hw/acpi/acpi-defs.h" +#include "libqtest.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) + +uint8_t acpi_calc_checksum(const uint8_t *data, int len); +uint32_t acpi_find_rsdp_address(void); +void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table); + +#endif /* TEST_ACPI_UTILS_H */ diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 5404805..423a6f5 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -13,10 +13,9 @@ #include "qemu/osdep.h" #include #include "qemu-common.h" -#include "libqtest.h" -#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 +23,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 +40,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 @@ -147,36 +75,9 @@ static void free_test_data(test_data *data) g_array_free(data->tables, false); } =20 -static uint8_t acpi_checksum(const uint8_t *data, int len) -{ - int i; - uint8_t sum =3D 0; - - for (i =3D 0; i < len; i++) { - sum +=3D data[i]; - } - - return sum; -} - static void test_acpi_rsdp_address(test_data *data) { - uint32_t off; - - /* OK, now find RSDP */ - for (off =3D 0xf0000; off < 0x100000; off +=3D 0x10) { - uint8_t sig[] =3D "RSD PTR "; - int i; - - for (i =3D 0; i < sizeof sig - 1; ++i) { - sig[i] =3D readb(off + i); - } - - if (!memcmp(sig, "RSD PTR ", sizeof sig)) { - break; - } - } - + uint32_t off =3D acpi_find_rsdp_address(); g_assert_cmphex(off, <, 0x100000); data->rsdp_addr =3D off; } @@ -186,17 +87,10 @@ static void test_acpi_rsdp_table(test_data *data) AcpiRsdpDescriptor *rsdp_table =3D &data->rsdp_table; uint32_t addr =3D data->rsdp_addr; =20 - ACPI_READ_FIELD(rsdp_table->signature, addr); - ACPI_ASSERT_CMP64(rsdp_table->signature, "RSD PTR "); - - ACPI_READ_FIELD(rsdp_table->checksum, addr); - ACPI_READ_ARRAY(rsdp_table->oem_id, addr); - ACPI_READ_FIELD(rsdp_table->revision, addr); - ACPI_READ_FIELD(rsdp_table->rsdt_physical_address, addr); - ACPI_READ_FIELD(rsdp_table->length, addr); + acpi_parse_rsdp_table(addr, rsdp_table); =20 /* rsdp checksum is not for the whole table, but for the first 20 byte= s */ - g_assert(!acpi_checksum((uint8_t *)rsdp_table, 20)); + g_assert(!acpi_calc_checksum((uint8_t *)rsdp_table, 20)); } =20 static void test_acpi_rsdt_table(test_data *data) @@ -220,8 +114,9 @@ static void test_acpi_rsdt_table(test_data *data) tables =3D g_new0(uint32_t, tables_nr); ACPI_READ_ARRAY_PTR(tables, tables_nr, addr); =20 - checksum =3D acpi_checksum((uint8_t *)rsdt_table, rsdt_table->length) + - acpi_checksum((uint8_t *)tables, tables_nr * sizeof(uint32_= t)); + checksum =3D acpi_calc_checksum((uint8_t *)rsdt_table, rsdt_table->len= gth) + + acpi_calc_checksum((uint8_t *)tables, + tables_nr * sizeof(uint32_t)); g_assert(!checksum); =20 /* SSDT tables after FADT */ @@ -279,7 +174,7 @@ static void test_acpi_fadt_table(test_data *data) ACPI_READ_FIELD(fadt_table->flags, addr); =20 ACPI_ASSERT_CMP(fadt_table->signature, "FACP"); - g_assert(!acpi_checksum((uint8_t *)fadt_table, fadt_table->length)); + g_assert(!acpi_calc_checksum((uint8_t *)fadt_table, fadt_table->length= )); } =20 static void test_acpi_facs_table(test_data *data) @@ -308,8 +203,10 @@ static void test_dst_table(AcpiSdtTable *sdt_table, ui= nt32_t addr) sdt_table->aml =3D g_malloc0(sdt_table->aml_len); ACPI_READ_ARRAY_PTR(sdt_table->aml, sdt_table->aml_len, addr); =20 - checksum =3D acpi_checksum((uint8_t *)sdt_table, sizeof(AcpiTableHeade= r)) + - acpi_checksum((uint8_t *)sdt_table->aml, sdt_table->aml_len= ); + checksum =3D acpi_calc_checksum((uint8_t *)sdt_table, + sizeof(AcpiTableHeader)) + + acpi_calc_checksum((uint8_t *)sdt_table->aml, + sdt_table->aml_len); g_assert(!checksum); } =20 @@ -608,8 +505,9 @@ static bool smbios_ep_table_ok(test_data *data) return false; } ACPI_READ_FIELD(ep_table->smbios_bcd_revision, addr); - if (acpi_checksum((uint8_t *)ep_table, sizeof *ep_table) || - acpi_checksum((uint8_t *)ep_table + 0x10, sizeof *ep_table - 0x10)= ) { + if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table) || + acpi_calc_checksum((uint8_t *)ep_table + 0x10, + sizeof *ep_table - 0x10)) { return false; } return true; --=20 2.7.4 From nobody Sun Apr 28 03:18:29 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 1487287378885497.5929876632114; Thu, 16 Feb 2017 15:22:58 -0800 (PST) Received: from localhost ([::1]:50774 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVO5-0007sP-IF for importer@patchew.org; Thu, 16 Feb 2017 18:22:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43021) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHE-0000U4-N1 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVHD-0000y6-8D for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:52 -0500 Received: from mail-pg0-x22f.google.com ([2607:f8b0:400e:c05::22f]:35132) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVHD-0000xM-0O for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:51 -0500 Received: by mail-pg0-x22f.google.com with SMTP id t188so9834949pgt.2 for ; Thu, 16 Feb 2017 15:15:50 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.48 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:49 -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=1z/cWdDXxr6YJRkyxmPb2hVOBegxoEkZ+hIzjR3sLS4=; b=MI5thuRrLdEPHYsLLgx14j5JxtYscNN+dootFvaxDtY5UhYOs1VyNBSUJ9+Q00Zfbn hYV8EGYJsM0NKWFT0ZCm5MW/F/IiQlwsrhnsT2r3syn6ahf4Zh7rF3SYa6Hq+cJJQnpV e7Lmi56Ub/PEwqmCePzoM9vqCe6oFpeuHuzXg= 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=1z/cWdDXxr6YJRkyxmPb2hVOBegxoEkZ+hIzjR3sLS4=; b=FDBzlc4386ejWY4bO8hUtIETQm/svk4/MGlTMQk9eGSavcNUNZ2KyXocIuoXKXtNia 10Cz5xvrfCc2/dm5aTwMTwn7uyNTePZs7z09VV6MRMydyowtRI4Y9/emszfpbcV6kLAF g8Wz7MaOrJBpy2FYzafU+gfeHmetSbVRd1//PC53rInq/CPw2MkJQn9/152p39pOSfKE VqYvYyIzW7wpOjOmye0KziGxSNk7pVG2AHa44X2Zg5DX/yWjQ/fiJT3Q+PBRua6fo4Fk qZzcsWXwBUKokMj9HYfcWHqpoy2c/GMkNCvOd6uzQFWS60jeh7h85dnZYqAQh08Vw0zH 7x2g== X-Gm-Message-State: AMke39mj5J+tcW6u9hytD3hJRjqIZQgJ5S8ic/LxdGqxzzZ5oh7VKtI22GzqL0XYFfXp5KCs X-Received: by 10.99.140.77 with SMTP id q13mr6003444pgn.179.1487286949849; Thu, 16 Feb 2017 15:15:49 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:39 -0800 Message-Id: <5353279f68be14c63f049bc34902675290e45b1d.1487286467.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 v8 7/8] 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. Read the GUID from guest memory * test that the "auto" argument to the GUID generates a valid GUID, as seen by the guest. * test that a GUID passed in can be queried from the monitor This patch is loosely based on a previous patch from: Gal Hammer and Igor Mammedov Signed-off-by: Ben Warren Reviewed-by: Igor Mammedov --- tests/Makefile.include | 2 + tests/vmgenid-test.c | 200 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 202 insertions(+) create mode 100644 tests/vmgenid-test.c diff --git a/tests/Makefile.include b/tests/Makefile.include index 143507e..8d36341 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 tests/acpi-utils.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..123beae --- /dev/null +++ b/tests/vmgenid-test.c @@ -0,0 +1,200 @@ +/* + * 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 + */ +#define RSDP_ADDR_INVALID 0x100000 /* RSDP must be below this address */ +#define RSDP_SLEEP_US 100000 /* Sleep for 100ms between tries */ +#define RSDP_TRIES_MAX 100 /* Max total time is 10 seconds */ + +typedef struct { + AcpiTableHeader header; + gchar name_op; + gchar vgia[4]; + gchar val_op; + uint32_t vgia_val; +} QEMU_PACKED VgidTable; + +static uint32_t acpi_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; + + /* Tables may take a short time to be set up by the guest */ + for (i =3D 0; i < RSDP_TRIES_MAX; i++) { + off =3D acpi_find_rsdp_address(); + if (off < RSDP_ADDR_INVALID) { + break; + } + g_usleep(RSDP_SLEEP_US); + } + g_assert_cmphex(off, <, RSDP_ADDR_INVALID); + + acpi_parse_rsdp_table(off, &rsdp_table); + + 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 read_guid_from_memory(QemuUUID *guid) +{ + uint32_t vmgenid_addr; + int i; + + vmgenid_addr =3D acpi_find_vgia(); + g_assert(vmgenid_addr); + + /* Read the GUID directly from guest memory */ + for (i =3D 0; i < 16; i++) { + guid->data[i] =3D readb(vmgenid_addr + 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 read_guid_from_monitor(QemuUUID *guid) +{ + QDict *rsp, *rsp_ret; + const char *guid_str; + + rsp =3D qmp("{ 'execute': 'query-vm-generation-id' }"); + if (qdict_haskey(rsp, "return")) { + rsp_ret =3D qdict_get_qdict(rsp, "return"); + g_assert(qdict_haskey(rsp_ret, "guid")); + guid_str =3D qdict_get_str(rsp_ret, "guid"); + g_assert(qemu_uuid_parse(guid_str, guid) =3D=3D 0); + } + QDECREF(rsp); +} + +static void vmgenid_set_guid_test(void) +{ + QemuUUID expected, measured; + gchar *cmd; + + g_assert(qemu_uuid_parse(VGID_GUID, &expected) =3D=3D 0); + + cmd =3D g_strdup_printf("-machine accel=3Dtcg -device vmgenid,id=3Dtes= tvgid," + "guid=3D%s", VGID_GUID); + qtest_start(cmd); + + /* Read the GUID from accessing guest memory */ + read_guid_from_memory(&measured); + g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) = =3D=3D 0); + + qtest_quit(global_qtest); + g_free(cmd); +} + +static void vmgenid_set_guid_auto_test(void) +{ + const char *cmd; + QemuUUID measured; + + cmd =3D "-machine accel=3Dtcg -device vmgenid,id=3Dtestvgid," "guid=3D= auto"; + qtest_start(cmd); + + read_guid_from_memory(&measured); + + /* Just check that the GUID is non-null */ + g_assert(!qemu_uuid_is_null(&measured)); + + qtest_quit(global_qtest); +} + +static void vmgenid_query_monitor_test(void) +{ + QemuUUID expected, measured; + gchar *cmd; + + g_assert(qemu_uuid_parse(VGID_GUID, &expected) =3D=3D 0); + + cmd =3D g_strdup_printf("-machine accel=3Dtcg -device vmgenid,id=3Dtes= tvgid," + "guid=3D%s", VGID_GUID); + qtest_start(cmd); + + /* Read the GUID via the monitor */ + read_guid_from_monitor(&measured); + g_assert(memcmp(measured.data, expected.data, sizeof(measured.data)) = =3D=3D 0); + + qtest_quit(global_qtest); + g_free(cmd); +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/vmgenid/vmgenid/set-guid", + vmgenid_set_guid_test); + qtest_add_func("/vmgenid/vmgenid/set-guid-auto", + vmgenid_set_guid_auto_test); + qtest_add_func("/vmgenid/vmgenid/query-monitor", + vmgenid_query_monitor_test); + ret =3D g_test_run(); + + return ret; +} --=20 2.7.4 From nobody Sun Apr 28 03:18:29 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 1487287079420342.1481776694343; Thu, 16 Feb 2017 15:17:59 -0800 (PST) Received: from localhost ([::1]:50745 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVJG-0001yG-9J for importer@patchew.org; Thu, 16 Feb 2017 18:17:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43020) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceVHE-0000U3-Mu for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceVHD-0000yK-Ns for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:52 -0500 Received: from mail-pg0-x232.google.com ([2607:f8b0:400e:c05::232]:35133) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceVHD-0000xs-J1 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 18:15:51 -0500 Received: by mail-pg0-x232.google.com with SMTP id t188so9835030pgt.2 for ; Thu, 16 Feb 2017 15:15:51 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id r74sm15455696pfb.67.2017.02.16.15.15.49 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 16 Feb 2017 15:15:50 -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=khvZBYzhHlR26BetZbaGaRF4NKW1iKbN7J4WQ7Trshk=; b=M96OrZ8QkViIOp55sYO+39Vn05bUnmoR24KyE5jTbSQfbUHeaM9PicD0steRoOOsGR BsrdlYGf/Ck/WBHxSe0fxA7XE/OhzU7lMbpYhu2eNVGkeIWSwhlK398PZ8kMTGRBWfHI qkRZbNcIBRoUZqU+OvJdhiWlEj14fTGDj1BWQ= 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=khvZBYzhHlR26BetZbaGaRF4NKW1iKbN7J4WQ7Trshk=; b=MI7vpg4Ui5shqiCsJBdmzvN7QxjtCYVBJp1UNci6YRnBjvKK0CRtYw7LCy6jeT8Bjn 3dYWJb4Z7A30RSIlqUeUTdEWrgzDB+r5U5Yq3BXJHWkRCKSNiOhwZiXb83hXb5cIsGQ/ IDImv5gySej0HUy+yp5410wu2Ui6TysqN4wzrSN9tflX6UI3ZFwgwwV4NBIUH9OlbFL5 CCNpHOTg/tCfTeZopcnCbfDU4wr+jnuU9ml2lz9waLlXgDo0fY4kTI9dxeOf1bFzwlMu rmVSnxMf3wQJ+Fbp3aROZFigBxDORncNM4hXDqGj83+O7o8MLxaTqiY60rpIeU2Bl5UH jt8w== X-Gm-Message-State: AMke39lTBpve4ZyaCMvPDsH3YRyX/tdb/Bwv9x1LrRAyg8UOpaKCHb7/UZAdMLUWxucqpukR X-Received: by 10.98.71.7 with SMTP id u7mr5728371pfa.76.1487286950792; Thu, 16 Feb 2017 15:15:50 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 15:15:40 -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::232 Subject: [Qemu-devel] [PATCH v8 8/8] MAINTAINERS: Add VM Generation ID entries 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 Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek Reviewed-by: Igor Mammedov --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 81d4baf..8f5dd35 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1125,6 +1125,15 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c =20 +VM Generation ID +M: Ben Warren +S: Maintained +F: hw/acpi/vmgenid.c +F: include/hw/acpi/vmgenid.h +F: docs/specs/vmgenid.txt +F: tests/vmgenid-test.c +F: stubs/vmgenid.c + Subsystems ---------- Audio --=20 2.7.4