All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID
@ 2015-06-16 14:10 Gal Hammer
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description Gal Hammer
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Gal Hammer @ 2015-06-16 14:10 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gal Hammer, pbonzini, imammedo, mst

Hi,

Resending after applying changes requested from Paolo, Igor and Michael.

Thanks,

    Gal.

V16 - Remove the sysbus device and use directly a DeviceClass.
    - Device is created with -device command line parameter
    - Device have uuid and addr parameters.
    - Support for 64-bit address.
    - Shorten the ACPI device description.

V15 - Version is based on V7 ("fixed address") with new aml apis.

V13, V14 - Igor Mammedov's patches.

V12 - Fixed bios_linker_loader_add_pointer call parameters. Offset
      should be relative to the table.

V11 - Add required missing files.

V10 - Fixed typos in docs and a few clarification.

V9 - Add a unit test.
   - Rebased to version 2.2.
   - Removed hex.generated the binary files from patch.

V8 - Add a device's description file.
   - GUID is stored in fw cfg file and the guest writes the
     physical address to the device (reduces vmexits).

V7 - Move the device's description back to the static SSDT table.
   - The GUID is store in a "hard coded" physical address and not
     in the ACPI table itself.
   - ACPI notification is triggered when the GUID is changed.

V6 - include the pre-compiled ASL file
   - remove an empty line at end of files.

V5 - Move device's description to SSDT table (dynamic).

V4 - Fix a typo in error message string.
   - Move device's description from DSDT back to SSDT table.

V3 - Remove "-uuid" command line parameter.
   - Move device's description from SSDT to DSDT table.
   - Add new "vmgenid" sysbus device.

Gal Hammer (4):
  docs: vm generation id device's description
  acpi: add a vm_generation_id_changed method
  i386: add a Virtual Machine Generation ID device
  tests: add a unit test for the vmgenid device

 default-configs/i386-softmmu.mak     |   1 +
 default-configs/x86_64-softmmu.mak   |   1 +
 docs/specs/vmgenid.txt               |  33 +++++++++
 hw/acpi/core.c                       |   8 ++
 hw/acpi/ich9.c                       |   8 ++
 hw/acpi/piix4.c                      |   8 ++
 hw/i386/acpi-build.c                 |  32 ++++++++
 hw/isa/lpc_ich9.c                    |   1 +
 hw/misc/Makefile.objs                |   1 +
 hw/misc/vmgenid.c                    | 140 +++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi.h               |   2 +
 include/hw/acpi/acpi_dev_interface.h |   4 +
 include/hw/acpi/ich9.h               |   2 +
 include/hw/i386/pc.h                 |   3 +
 tests/Makefile                       |   2 +
 tests/vmgenid-test.c                 |  44 +++++++++++
 16 files changed, 290 insertions(+)
 create mode 100644 docs/specs/vmgenid.txt
 create mode 100644 hw/misc/vmgenid.c
 create mode 100644 tests/vmgenid-test.c

-- 
2.1.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description
  2015-06-16 14:10 [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID Gal Hammer
@ 2015-06-16 14:11 ` Gal Hammer
  2015-06-16 15:22   ` Eric Blake
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method Gal Hammer
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Gal Hammer @ 2015-06-16 14:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gal Hammer, pbonzini, imammedo, mst

Signed-off-by: Gal Hammer <ghammer@redhat.com>
---
 docs/specs/vmgenid.txt | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 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..d06977a
--- /dev/null
+++ b/docs/specs/vmgenid.txt
@@ -0,0 +1,33 @@
+VIRTUAL MACHINE GENERATION ID
+=============================
+
+Copyright (C) 2015 Red Hat, Inc.
+
+This work is licensed under the terms of the GNU GPL, version 2 or later.
+See the COPYING file in the top-level directory.
+
+===
+
+The VM generation ID (vmgenid) device is an emulated device which
+is expected to exposes a 128-bit, cryptographically random, integer value
+identifier, provided by a management system (It is NOT in the device's
+responsibilty to ensure that the value is cryptographically random).
+
+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).
+
+This is specified on the web at: http://go.microsoft.com/fwlink/?LinkId=260709
+
+---
+
+The vmgenid device is a device with the following ACPI ID: "QEMU0002".
+
+It has two properties:
+
+uuid - The virtual machine generation ID (A required UUID string)
+addr - The uuid memory location (A 64-bit address, defaults to 0xfedf0000)
+
+According to the specification, any change to the GUID executes an
+ACPI notification. The vmgenid device triggers the GPE._E00 which
+executes the ACPI Notify operation.
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method
  2015-06-16 14:10 [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID Gal Hammer
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description Gal Hammer
@ 2015-06-16 14:11 ` Gal Hammer
  2015-06-16 15:23   ` Eric Blake
  2015-06-16 22:55   ` Igor Mammedov
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device Gal Hammer
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device Gal Hammer
  3 siblings, 2 replies; 11+ messages in thread
From: Gal Hammer @ 2015-06-16 14:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gal Hammer, pbonzini, imammedo, mst

Add a new method to the AcpiDeviceIfClass interface. The new
method sends an ACPI notfication when the VM generation id is
changed.

Signed-off-by: Gal Hammer <ghammer@redhat.com>
---
 hw/acpi/core.c                       | 8 ++++++++
 hw/acpi/ich9.c                       | 8 ++++++++
 hw/acpi/piix4.c                      | 8 ++++++++
 hw/isa/lpc_ich9.c                    | 1 +
 include/hw/acpi/acpi.h               | 2 ++
 include/hw/acpi/acpi_dev_interface.h | 4 ++++
 include/hw/acpi/ich9.h               | 2 ++
 7 files changed, 33 insertions(+)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 0f201d8..3c8d1eb 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -29,6 +29,8 @@
 #include "qapi-visit.h"
 #include "qapi-event.h"
 
+#define ACPI_VM_GENERATION_ID_CHANGED_STATUS 1
+
 struct acpi_table_header {
     uint16_t _length;         /* our length, not actual part of the hdr */
                               /* allows easier parsing for fw_cfg clients */
@@ -703,3 +705,9 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq)
                        (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
                        !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
 }
+
+void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq irq)
+{
+    acpi_regs->gpe.sts[0] |= ACPI_VM_GENERATION_ID_CHANGED_STATUS;
+    acpi_update_sci(acpi_regs, irq);
+}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 8a64ffb..cab1af7 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -429,3 +429,11 @@ void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
 
     acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list);
 }
+
+void ich9_vm_generation_id_changed(AcpiDeviceIf *adev)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
+    ICH9LPCPMRegs *pm = &s->pm;
+
+    acpi_vm_generation_id_changed(&pm->acpi_regs, pm->irq);
+}
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 3bd1d5a..101a13a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -580,6 +580,13 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
     acpi_memory_ospm_status(&s->acpi_memory_hotplug, list);
 }
 
+static void piix4_vm_generation_id_changed(AcpiDeviceIf *adev)
+{
+    PIIX4PMState *s = PIIX4_PM(adev);
+
+    acpi_vm_generation_id_changed(&s->ar, s->irq);
+}
+
 static Property piix4_pm_properties[] = {
     DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
     DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
@@ -618,6 +625,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
     hc->unplug_request = piix4_device_unplug_request_cb;
     hc->unplug = piix4_device_unplug_cb;
     adevc->ospm_status = piix4_ospm_status;
+    adevc->vm_generation_id_changed = piix4_vm_generation_id_changed;
 }
 
 static const TypeInfo piix4_pm_info = {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index b3e0b1f..f240a3a 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -702,6 +702,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
     hc->unplug_request = ich9_device_unplug_request_cb;
     hc->unplug = ich9_device_unplug_cb;
     adevc->ospm_status = ich9_pm_ospm_status;
+    adevc->vm_generation_id_changed = ich9_vm_generation_id_changed;
 }
 
 static const TypeInfo ich9_lpc_info = {
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index b20bd55..1a4caf2 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -196,4 +196,6 @@ unsigned acpi_table_len(void *current);
 void acpi_table_add(const QemuOpts *opts, Error **errp);
 void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
 
+void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq irq);
+
 #endif /* !QEMU_HW_ACPI_H */
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index f245f8d..757ce60 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -28,6 +28,9 @@ typedef struct AcpiDeviceIf {
  * ospm_status: returns status of ACPI device objects, reported
  *              via _OST method if device supports it.
  *
+ * vm_generation_id_changed: notify the guest that it generation
+ *                           id was changed.
+ *
  * Interface is designed for providing unified interface
  * to generic ACPI functionality that could be used without
  * knowledge about internals of actual device that implements
@@ -39,5 +42,6 @@ typedef struct AcpiDeviceIfClass {
 
     /* <public> */
     void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
+    void (*vm_generation_id_changed)(AcpiDeviceIf *adev);
 } AcpiDeviceIfClass;
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 77cc65c..497c004 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -70,4 +70,6 @@ void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
                               Error **errp);
 
 void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
+
+void ich9_vm_generation_id_changed(AcpiDeviceIf *adev);
 #endif /* HW_ACPI_ICH9_H */
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device
  2015-06-16 14:10 [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID Gal Hammer
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description Gal Hammer
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method Gal Hammer
@ 2015-06-16 14:11 ` Gal Hammer
  2015-06-16 22:52   ` Igor Mammedov
  2015-06-16 23:08   ` Igor Mammedov
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device Gal Hammer
  3 siblings, 2 replies; 11+ messages in thread
From: Gal Hammer @ 2015-06-16 14:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gal Hammer, pbonzini, imammedo, mst

Based on Microsoft's specifications (paper can be downloaded from
http://go.microsoft.com/fwlink/?LinkId=260709), add a device
description to the SSDT ACPI table and its implementation.

The GUID is set using a global "vmgenid.uuid" parameter.

Signed-off-by: Gal Hammer <ghammer@redhat.com>
---
 default-configs/i386-softmmu.mak   |   1 +
 default-configs/x86_64-softmmu.mak |   1 +
 hw/i386/acpi-build.c               |  32 +++++++++
 hw/misc/Makefile.objs              |   1 +
 hw/misc/vmgenid.c                  | 140 +++++++++++++++++++++++++++++++++++++
 include/hw/i386/pc.h               |   3 +
 6 files changed, 178 insertions(+)
 create mode 100644 hw/misc/vmgenid.c

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 91d602c..3c2fda8 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -48,3 +48,4 @@ CONFIG_MEM_HOTPLUG=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
+CONFIG_VMGENID=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 62575eb..36e654d 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -49,3 +49,4 @@ CONFIG_MEM_HOTPLUG=y
 CONFIG_XIO3130=y
 CONFIG_IOH3420=y
 CONFIG_I82801B11=y
+CONFIG_VMGENID=y
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b71e942..784e23d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -112,6 +112,7 @@ typedef struct AcpiMiscInfo {
     unsigned dsdt_size;
     uint16_t pvpanic_port;
     uint16_t applesmc_io_base;
+    uint64_t vm_generation_addr;
 } AcpiMiscInfo;
 
 typedef struct AcpiBuildPciBusHotplugState {
@@ -238,6 +239,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
     info->tpm_version = tpm_get_version();
     info->pvpanic_port = pvpanic_port();
     info->applesmc_io_base = applesmc_port();
+    info->vm_generation_addr = vm_generation_addr();
 }
 
 /*
@@ -1128,6 +1130,36 @@ build_ssdt(GArray *table_data, GArray *linker,
     }
 
     sb_scope = aml_scope("\\_SB");
+
+    if (misc->vm_generation_addr) {
+        dev = aml_device("VMGI");
+        aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+        aml_append(dev,
+            aml_name_decl("_CID", aml_string("VM_Gen_Counter")));
+        aml_append(dev,
+            aml_name_decl("_DDN", aml_string("VM_Gen_Counter")));
+
+        method = aml_method("ADDR", 0);
+        pkg = aml_package(2);
+        aml_append(pkg, aml_int(misc->vm_generation_addr & 0xffffffff));
+        aml_append(pkg, aml_int(misc->vm_generation_addr >> 32));
+        aml_append(method, aml_store(pkg, aml_local(0)));
+        aml_append(method, aml_return(aml_local(0)));
+        aml_append(dev, method);
+
+        aml_append(sb_scope, dev);
+        aml_append(ssdt, sb_scope);
+
+        scope = aml_scope("\\_GPE");
+
+        method = aml_method("_E00", 0);
+        aml_append(method,
+            aml_notify(aml_name("\\_SB.VMGI"), aml_int(0x80)));
+
+        aml_append(scope, method);
+        aml_append(ssdt, scope);
+    }
+
     {
         /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
         dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..3db11de 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
+obj-$(CONFIG_VMGENID) += vmgenid.o
diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
new file mode 100644
index 0000000..4484952
--- /dev/null
+++ b/hw/misc/vmgenid.c
@@ -0,0 +1,140 @@
+/*
+ *  Virtual Machine Generation ID Device
+ *
+ *  Copyright (C) 2015 Red Hat Inc.
+ *
+ *  Authors: Gal Hammer <ghammer@redhat.com>
+ *
+ * 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 "hw/i386/pc.h"
+#include "hw/acpi/acpi_dev_interface.h"
+
+#define VMGENID_DEVICE "vmgenid"
+
+/* Use the memory address which follows HPET for no special reason. */
+#define VMGENID_DEFAULT_ADDRESS 0xfedf0000
+
+#define PROPERTY_ADDR "addr"
+#define PROPERTY_UUID "uuid"
+
+#define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj), VMGENID_DEVICE)
+
+typedef struct VmGenIdState {
+    DeviceState parent_obj;
+    MemoryRegion iomem;
+    uint64_t addr;
+    uint8_t guid[16];
+    bool guid_set;
+} VmGenIdState;
+
+uint64_t vm_generation_addr(void)
+{
+    Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL);
+    VmGenIdState *s = VMGENID(obj);
+
+    if (!obj) {
+        return 0;
+    }
+    return s->addr;
+}
+
+static void update_guest(VmGenIdState *s, bool notify)
+{
+    void *ptr = memory_region_get_ram_ptr(&s->iomem);
+    Object *acpi_obj;
+
+    memcpy(ptr, &s->guid, sizeof(s->guid));
+    memory_region_set_dirty(&s->iomem, 0, sizeof(s->guid));
+
+    if (notify) {
+        acpi_obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL);
+        if (acpi_obj) {
+           AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(acpi_obj);
+           AcpiDeviceIf *adev = ACPI_DEVICE_IF(acpi_obj);
+
+           adevc->vm_generation_id_changed(adev);
+        }
+     }
+}
+
+static void vmgenid_set_uuid(Object *obj, const char *value, Error **errp)
+{
+    VmGenIdState *s = VMGENID(obj);
+    bool first_set = !s->guid_set;
+
+    if (qemu_uuid_parse(value, s->guid) < 0) {
+        error_setg(errp, "Fail to parse UUID string.");
+        return;
+    }
+    s->guid_set = true;
+
+    /* Skip the acpi notification when setting the vm generation id for the
+     * first time. This is done because in a q35 machine the gpe register is
+     * allocated after the device is initialized.
+     */
+    update_guest(s, !first_set);
+}
+
+static void vmgenid_realize(DeviceState *qdev, Error **errp)
+{
+    VmGenIdState *s = VMGENID(qdev);
+
+    if (!s->guid_set) {
+        error_setg(errp, "Missing virtual machine generation ID.");
+        return;
+    }
+
+    if (s->addr % 8 != 0) {
+        error_setg(errp, "Address must be 8-byte aligned.");
+        return;
+    }
+
+    vmstate_register_ram(&s->iomem, DEVICE(s));
+    memory_region_add_subregion(get_system_memory(), s->addr, &s->iomem);
+}
+
+static void vmgenid_init(Object *obj)
+{
+    VmGenIdState *s = VMGENID(obj);
+
+    object_property_add_str(obj, PROPERTY_UUID, NULL, vmgenid_set_uuid, NULL);
+
+    memory_region_init_ram(&s->iomem, OBJECT(s), "vm-generation-id", 0x1000,
+        &error_abort);
+}
+
+static Property vmgenid_properties[] = {
+    DEFINE_PROP_UINT64(PROPERTY_ADDR, VmGenIdState, addr,
+                       VMGENID_DEFAULT_ADDRESS),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vmgenid_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = vmgenid_realize;
+    dc->props = vmgenid_properties;
+    dc->hotpluggable = false;
+
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo vmgenid_device_info = {
+    .name          = VMGENID_DEVICE,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(VmGenIdState),
+    .instance_init = vmgenid_init,
+    .class_init    = vmgenid_class_init,
+};
+
+static void vmgenid_register_types(void)
+{
+    type_register_static(&vmgenid_device_info);
+}
+
+type_init(vmgenid_register_types)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 86c5651..9492e32 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -281,6 +281,9 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
 /* pvpanic.c */
 uint16_t pvpanic_port(void);
 
+/* vmgenid.c */
+uint64_t vm_generation_addr(void);
+
 /* e820 types */
 #define E820_RAM        1
 #define E820_RESERVED   2
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device
  2015-06-16 14:10 [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID Gal Hammer
                   ` (2 preceding siblings ...)
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device Gal Hammer
@ 2015-06-16 14:11 ` Gal Hammer
  2015-06-16 23:41   ` Igor Mammedov
  3 siblings, 1 reply; 11+ messages in thread
From: Gal Hammer @ 2015-06-16 14:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gal Hammer, pbonzini, imammedo, mst

Signed-off-by: Gal Hammer <ghammer@redhat.com>
---
 tests/Makefile       |  2 ++
 tests/vmgenid-test.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 tests/vmgenid-test.c

diff --git a/tests/Makefile b/tests/Makefile
index c5e4744..3608068 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -177,6 +177,7 @@ check-qtest-i386-y += tests/pc-cpu-test$(EXESUF)
 check-qtest-i386-y += tests/q35-test$(EXESUF)
 gcov-files-i386-y += hw/pci-host/q35.c
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
+check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -396,6 +397,7 @@ tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(block-obj-y) libqemuutil.a libqemustub.a
+tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o
 
 ifeq ($(CONFIG_POSIX),y)
 LIBS += -lutil
diff --git a/tests/vmgenid-test.c b/tests/vmgenid-test.c
new file mode 100644
index 0000000..dad1f1b
--- /dev/null
+++ b/tests/vmgenid-test.c
@@ -0,0 +1,44 @@
+/*
+ * QTest testcase for VM Generation ID
+ *
+ * Copyright (c) 2015 Red Hat, 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.
+ */
+
+#include <string.h>
+#include "libqtest.h"
+
+static void vmgenid_test(void)
+{
+    static const uint8_t expected[16] = {
+        0x32, 0x4e, 0x6e, 0xaf, 0xd1, 0xd1, 0x4b, 0xf6,
+        0xbf, 0x41, 0xb9, 0xbb, 0x6c, 0x91, 0xfb, 0x87
+    };
+    uint8_t guid[16];
+    uint32_t i;
+
+    /* Skip the ACPI ADDR method and read the GUID directly from memory. */
+    for (i = 0; i < 16; i++) {
+        guid[i] = readb(0xfedf0000 + i);
+    }
+
+    g_assert_cmpuint(sizeof(guid), ==, sizeof(expected));
+    g_assert(memcmp(guid, expected, sizeof(guid)) == 0);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+    qtest_add_func("/vmgenid/vmgenid", vmgenid_test);
+
+    qtest_start("-device vmgenid,uuid=324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87");
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description Gal Hammer
@ 2015-06-16 15:22   ` Eric Blake
  0 siblings, 0 replies; 11+ messages in thread
From: Eric Blake @ 2015-06-16 15:22 UTC (permalink / raw)
  To: Gal Hammer, qemu-devel; +Cc: pbonzini, imammedo, mst

[-- Attachment #1: Type: text/plain, Size: 2759 bytes --]

On 06/16/2015 08:11 AM, Gal Hammer wrote:
> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---
>  docs/specs/vmgenid.txt | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 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..d06977a
> --- /dev/null
> +++ b/docs/specs/vmgenid.txt
> @@ -0,0 +1,33 @@
> +VIRTUAL MACHINE GENERATION ID
> +=============================
> +
> +Copyright (C) 2015 Red Hat, Inc.
> +
> +This work is licensed under the terms of the GNU GPL, version 2 or later.
> +See the COPYING file in the top-level directory.
> +
> +===
> +
> +The VM generation ID (vmgenid) device is an emulated device which
> +is expected to exposes a 128-bit, cryptographically random, integer value

s/exposes/expose/

> +identifier, provided by a management system (It is NOT in the device's
> +responsibilty to ensure that the value is cryptographically random).

s/responsibilty/responsibility/

> +
> +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).
> +
> +This is specified on the web at: http://go.microsoft.com/fwlink/?LinkId=260709
> +

Hopefully the link doesn't go stale too soon (when the cover page states
the same address, and the disclaimer "Information ... in this document,
URL and other Internet website references, may change without notice").
 On the other hand, the document is fairly loosely licensed ("You may
copy and use this document for your internal, reference purposes") even
if done in a non-free .docx format.  Do we need to hedge our bets and
save a copy of it in the qemu wiki?

> +---
> +
> +The vmgenid device is a device with the following ACPI ID: "QEMU0002".
> +
> +It has two properties:
> +
> +uuid - The virtual machine generation ID (A required UUID string)
> +addr - The uuid memory location (A 64-bit address, defaults to 0xfedf0000)
> +
> +According to the specification, any change to the GUID executes an
> +ACPI notification. The vmgenid device triggers the GPE._E00 which
> +executes the ACPI Notify operation.

Still would be nice for this document to contain sample QMP commands for
getting at the QOM object necessary for changing the id exposed to the
guest via this device (that is, not only talk about how the device is
implemented in the ACPI view of the guest, but also how the device is
managed from the application driving qemu).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method Gal Hammer
@ 2015-06-16 15:23   ` Eric Blake
  2015-06-16 22:55   ` Igor Mammedov
  1 sibling, 0 replies; 11+ messages in thread
From: Eric Blake @ 2015-06-16 15:23 UTC (permalink / raw)
  To: Gal Hammer, qemu-devel; +Cc: pbonzini, imammedo, mst

[-- Attachment #1: Type: text/plain, Size: 753 bytes --]

On 06/16/2015 08:11 AM, Gal Hammer wrote:
> Add a new method to the AcpiDeviceIfClass interface. The new
> method sends an ACPI notfication when the VM generation id is

s/notfication/notification/

> changed.
> 
> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---

> +++ b/include/hw/acpi/acpi_dev_interface.h
> @@ -28,6 +28,9 @@ typedef struct AcpiDeviceIf {
>   * ospm_status: returns status of ACPI device objects, reported
>   *              via _OST method if device supports it.
>   *
> + * vm_generation_id_changed: notify the guest that it generation
> + *                           id was changed.

s/it/its/

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device Gal Hammer
@ 2015-06-16 22:52   ` Igor Mammedov
  2015-06-16 23:08   ` Igor Mammedov
  1 sibling, 0 replies; 11+ messages in thread
From: Igor Mammedov @ 2015-06-16 22:52 UTC (permalink / raw)
  To: Gal Hammer; +Cc: pbonzini, qemu-devel, mst

On Tue, 16 Jun 2015 17:11:02 +0300
Gal Hammer <ghammer@redhat.com> wrote:

> Based on Microsoft's specifications (paper can be downloaded from
> http://go.microsoft.com/fwlink/?LinkId=260709), add a device
> description to the SSDT ACPI table and its implementation.
> 
> The GUID is set using a global "vmgenid.uuid" parameter.
-device vmgenid,uuid=FOO
or
some QMP FOO

> 
> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---
>  default-configs/i386-softmmu.mak   |   1 +
>  default-configs/x86_64-softmmu.mak |   1 +
>  hw/i386/acpi-build.c               |  32 +++++++++
>  hw/misc/Makefile.objs              |   1 +
>  hw/misc/vmgenid.c                  | 140
> +++++++++++++++++++++++++++++++++++++
> include/hw/i386/pc.h               |   3 + 6 files changed, 178
> insertions(+) create mode 100644 hw/misc/vmgenid.c
> 
> diff --git a/default-configs/i386-softmmu.mak
> b/default-configs/i386-softmmu.mak index 91d602c..3c2fda8 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -48,3 +48,4 @@ CONFIG_MEM_HOTPLUG=y
>  CONFIG_XIO3130=y
>  CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
> +CONFIG_VMGENID=y
> diff --git a/default-configs/x86_64-softmmu.mak
> b/default-configs/x86_64-softmmu.mak index 62575eb..36e654d 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -49,3 +49,4 @@ CONFIG_MEM_HOTPLUG=y
>  CONFIG_XIO3130=y
>  CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
> +CONFIG_VMGENID=y
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index b71e942..784e23d 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -112,6 +112,7 @@ typedef struct AcpiMiscInfo {
>      unsigned dsdt_size;
>      uint16_t pvpanic_port;
>      uint16_t applesmc_io_base;
> +    uint64_t vm_generation_addr;
>  } AcpiMiscInfo;
>  
>  typedef struct AcpiBuildPciBusHotplugState {
> @@ -238,6 +239,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
>      info->tpm_version = tpm_get_version();
>      info->pvpanic_port = pvpanic_port();
>      info->applesmc_io_base = applesmc_port();
> +    info->vm_generation_addr = vm_generation_addr();
>  }
>  
>  /*
> @@ -1128,6 +1130,36 @@ build_ssdt(GArray *table_data, GArray *linker,
>      }
>  
>      sb_scope = aml_scope("\\_SB");
move ^^ inside of if(misc->vm_generation_addr) block

> +    if (misc->vm_generation_addr) {
like this:
+          sb_scope = aml_scope("\\_SB"); // <= scope comes
> +        dev = aml_device("VMGI");
...
> +
> +        aml_append(sb_scope, dev);
> +        aml_append(ssdt, sb_scope);
                                ^^^ scope goes away

here you've added sb_scope to ssdt and later it continues to be
extended with PCI0.PRES and other devices. it most likely will cause a
mess in the table.
Try to verify by running "make check" to see what changes you've added.


> +
> +        scope = aml_scope("\\_GPE");
> +
> +        method = aml_method("_E00", 0);
> +        aml_append(method,
> +            aml_notify(aml_name("\\_SB.VMGI"), aml_int(0x80)));
> +
> +        aml_append(scope, method);
> +        aml_append(ssdt, scope);
> +    }
leave original line as it was:
  sb_scope = aml_scope("\\_SB");
>      {
>          /* create PCI0.PRES device and its _CRS to reserve CPU
> hotplug MMIO */ dev = aml_device("PCI0."
> stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); diff --git
> a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index
> 4aa76ff..3db11de 100644 --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
>  
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
> +obj-$(CONFIG_VMGENID) += vmgenid.o
> diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
> new file mode 100644
> index 0000000..4484952
> --- /dev/null
> +++ b/hw/misc/vmgenid.c
> @@ -0,0 +1,140 @@
> +/*
> + *  Virtual Machine Generation ID Device
> + *
> + *  Copyright (C) 2015 Red Hat Inc.
> + *
> + *  Authors: Gal Hammer <ghammer@redhat.com>
> + *
> + * 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 "hw/i386/pc.h"
> +#include "hw/acpi/acpi_dev_interface.h"
> +
> +#define VMGENID_DEVICE "vmgenid"
> +
> +/* Use the memory address which follows HPET for no special reason.
> */ +#define VMGENID_DEFAULT_ADDRESS 0xfedf0000
> +
> +#define PROPERTY_ADDR "addr"
> +#define PROPERTY_UUID "uuid"
> +
> +#define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj),
> VMGENID_DEVICE) +
> +typedef struct VmGenIdState {
> +    DeviceState parent_obj;
> +    MemoryRegion iomem;
> +    uint64_t addr;
> +    uint8_t guid[16];
> +    bool guid_set;
> +} VmGenIdState;
> +
> +uint64_t vm_generation_addr(void)
> +{
> +    Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL);
> +    VmGenIdState *s = VMGENID(obj);
> +
> +    if (!obj) {
> +        return 0;
> +    }
> +    return s->addr;
> +}
> +
> +static void update_guest(VmGenIdState *s, bool notify)
> +{
> +    void *ptr = memory_region_get_ram_ptr(&s->iomem);
> +    Object *acpi_obj;
> +
> +    memcpy(ptr, &s->guid, sizeof(s->guid));
> +    memory_region_set_dirty(&s->iomem, 0, sizeof(s->guid));
> +
> +    if (notify) {
> +        acpi_obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF,
> NULL);
> +        if (acpi_obj) {
> +           AcpiDeviceIfClass *adevc =
> ACPI_DEVICE_IF_GET_CLASS(acpi_obj);
> +           AcpiDeviceIf *adev = ACPI_DEVICE_IF(acpi_obj);
> +
> +           adevc->vm_generation_id_changed(adev);
> +        }
else {
   error_setg(errp, "Not supported");
}

so mgmt would know that it's doing something wrong

> +     }
> +}
> +
> +static void vmgenid_set_uuid(Object *obj, const char *value, Error
> **errp) +{
> +    VmGenIdState *s = VMGENID(obj);
> +    bool first_set = !s->guid_set;
> +
> +    if (qemu_uuid_parse(value, s->guid) < 0) {
> +        error_setg(errp, "Fail to parse UUID string.");
> +        return;
> +    }
> +    s->guid_set = true;
> +
> +    /* Skip the acpi notification when setting the vm generation id
> for the
> +     * first time. This is done because in a q35 machine the gpe
> register is
> +     * allocated after the device is initialized.
which device is initialized, my thought was that all onboard devices
are initialised/realised first (including ICH9 with it's GPE register)
and only then -device CLI options are parsed.

> +     */
> +    update_guest(s, !first_set);
> +}
> +
> +static void vmgenid_realize(DeviceState *qdev, Error **errp)
> +{
> +    VmGenIdState *s = VMGENID(qdev);
> +
> +    if (!s->guid_set) {
> +        error_setg(errp, "Missing virtual machine generation ID.");
> +        return;
> +    }
> +
> +    if (s->addr % 8 != 0) {
> +        error_setg(errp, "Address must be 8-byte aligned.");
> +        return;
> +    }
> +
> +    vmstate_register_ram(&s->iomem, DEVICE(s));
> +    memory_region_add_subregion(get_system_memory(), s->addr,
> &s->iomem); +}
> +
> +static void vmgenid_init(Object *obj)
> +{
> +    VmGenIdState *s = VMGENID(obj);
> +
> +    object_property_add_str(obj, PROPERTY_UUID, NULL,
> vmgenid_set_uuid, NULL); +
> +    memory_region_init_ram(&s->iomem, OBJECT(s), "vm-generation-id",
There were concerns about using RAM since it's going to be in
migration stream as separate entry. Suggestion was to use
MMIO instead so replace memory_region_init_ram() with
memory_region_init_io()
and that also alleviates need in dirtying updated memory.
 

> 0x1000,
> +        &error_abort);
> +}
> +
> +static Property vmgenid_properties[] = {
> +    DEFINE_PROP_UINT64(PROPERTY_ADDR, VmGenIdState, addr,
> +                       VMGENID_DEFAULT_ADDRESS),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void vmgenid_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = vmgenid_realize;
> +    dc->props = vmgenid_properties;
> +    dc->hotpluggable = false;
> +
> +    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +}
> +
> +static const TypeInfo vmgenid_device_info = {
> +    .name          = VMGENID_DEVICE,
> +    .parent        = TYPE_DEVICE,
> +    .instance_size = sizeof(VmGenIdState),
> +    .instance_init = vmgenid_init,
> +    .class_init    = vmgenid_class_init,
> +};
> +
> +static void vmgenid_register_types(void)
> +{
> +    type_register_static(&vmgenid_device_info);
> +}
> +
> +type_init(vmgenid_register_types)
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 86c5651..9492e32 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -281,6 +281,9 @@ void pc_system_firmware_init(MemoryRegion
> *rom_memory, /* pvpanic.c */
>  uint16_t pvpanic_port(void);
>  
> +/* vmgenid.c */
> +uint64_t vm_generation_addr(void);
> +
>  /* e820 types */
>  #define E820_RAM        1
>  #define E820_RESERVED   2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method Gal Hammer
  2015-06-16 15:23   ` Eric Blake
@ 2015-06-16 22:55   ` Igor Mammedov
  1 sibling, 0 replies; 11+ messages in thread
From: Igor Mammedov @ 2015-06-16 22:55 UTC (permalink / raw)
  To: Gal Hammer; +Cc: pbonzini, qemu-devel, mst

On Tue, 16 Jun 2015 17:11:01 +0300
Gal Hammer <ghammer@redhat.com> wrote:

> Add a new method to the AcpiDeviceIfClass interface. The new
> method sends an ACPI notfication when the VM generation id is
> changed.
> 
> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---
>  hw/acpi/core.c                       | 8 ++++++++
>  hw/acpi/ich9.c                       | 8 ++++++++
>  hw/acpi/piix4.c                      | 8 ++++++++
>  hw/isa/lpc_ich9.c                    | 1 +
>  include/hw/acpi/acpi.h               | 2 ++
>  include/hw/acpi/acpi_dev_interface.h | 4 ++++
>  include/hw/acpi/ich9.h               | 2 ++
>  7 files changed, 33 insertions(+)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index 0f201d8..3c8d1eb 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -29,6 +29,8 @@
>  #include "qapi-visit.h"
>  #include "qapi-event.h"
>  
> +#define ACPI_VM_GENERATION_ID_CHANGED_STATUS 1
nowadays this should be a part of AcpiGPEStatusBits enum
 
> +
>  struct acpi_table_header {
>      uint16_t _length;         /* our length, not actual part of the
> hdr */ /* allows easier parsing for fw_cfg clients */
> @@ -703,3 +705,9 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq)
>                         (regs->pm1.evt.en &
> ACPI_BITMASK_TIMER_ENABLE) && !(pm1a_sts &
> ACPI_BITMASK_TIMER_STATUS)); }
> +
> +void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq irq)
> +{
> +    acpi_regs->gpe.sts[0] |= ACPI_VM_GENERATION_ID_CHANGED_STATUS;
> +    acpi_update_sci(acpi_regs, irq);
replace above 2 with acpi_send_gpe_event()

> +}
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 8a64ffb..cab1af7 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -429,3 +429,11 @@ void ich9_pm_ospm_status(AcpiDeviceIf *adev,
> ACPIOSTInfoList ***list) 
>      acpi_memory_ospm_status(&s->pm.acpi_memory_hotplug, list);
>  }
> +
> +void ich9_vm_generation_id_changed(AcpiDeviceIf *adev)
> +{
> +    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
> +    ICH9LPCPMRegs *pm = &s->pm;
> +
> +    acpi_vm_generation_id_changed(&pm->acpi_regs, pm->irq);
> +}
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index 3bd1d5a..101a13a 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -580,6 +580,13 @@ static void piix4_ospm_status(AcpiDeviceIf
> *adev, ACPIOSTInfoList ***list)
> acpi_memory_ospm_status(&s->acpi_memory_hotplug, list); }
>  
> +static void piix4_vm_generation_id_changed(AcpiDeviceIf *adev)
> +{
> +    PIIX4PMState *s = PIIX4_PM(adev);
> +
> +    acpi_vm_generation_id_changed(&s->ar, s->irq);
> +}
> +
>  static Property piix4_pm_properties[] = {
>      DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
>      DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState,
> disable_s3, 0), @@ -618,6 +625,7 @@ static void
> piix4_pm_class_init(ObjectClass *klass, void *data)
> hc->unplug_request = piix4_device_unplug_request_cb; hc->unplug =
> piix4_device_unplug_cb; adevc->ospm_status = piix4_ospm_status;
> +    adevc->vm_generation_id_changed = piix4_vm_generation_id_changed;
>  }
>  
>  static const TypeInfo piix4_pm_info = {
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index b3e0b1f..f240a3a 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -702,6 +702,7 @@ static void ich9_lpc_class_init(ObjectClass
> *klass, void *data) hc->unplug_request =
> ich9_device_unplug_request_cb; hc->unplug = ich9_device_unplug_cb;
>      adevc->ospm_status = ich9_pm_ospm_status;
> +    adevc->vm_generation_id_changed = ich9_vm_generation_id_changed;
>  }
>  
>  static const TypeInfo ich9_lpc_info = {
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index b20bd55..1a4caf2 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -196,4 +196,6 @@ unsigned acpi_table_len(void *current);
>  void acpi_table_add(const QemuOpts *opts, Error **errp);
>  void acpi_table_add_builtin(const QemuOpts *opts, Error **errp);
>  
> +void acpi_vm_generation_id_changed(ACPIREGS *acpi_regs, qemu_irq
> irq); +
>  #endif /* !QEMU_HW_ACPI_H */
> diff --git a/include/hw/acpi/acpi_dev_interface.h
> b/include/hw/acpi/acpi_dev_interface.h index f245f8d..757ce60 100644
> --- a/include/hw/acpi/acpi_dev_interface.h
> +++ b/include/hw/acpi/acpi_dev_interface.h
> @@ -28,6 +28,9 @@ typedef struct AcpiDeviceIf {
>   * ospm_status: returns status of ACPI device objects, reported
>   *              via _OST method if device supports it.
>   *
> + * vm_generation_id_changed: notify the guest that it generation
> + *                           id was changed.
> + *
>   * Interface is designed for providing unified interface
>   * to generic ACPI functionality that could be used without
>   * knowledge about internals of actual device that implements
> @@ -39,5 +42,6 @@ typedef struct AcpiDeviceIfClass {
>  
>      /* <public> */
>      void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
> +    void (*vm_generation_id_changed)(AcpiDeviceIf *adev);
>  } AcpiDeviceIfClass;
>  #endif
> diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> index 77cc65c..497c004 100644
> --- a/include/hw/acpi/ich9.h
> +++ b/include/hw/acpi/ich9.h
> @@ -70,4 +70,6 @@ void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm,
> DeviceState *dev, Error **errp);
>  
>  void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList
> ***list); +
> +void ich9_vm_generation_id_changed(AcpiDeviceIf *adev);
>  #endif /* HW_ACPI_ICH9_H */

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device Gal Hammer
  2015-06-16 22:52   ` Igor Mammedov
@ 2015-06-16 23:08   ` Igor Mammedov
  1 sibling, 0 replies; 11+ messages in thread
From: Igor Mammedov @ 2015-06-16 23:08 UTC (permalink / raw)
  To: Gal Hammer; +Cc: pbonzini, qemu-devel, mst

On Tue, 16 Jun 2015 17:11:02 +0300
Gal Hammer <ghammer@redhat.com> wrote:

> Based on Microsoft's specifications (paper can be downloaded from
> http://go.microsoft.com/fwlink/?LinkId=260709), add a device
> description to the SSDT ACPI table and its implementation.
> 
> The GUID is set using a global "vmgenid.uuid" parameter.
> 
> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---
>  default-configs/i386-softmmu.mak   |   1 +
>  default-configs/x86_64-softmmu.mak |   1 +
>  hw/i386/acpi-build.c               |  32 +++++++++
>  hw/misc/Makefile.objs              |   1 +
>  hw/misc/vmgenid.c                  | 140
> +++++++++++++++++++++++++++++++++++++
> include/hw/i386/pc.h               |   3 + 6 files changed, 178
> insertions(+) create mode 100644 hw/misc/vmgenid.c
> 
> diff --git a/default-configs/i386-softmmu.mak
> b/default-configs/i386-softmmu.mak index 91d602c..3c2fda8 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -48,3 +48,4 @@ CONFIG_MEM_HOTPLUG=y
>  CONFIG_XIO3130=y
>  CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
> +CONFIG_VMGENID=y
> diff --git a/default-configs/x86_64-softmmu.mak
> b/default-configs/x86_64-softmmu.mak index 62575eb..36e654d 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -49,3 +49,4 @@ CONFIG_MEM_HOTPLUG=y
>  CONFIG_XIO3130=y
>  CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
> +CONFIG_VMGENID=y
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index b71e942..784e23d 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -112,6 +112,7 @@ typedef struct AcpiMiscInfo {
>      unsigned dsdt_size;
>      uint16_t pvpanic_port;
>      uint16_t applesmc_io_base;
> +    uint64_t vm_generation_addr;
>  } AcpiMiscInfo;
>  
>  typedef struct AcpiBuildPciBusHotplugState {
> @@ -238,6 +239,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
>      info->tpm_version = tpm_get_version();
>      info->pvpanic_port = pvpanic_port();
>      info->applesmc_io_base = applesmc_port();
> +    info->vm_generation_addr = vm_generation_addr();
>  }
>  
>  /*
> @@ -1128,6 +1130,36 @@ build_ssdt(GArray *table_data, GArray *linker,
>      }
>  
>      sb_scope = aml_scope("\\_SB");
> +
> +    if (misc->vm_generation_addr) {
> +        dev = aml_device("VMGI");
> +        aml_append(dev, aml_name_decl("_HID",
> aml_string("QEMU0002")));
> +        aml_append(dev,
> +            aml_name_decl("_CID", aml_string("VM_Gen_Counter")));
> +        aml_append(dev,
> +            aml_name_decl("_DDN", aml_string("VM_Gen_Counter")));
> +
> +        method = aml_method("ADDR", 0);
> +        pkg = aml_package(2);
> +        aml_append(pkg, aml_int(misc->vm_generation_addr &
> 0xffffffff));
> +        aml_append(pkg, aml_int(misc->vm_generation_addr >> 32));
> +        aml_append(method, aml_store(pkg, aml_local(0)));
> +        aml_append(method, aml_return(aml_local(0)));
> +        aml_append(dev, method);
> +
> +        aml_append(sb_scope, dev);
> +        aml_append(ssdt, sb_scope);
> +
> +        scope = aml_scope("\\_GPE");
> +
> +        method = aml_method("_E00", 0);
> +        aml_append(method,
> +            aml_notify(aml_name("\\_SB.VMGI"), aml_int(0x80)));
> +
> +        aml_append(scope, method);
> +        aml_append(ssdt, scope);
> +    }
> +
>      {
>          /* create PCI0.PRES device and its _CRS to reserve CPU
> hotplug MMIO */ dev = aml_device("PCI0."
> stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); diff --git
> a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index
> 4aa76ff..3db11de 100644 --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -40,3 +40,4 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
>  
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
> +obj-$(CONFIG_VMGENID) += vmgenid.o
> diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
> new file mode 100644
> index 0000000..4484952
> --- /dev/null
> +++ b/hw/misc/vmgenid.c
> @@ -0,0 +1,140 @@
> +/*
> + *  Virtual Machine Generation ID Device
> + *
> + *  Copyright (C) 2015 Red Hat Inc.
> + *
> + *  Authors: Gal Hammer <ghammer@redhat.com>
> + *
> + * 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 "hw/i386/pc.h"
> +#include "hw/acpi/acpi_dev_interface.h"
> +
> +#define VMGENID_DEVICE "vmgenid"
> +
> +/* Use the memory address which follows HPET for no special reason.
> */ +#define VMGENID_DEFAULT_ADDRESS 0xfedf0000
should be somwhere in target specific in header, I'd suggest i386/pc.h


[...]

> +
> +    vmstate_register_ram(&s->iomem, DEVICE(s));
with MMIO it ^^^ won't be needed

> +    memory_region_add_subregion(get_system_memory(), s->addr,
> &s->iomem); +}
that should be in pc_machine_device_plug_cb() along the lines:

} else if (object_dynamic_cast(OBJECT(dev), TYPE_VMGENID_DEVICE)) {
    VMGENID_DEVICE_CLASS *dc = GET_FOO_CLASS(dev)
    addr = get_property(dev, "addr");
    memory_region_add_subregion(get_system_memory(),
       addr ? addr : VMGENID_DEFAULT_ADDRESS,
       dc->get_memory_region())
}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device
  2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device Gal Hammer
@ 2015-06-16 23:41   ` Igor Mammedov
  0 siblings, 0 replies; 11+ messages in thread
From: Igor Mammedov @ 2015-06-16 23:41 UTC (permalink / raw)
  To: Gal Hammer; +Cc: pbonzini, qemu-devel, mst

On Tue, 16 Jun 2015 17:11:03 +0300
Gal Hammer <ghammer@redhat.com> wrote:

> Signed-off-by: Gal Hammer <ghammer@redhat.com>
> ---
>  tests/Makefile       |  2 ++
>  tests/vmgenid-test.c | 44
> ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46
> insertions(+) create mode 100644 tests/vmgenid-test.c
> 
> diff --git a/tests/Makefile b/tests/Makefile
> index c5e4744..3608068 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -177,6 +177,7 @@ check-qtest-i386-y += tests/pc-cpu-test$(EXESUF)
>  check-qtest-i386-y += tests/q35-test$(EXESUF)
>  gcov-files-i386-y += hw/pci-host/q35.c
>  check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
> +check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
>  check-qtest-x86_64-y = $(check-qtest-i386-y)
>  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
>  gcov-files-x86_64-y = $(subst
> i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) @@ -396,6 +397,7
> @@ tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o
> qemu-char.o qemu-timer.o
> tests/qemu-iotests/socket_scm_helper$(EXESUF):
> tests/qemu-iotests/socket_scm_helper.o tests/test-qemu-opts$(EXESUF):
> tests/test-qemu-opts.o libqemuutil.a libqemustub.a
> tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o
> $(block-obj-y) libqemuutil.a libqemustub.a
> +tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o ifeq
> ($(CONFIG_POSIX),y) LIBS += -lutil diff --git a/tests/vmgenid-test.c
> b/tests/vmgenid-test.c new file mode 100644 index 0000000..dad1f1b
> --- /dev/null
> +++ b/tests/vmgenid-test.c
> @@ -0,0 +1,44 @@
> +/*
> + * QTest testcase for VM Generation ID
> + *
> + * Copyright (c) 2015 Red Hat, 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.
> + */
> +
> +#include <string.h>
> +#include "libqtest.h"
> +
> +static void vmgenid_test(void)
> +{
> +    static const uint8_t expected[16] = {
> +        0x32, 0x4e, 0x6e, 0xaf, 0xd1, 0xd1, 0x4b, 0xf6,
> +        0xbf, 0x41, 0xb9, 0xbb, 0x6c, 0x91, 0xfb, 0x87
> +    };
> +    uint8_t guid[16];
> +    uint32_t i;
> +
> +    /* Skip the ACPI ADDR method and read the GUID directly from
> memory. */
> +    for (i = 0; i < 16; i++) {
> +        guid[i] = readb(0xfedf0000 + i);
get address from vmgidid.addr property

> +    }
> +
> +    g_assert_cmpuint(sizeof(guid), ==, sizeof(expected));
> +    g_assert(memcmp(guid, expected, sizeof(guid)) == 0);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    int ret;
> +
> +    g_test_init(&argc, &argv, NULL);
> +    qtest_add_func("/vmgenid/vmgenid", vmgenid_test);
> +
> +    qtest_start("-device
> vmgenid,uuid=324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87");
add case for non default addr value,

BTW if board would use default mapping addr then it should also set
vmgenid.addr to it so that introspection tools would see
actual mapped addr. 

> +    ret = g_test_run();
> +
> +    qtest_end();
> +
> +    return ret;
> +}

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-06-16 23:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-16 14:10 [Qemu-devel] [PATCH V16 0/4] Virtual Machine Generation ID Gal Hammer
2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 1/4] docs: vm generation id device's description Gal Hammer
2015-06-16 15:22   ` Eric Blake
2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 2/4] acpi: add a vm_generation_id_changed method Gal Hammer
2015-06-16 15:23   ` Eric Blake
2015-06-16 22:55   ` Igor Mammedov
2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 3/4] i386: add a Virtual Machine Generation ID device Gal Hammer
2015-06-16 22:52   ` Igor Mammedov
2015-06-16 23:08   ` Igor Mammedov
2015-06-16 14:11 ` [Qemu-devel] [PATCH V16 4/4] tests: add a unit test for the vmgenid device Gal Hammer
2015-06-16 23:41   ` Igor Mammedov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.