Re: [Qemu-devel] [PATCH v4 4/9] ACPI: Add Virtual Machine Generation ID support

2017-01-25 Thread Laszlo Ersek
On 01/25/17 02:43, b...@skyportsystems.com wrote:
> 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, and ACPI notify event is sent to the guest

(1) typo: "and" -> "an"

> 
> The user interface is a simple device with one parameter:
>  - guid (string, must be "auto" or in UUID format
>----)
> 
> Signed-off-by: Ben Warren 
> ---
>  default-configs/i386-softmmu.mak |   1 +
>  default-configs/x86_64-softmmu.mak   |   1 +
>  hw/acpi/Makefile.objs|   1 +
>  hw/acpi/vmgenid.c| 244 
> +++
>  hw/i386/acpi-build.c |   9 ++
>  include/hw/acpi/acpi_dev_interface.h |   1 +
>  include/hw/acpi/vmgenid.h|  32 +
>  7 files changed, 289 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-softmmu.mak
> index 0b51360..b2bccf6 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -56,3 +56,4 @@ CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
>  CONFIG_SMBIOS=y
>  CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
> +CONFIG_ACPI_VMGENID=y
> diff --git a/default-configs/x86_64-softmmu.mak 
> b/default-configs/x86_64-softmmu.mak
> index 7f89503..c6bd310 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -56,3 +56,4 @@ CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
>  CONFIG_SMBIOS=y
>  CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
> +CONFIG_ACPI_VMGENID=y
> 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) += cpu_hotplug.o
>  common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
>  common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
>  common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
> +common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
>  common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
>  
>  common-obj-y += acpi_interface.o
> diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
> new file mode 100644
> index 000..63cb039
> --- /dev/null
> +++ b/hw/acpi/vmgenid.c
> @@ -0,0 +1,244 @@
> +/*
> + *  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 later.
> + * 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"
> +
> +Object *find_vmgenid_dev(Error **errp)
> +{
> +Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL);
> +if (!obj) {
> +error_setg(errp, VMGENID_DEVICE " is not found");
> +}

(2) For general cleanliness, we should use "%s" in the format string,
and pass VMGENID_DEVICE as an argument.

> +return obj;
> +}
> +
> +void vmgenid_build_acpi(GArray *table_offsets, GArray *table_data,
> + BIOSLinker *linker)

(3) I think the "table_offsets" parameter should be dropped.

In this function, that param is used only for calling acpi_add_table().
Looking at other similar call sites in acpi_build(), the pattern is always:

  if (check_feature_or_device()) {
acpi_add_table(table_offsets, table_data);
build_stuff_for_feature_or_device();
  }

That is, the parameter should be dropped, and the acpi_add_table() call
should be moved out to acpi_build().

> +{
> +Object *obj;
> +VmGenIdState *s;
> +GArray *guid, *vgia;
> +Aml *ssdt, *dev, *scope, *method, *addr, *if_ctx;
> +uint32_t vgia_offset;
> +
> +obj = find_vmgenid_dev(NULL);
> +if (!obj) {
> +return;
> +}
> +s = VMGENID(obj);

(4) The call to this function, from acpi_build(), is already protected
by has_vmgenid(). (And, see my suggestion near the end of this email
about rebasing has_vmgenid() to find_vmgenid_dev().) Therefore we should
simply assert that find_vmgenid_dev() succeeds.

> +
> +acpi_add_table(table_offsets, table_data);

(So this should be moved to acpi_build(), see (3) above.)

> +
> +guid = g_array_new(false, true, sizeof(s->guid.data));
> +g_array_append_val(guid, s->guid.data);

(5) We're not considering host vs. guest endianness.
Let me quote the VmGenIdState structure:

typedef struct VmGenIdState {
SysBusDevice parent_obj;
QemuUUID guid;
uint64_t vgia;
} VmGenIdState;

According to the documentation of QemuUUID, and the qemu_uuid_parse()
and qemu_uuid_unparse() functions -- used later in this patch --, the
representation of the UUID fields is big-endian in the QemuUUID structure.

However, the Windows gue

Re: [Qemu-devel] [PATCH v4 4/9] ACPI: Add Virtual Machine Generation ID support

2017-01-25 Thread Laszlo Ersek
On 01/25/17 11:04, Laszlo Ersek wrote:

> (7) The blob constructed in this function, as a GArray, should be the
> exact same object that is later linked into fw_cfg, via acpi_setup() -->
> vmgenid_add_fw_cfg().
> 
> Currently, the blob is allocated here under the variable "guid", and
> passed to bios_linker_loader_alloc_ret_addr(). That results in the
> creation of a new BiosLinkerFileEntry object, with the "blob" field
> being set to "guid".
> 
> However, in vmgenid_add_fw_cfg(), the VmGenIdState.guid.data field is
> linked into fw_cfg. This is incorrect, those objects are independent,
> but they should be the same.
> 
> Here's how to implement it:
> 
> * Add the field
> 
> GArray *vmgenid
> 
>   to the "AcpiBuildTables" structure in "include/hw/acpi/aml-build.h",
>   under the "tcpalog" field.
> 
> * Extend the acpi_build_tables_init() and acpi_build_tables_cleanup()
>   functions in "hw/acpi/aml-build.c", so that the new field is
>   initialized and released.

In acpi_build_tables_cleanup(), the line you need is

g_array_free(tables->vmgenid, mfre);

similarly to "tcpalog".

> 
> * In the acpi_build() function, pass "tables->vmgenid" to
>   vmgenid_build_acpi(). This will require the a new parameter for the
>   latter function.
> 
> * In vmgenid_build_acpi(), construct the blob as described under (5)
>   and (6).
> 
> * In the acpi_setup() function, pass "tables.vmgenid" to
>   vmgenid_add_fw_cfg(). (Again, new function parameter is necessary.)
> 
> * In vmgenid_add_fw_cfg(), link "tables.vmgenid->data" into fw_cfg, not
>   VmGenIdState.guid.data.

Thanks
Laszlo