All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v18 0/9]
@ 2016-01-22 13:20 Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 1/9] acpi: extend ACPI interface to provide access to ACPI registers and SCI irq Igor Mammedov
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

Changes since v17:
  - make BAR prefetchable to meet cached req of MS spec
  - rename UUID/uuid to GUID/guid across series to match spec
  - qmp: add new GuidInfo type and use it instead of UuidInfo
  - tests: fail if test is timed out when waitng for address
Changes since v14:
  - statically reserve used BAR resources in SSDT, so
    that Windows won't claim them during PCI rebalancing
  - support VGID page in high mem in addition to low mem
  - add QMP/HMP interfaces to get/set VM Generation ID
  - do not consume a PCI slot by default and attach
    vmgenid device as a function of multifuction
    ISA bridge.
  - allow only one vmgenid device instance

It's respin of v14* series which uses a PCI BAR to map
VGID page in guest AS.

Tested with WS2012R2x64, older Windows versions which don't
support vmgenid boot fine but show unknown device
which is expected.

Git tree for testing:
https://github.com/imammedo/qemu.git vmgenid_v18

* v14, https://lists.gnu.org/archive/html/qemu-devel/2015-03/msg00530.html

Gal Hammer (1):
  docs: vm generation id device's description

Igor Mammedov (8):
  acpi: extend ACPI interface to provide access to ACPI registers and
    SCI irq
  pc: add a Virtual Machine Generation ID device
  tests: add a unit test for the vmgenid device.
  qmp/hmp: add query-vm-generation-id and 'info vm-generation-id'
    commands
  qmp/hmp: add set-vm-generation-id commands
  add MachineClass->default_props for setting default device properties
  pc: put PIIX3 in slot 1 explicitly and cleanup functions assignment
  pc/q53: by default put vmgenid device as an function of ISA bridge

 default-configs/i386-softmmu.mak     |   1 +
 default-configs/x86_64-softmmu.mak   |   1 +
 docs/specs/pci-ids.txt               |   1 +
 docs/specs/vmgenid.txt               |  36 +++++++
 hmp-commands-info.hx                 |  13 +++
 hmp-commands.hx                      |  13 +++
 hmp.c                                |  21 ++++
 hmp.h                                |   2 +
 hw/acpi/piix4.c                      |  17 ++++
 hw/i386/acpi-build.c                 |  56 ++++++++++-
 hw/i386/pc_piix.c                    |  29 ++++--
 hw/i386/pc_q35.c                     |  12 +++
 hw/isa/lpc_ich9.c                    |  16 +++
 hw/isa/vt82c686.c                    |  19 ++++
 hw/misc/Makefile.objs                |   1 +
 hw/misc/vmgenid.c                    | 185 +++++++++++++++++++++++++++++++++++
 hw/pci-host/piix.c                   |   9 +-
 include/hw/acpi/acpi.h               |   1 +
 include/hw/acpi/acpi_dev_interface.h |   9 ++
 include/hw/boards.h                  |   1 +
 include/hw/i386/ich9.h               |   3 +-
 include/hw/i386/pc.h                 |   9 +-
 include/hw/misc/vmgenid.h            |  27 +++++
 include/hw/pci/pci.h                 |   1 +
 qapi-schema.json                     |  31 ++++++
 qmp-commands.hx                      |  41 ++++++++
 stubs/Makefile.objs                  |   1 +
 stubs/vmgenid.c                      |  13 +++
 tests/Makefile                       |   2 +
 tests/vmgenid-test.c                 |  93 ++++++++++++++++++
 vl.c                                 |   4 +
 31 files changed, 652 insertions(+), 16 deletions(-)
 create mode 100644 docs/specs/vmgenid.txt
 create mode 100644 hw/misc/vmgenid.c
 create mode 100644 include/hw/misc/vmgenid.h
 create mode 100644 stubs/vmgenid.c
 create mode 100644 tests/vmgenid-test.c

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 1/9] acpi: extend ACPI interface to provide access to ACPI registers and SCI irq
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 2/9] docs: vm generation id device's description Igor Mammedov
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

so that we don't have to always add proxy wrappers in piix4pm/ich9
to access ACPI regs and SCI kept in piix4pm/lcp_ich9 devices
and call acpi_foo() API directly.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c                      | 17 +++++++++++++++++
 hw/isa/lpc_ich9.c                    | 16 ++++++++++++++++
 hw/isa/vt82c686.c                    | 19 +++++++++++++++++++
 include/hw/acpi/acpi.h               |  1 +
 include/hw/acpi/acpi_dev_interface.h |  9 +++++++++
 5 files changed, 62 insertions(+)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 2cd2fee..5e29be4 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -583,6 +583,21 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
     acpi_memory_ospm_status(&s->acpi_memory_hotplug, list);
 }
 
+static ACPIREGS *piix4_acpi_regs(AcpiDeviceIf *adev)
+{
+    PIIX4PMState *s = PIIX4_PM(adev);
+
+    return &s->ar;
+}
+
+static qemu_irq piix4_acpi_irq(AcpiDeviceIf *adev)
+{
+    PIIX4PMState *s = PIIX4_PM(adev);
+
+    return 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),
@@ -621,6 +636,8 @@ 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->regs = piix4_acpi_regs;
+    adevc->sci = piix4_acpi_irq;
 }
 
 static const TypeInfo piix4_pm_info = {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index ed9907d..9d60caa 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -700,6 +700,20 @@ static Property ich9_lpc_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static ACPIREGS *ich9_acpi_regs(AcpiDeviceIf *adev)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
+
+    return &s->pm.acpi_regs;
+}
+
+static qemu_irq ich9_acpi_irq(AcpiDeviceIf *adev)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
+
+    return s->pm.irq;
+}
+
 static void ich9_lpc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -727,6 +741,8 @@ 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->regs = ich9_acpi_regs;
+    adevc->sci = ich9_acpi_irq;
 }
 
 static const TypeInfo ich9_lpc_info = {
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 6c2190b..58707d4 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -391,6 +391,18 @@ I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smb.smbus;
 }
 
+static ACPIREGS *via_pm_acpi_regs(AcpiDeviceIf *adev)
+{
+    VT686PMState *s = VT82C686B_PM_DEVICE(adev);
+
+    return &s->ar;
+}
+
+static qemu_irq via_pm_acpi_irq(AcpiDeviceIf *adev)
+{
+    return NULL;
+}
+
 static Property via_pm_properties[] = {
     DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
     DEFINE_PROP_END_OF_LIST(),
@@ -400,6 +412,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass);
 
     k->realize = vt82c686b_pm_realize;
     k->config_write = pm_write_config;
@@ -411,6 +424,8 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
     dc->vmsd = &vmstate_acpi;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->props = via_pm_properties;
+    adevc->regs = via_pm_acpi_regs;
+    adevc->sci = via_pm_acpi_irq;
 }
 
 static const TypeInfo via_pm_info = {
@@ -418,6 +433,10 @@ static const TypeInfo via_pm_info = {
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(VT686PMState),
     .class_init    = via_pm_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_ACPI_DEVICE_IF },
+        { }
+    },
 };
 
 static const VMStateDescription vmstate_via = {
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index b20bd55..3fb6399 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -25,6 +25,7 @@
 #include "qemu/option.h"
 #include "exec/memory.h"
 #include "hw/irq.h"
+#include "hw/acpi/acpi_dev_interface.h"
 
 /*
  * current device naming scheme supports up to 256 memory devices
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index f245f8d..e3f1bad 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -3,6 +3,9 @@
 
 #include "qom/object.h"
 #include "qapi-types.h"
+#include "hw/irq.h"
+
+typedef struct ACPIREGS ACPIREGS;
 
 #define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
 
@@ -28,6 +31,10 @@ typedef struct AcpiDeviceIf {
  * ospm_status: returns status of ACPI device objects, reported
  *              via _OST method if device supports it.
  *
+ * regs: returns pointer to ACPI registers block
+ *
+ * sci: return pointer to IRQ object associated with SCI
+ *
  * 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 +46,7 @@ typedef struct AcpiDeviceIfClass {
 
     /* <public> */
     void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
+    ACPIREGS *(*regs)(AcpiDeviceIf *adev);
+    qemu_irq (*sci)(AcpiDeviceIf *adev);
 } AcpiDeviceIfClass;
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 2/9] docs: vm generation id device's description
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 1/9] acpi: extend ACPI interface to provide access to ACPI registers and SCI irq Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 3/9] pc: add a Virtual Machine Generation ID device Igor Mammedov
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

From: Gal Hammer <ghammer@redhat.com>

Signed-off-by: Gal Hammer <ghammer@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 docs/specs/vmgenid.txt | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 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..462d17f
--- /dev/null
+++ b/docs/specs/vmgenid.txt
@@ -0,0 +1,36 @@
+VIRTUAL MACHINE GENERATION ID
+=============================
+
+Copyright (C) 2016 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
+exposes a 128-bit, cryptographically random, integer value identifier.
+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 PCI device with the following ACPI ID: "QEMU0003".
+
+The device has a "vmgenid.guid" property, which can be set using
+the command line argument or the QMP interface.
+For example:
+QEMU  -device vmgenid,id=FOO,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
+
+Or to change guid in runtime use:
+ qom-set "/machine/peripheral/FOO.guid" "124e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
+
+According to the specification, any change to the GUID executes an
+ACPI notification. The vmgenid device triggers the \_GPE._E00 handler
+which executes the ACPI Notify operation.
+
+Although not specified in Microsoft's document, it is assumed that the
+device is expected to use the little-endian system.
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 3/9] pc: add a Virtual Machine Generation ID device
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 1/9] acpi: extend ACPI interface to provide access to ACPI registers and SCI irq Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 2/9] docs: vm generation id device's description Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 4/9] tests: add a unit test for the vmgenid device Igor Mammedov
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

Based on Microsoft's specifications (paper can be
downloaded from http://go.microsoft.com/fwlink/?LinkId=260709,
easily found by "Virtual Machine Generation ID" keywords),
add a PCI device with corresponding description in
SSDT ACPI table.

The GUID is set using "vmgenid.guid" property or
a corresponding HMP/QMP command.

Example of using vmgenid device:
 -device vmgenid,id=FOO,guid="324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"

'vmgenid' device initialization flow is as following:
 1. vmgenid has RAM BAR registered with size of GUID buffer
 2. BIOS initializes PCI devices and it maps BAR in PCI hole
 3. BIOS reads ACPI tables from QEMU, at that moment tables
    are generated with \_SB.VMGI.ADDR constant pointing to
    GPA where BIOS's mapped vmgenid's BAR earlier

Note:
This implementation uses PCI class 0x0500 code for vmgenid device,
that is marked as NO_DRV in Windows's machine.inf.
Testing various Windows versions showed that, OS
doesn't touch nor checks for resource conflicts
for such PCI devices.
There was concern that during PCI rebalancing, OS
could reprogram the BAR at other place, which would
leave VGEN.ADDR pointing to the old (no more valid)
address.
However testing showed that Windows does rebalancing
only for PCI device that have a driver attached
and completely ignores NO_DRV class of devices.
Which in turn creates a problem where OS could remap
one of PCI devices(with driver) over BAR used by
a driver-less PCI device.
Statically declaring used memory range as VGEN._CRS
makes OS to honor resource reservation and an ignored
BAR range is not longer touched during PCI rebalancing.

Signed-off-by: Gal Hammer <ghammer@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
changes since 17:
  - small fixups suggested in v14 review by Michael S. Tsirkin" <mst@redhat.com>
  - make BAR prefetchable to make region cached as per MS spec
  - s/uuid/guid/ to match spec
changes since 14:
  - reserve BAR resources so that Windows won't touch it
    during PCI rebalancing - "Michael S. Tsirkin" <mst@redhat.com>
  - ACPI: split VGEN device of PCI device descriptor
    and place it at PCI0 scope, so that won't be need trace its
    location on PCI buses. - "Michael S. Tsirkin" <mst@redhat.com>
  - permit only one vmgenid to be created
  - enable BAR be mapped above 4Gb if it can't be mapped at low mem
---
 default-configs/i386-softmmu.mak   |   1 +
 default-configs/x86_64-softmmu.mak |   1 +
 docs/specs/pci-ids.txt             |   1 +
 hw/i386/acpi-build.c               |  56 +++++++++++++-
 hw/misc/Makefile.objs              |   1 +
 hw/misc/vmgenid.c                  | 154 +++++++++++++++++++++++++++++++++++++
 include/hw/misc/vmgenid.h          |  27 +++++++
 include/hw/pci/pci.h               |   1 +
 8 files changed, 240 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/vmgenid.c
 create mode 100644 include/hw/misc/vmgenid.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index b177e52..6402439 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -51,6 +51,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_VMGENID=y
 CONFIG_NVDIMM=y
 CONFIG_ACPI_NVDIMM=y
 CONFIG_XIO3130=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 6e3b312..fdac18f 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -51,6 +51,7 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_PVPANIC=y
 CONFIG_MEM_HOTPLUG=y
+CONFIG_VMGENID=y
 CONFIG_NVDIMM=y
 CONFIG_ACPI_NVDIMM=y
 CONFIG_XIO3130=y
diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
index 0adcb89..e65ecf9 100644
--- a/docs/specs/pci-ids.txt
+++ b/docs/specs/pci-ids.txt
@@ -47,6 +47,7 @@ PCI devices (other than virtio):
 1b36:0005  PCI test device (docs/specs/pci-testdev.txt)
 1b36:0006  PCI Rocker Ethernet switch device
 1b36:0007  PCI SD Card Host Controller Interface (SDHCI)
+1b36:0009  PCI VM-Generation device
 1b36:000a  PCI-PCI bridge (multiseat)
 
 All these devices are documented in docs/specs.
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 78758e2..0187262 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -44,6 +44,7 @@
 #include "hw/acpi/tpm.h"
 #include "sysemu/tpm_backend.h"
 #include "hw/timer/mc146818rtc_regs.h"
+#include "hw/misc/vmgenid.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -237,6 +238,40 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
     info->applesmc_io_base = applesmc_port();
 }
 
+static Aml *build_vmgenid_device(uint64_t buf_paddr)
+{
+    Aml *dev, *pkg, *crs;
+
+    dev = aml_device("VGEN");
+    aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0003")));
+    aml_append(dev, aml_name_decl("_CID", aml_string("VM_Gen_Counter")));
+    aml_append(dev, aml_name_decl("_DDN", aml_string("VM_Gen_Counter")));
+
+    pkg = aml_package(2);
+    /* low 32 bits of UUID buffer addr */
+    aml_append(pkg, aml_int(buf_paddr & 0xFFFFFFFFUL));
+    /* high 32 bits of UUID buffer addr */
+    aml_append(pkg, aml_int(buf_paddr >> 32));
+    aml_append(dev, aml_name_decl("ADDR", pkg));
+
+    /*
+     * VMGEN device has class_id PCI_CLASS_MEMORY_RAM and Windows
+     * displays it as "PCI RAM controller" which is marked as NO_DRV
+     * so Windows ignores VMGEN device completely and doesn't check
+     * for resource conflicts which during PCI rebalancing can lead
+     * to another PCI device claiming ignored BARs. To prevent this
+     * statically reserve resources used by VM_Gen_Counter.
+     * For more verbose comment see this commit message.
+     */
+     crs = aml_resource_template();
+     aml_append(crs, aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,
+                AML_MAX_FIXED, AML_CACHEABLE, AML_READ_WRITE, 0,
+                buf_paddr, buf_paddr + VMGENID_VMGID_BUF_SIZE - 1, 0,
+                VMGENID_VMGID_BUF_SIZE));
+     aml_append(dev, aml_name_decl("_CRS", crs));
+     return dev;
+}
+
 /*
  * Because of the PXB hosts we cannot simply query TYPE_PCI_HOST_BRIDGE.
  * On i386 arch we only have two pci hosts, so we can look only for them.
@@ -2171,6 +2206,7 @@ build_ssdt(GArray *table_data, GArray *linker,
             }
 
             if (bus) {
+                Object *vmgen;
                 Aml *scope = aml_scope("PCI0");
                 /* Scan all PCI buses. Generate tables to support hotplug. */
                 build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
@@ -2187,6 +2223,24 @@ build_ssdt(GArray *table_data, GArray *linker,
                     aml_append(scope, dev);
                 }
 
+                vmgen = find_vmgneid_dev(NULL);
+                if (vmgen) {
+                    PCIDevice *pdev = PCI_DEVICE(vmgen);
+                    uint64_t buf_paddr =
+                        pci_get_bar_addr(pdev, VMGENID_VMGID_BUF_BAR);
+
+                    if (buf_paddr != PCI_BAR_UNMAPPED) {
+                        aml_append(scope, build_vmgenid_device(buf_paddr));
+
+                        method = aml_method("\\_GPE._E00", 0,
+                                            AML_NOTSERIALIZED);
+                        aml_append(method,
+                            aml_notify(aml_name("\\_SB.PCI0.VGEN"),
+                                       aml_int(0x80)));
+                        aml_append(ssdt, method);
+                    }
+                }
+
                 aml_append(sb_scope, scope);
             }
         }
@@ -2489,8 +2543,6 @@ build_dsdt(GArray *table_data, GArray *linker,
     {
         aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
 
-        aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED));
-
         if (misc->is_piix4) {
             method = aml_method("_E01", 0, AML_NOTSERIALIZED);
             aml_append(method,
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d4765c2..1f05edd 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -43,4 +43,5 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
+obj-$(CONFIG_VMGENID) += vmgenid.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
new file mode 100644
index 0000000..a2fbdfc
--- /dev/null
+++ b/hw/misc/vmgenid.c
@@ -0,0 +1,154 @@
+/*
+ *  Virtual Machine Generation ID Device
+ *
+ *  Copyright (C) 2016 Red Hat Inc.
+ *
+ *  Authors: Gal Hammer <ghammer@redhat.com>
+ *           Igor Mammedov <imammedo@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/pci/pci.h"
+#include "hw/misc/vmgenid.h"
+#include "hw/acpi/acpi.h"
+#include "qapi/visitor.h"
+
+#define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj), VMGENID_DEVICE)
+
+typedef struct VmGenIdState {
+    PCIDevice parent_obj;
+    MemoryRegion iomem;
+    union {
+        uint8_t guid[16];
+        uint8_t guid_page[VMGENID_VMGID_BUF_SIZE];
+    };
+    bool guid_set;
+} VmGenIdState;
+
+Object *find_vmgneid_dev(Error **errp)
+{
+    Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL);
+    if (!obj) {
+        error_setg(errp, VMGENID_DEVICE " is not found");
+    }
+    return obj;
+}
+
+static void vmgenid_update_guest(VmGenIdState *s)
+{
+    Object *acpi_obj;
+    void *ptr = memory_region_get_ram_ptr(&s->iomem);
+
+    memcpy(ptr, &s->guid, sizeof(s->guid));
+    memory_region_set_dirty(&s->iomem, 0, sizeof(s->guid));
+
+    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);
+        ACPIREGS *acpi_regs = adevc->regs(adev);
+
+        acpi_regs->gpe.sts[0] |= 1; /* _GPE.E00 handler */
+        acpi_update_sci(acpi_regs, adevc->sci(adev));
+    }
+}
+
+static void vmgenid_set_guid(Object *obj, const char *value, Error **errp)
+{
+    VmGenIdState *s = VMGENID(obj);
+
+    if (qemu_uuid_parse(value, s->guid) < 0) {
+        error_setg(errp, "'%s." VMGENID_GUID
+                   "': Failed to parse GUID string: %s",
+                   object_get_typename(OBJECT(s)),
+                   value);
+        return;
+    }
+
+    s->guid_set = true;
+    vmgenid_update_guest(s);
+}
+
+static void vmgenid_get_vmgid_addr(Object *obj, Visitor *v, void *opaque,
+                                   const char *name, Error **errp)
+{
+    int64_t value = pci_get_bar_addr(PCI_DEVICE(obj), 0);
+
+    if (value == PCI_BAR_UNMAPPED) {
+        error_setg(errp, "'%s." VMGENID_VMGID_BUF_ADDR "': not initialized",
+                   object_get_typename(OBJECT(obj)));
+        return;
+    }
+    visit_type_int(v, &value, name, errp);
+}
+
+static void vmgenid_initfn(Object *obj)
+{
+    VmGenIdState *s = VMGENID(obj);
+
+    memory_region_init_ram(&s->iomem, obj, "vgid.bar", sizeof(s->guid_page),
+                           &error_abort);
+
+    object_property_add_str(obj, VMGENID_GUID, NULL, vmgenid_set_guid, NULL);
+    object_property_add(obj, VMGENID_VMGID_BUF_ADDR, "int",
+                        vmgenid_get_vmgid_addr, NULL, NULL, NULL, NULL);
+}
+
+
+static void vmgenid_realize(PCIDevice *dev, Error **errp)
+{
+    VmGenIdState *s = VMGENID(dev);
+    bool ambiguous = false;
+
+    object_resolve_path_type("", VMGENID_DEVICE, &ambiguous);
+    if (ambiguous) {
+        error_setg(errp, "no more than one " VMGENID_DEVICE
+                         " device is permitted");
+        return;
+    }
+
+    if (!s->guid_set) {
+        error_setg(errp, "'%s." VMGENID_GUID "' property is not set",
+                   object_get_typename(OBJECT(s)));
+        return;
+    }
+
+    vmstate_register_ram(&s->iomem, DEVICE(s));
+    pci_register_bar(PCI_DEVICE(s), VMGENID_VMGID_BUF_BAR,
+        PCI_BASE_ADDRESS_MEM_PREFETCH |
+        PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64,
+        &s->iomem);
+    return;
+}
+
+static void vmgenid_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    dc->hotpluggable = false;
+    k->realize = vmgenid_realize;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_VMGENID;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+}
+
+static const TypeInfo vmgenid_device_info = {
+    .name          = VMGENID_DEVICE,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VmGenIdState),
+    .instance_init = vmgenid_initfn,
+    .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/misc/vmgenid.h b/include/hw/misc/vmgenid.h
new file mode 100644
index 0000000..b90882c
--- /dev/null
+++ b/include/hw/misc/vmgenid.h
@@ -0,0 +1,27 @@
+/*
+ *  Virtual Machine Generation ID Device
+ *
+ *  Copyright (C) 2016 Red Hat Inc.
+ *
+ *  Authors: Gal Hammer <ghammer@redhat.com>
+ *           Igor Mammedov <imammedo@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.
+ *
+ */
+
+#ifndef HW_MISC_VMGENID_H
+#define HW_MISC_VMGENID_H
+
+#include "qom/object.h"
+
+#define VMGENID_DEVICE           "vmgenid"
+#define VMGENID_GUID             "guid"
+#define VMGENID_VMGID_BUF_ADDR   "vmgid-addr"
+#define VMGENID_VMGID_BUF_SIZE   0x1000
+#define VMGENID_VMGID_BUF_BAR    0
+
+Object *find_vmgneid_dev(Error **errp);
+
+#endif
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index dedf277..f4c9d48 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -94,6 +94,7 @@
 #define PCI_DEVICE_ID_REDHAT_PXB         0x0009
 #define PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT 0x000a
 #define PCI_DEVICE_ID_REDHAT_PXB_PCIE    0x000b
+#define PCI_DEVICE_ID_REDHAT_VMGENID     0x000c
 #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
 
 #define FMT_PCIBUS                      PRIx64
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 4/9] tests: add a unit test for the vmgenid device.
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (2 preceding siblings ...)
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 3/9] pc: add a Virtual Machine Generation ID device Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 5/9] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands Igor Mammedov
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

* test that guest can read GUID provided on CLI from buffer
  accessing it at HPA which is available via 'vmgid-addr'
  property when device is inintialized.
* test setting GUID at runtime and check that it's updated
  at expected HPA.

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

diff --git a/tests/Makefile b/tests/Makefile
index b7352f1..8cccf6e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -206,6 +206,7 @@ check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-xhci.c
 check-qtest-i386-y += tests/pc-cpu-test$(EXESUF)
 check-qtest-i386-y += tests/q35-test$(EXESUF)
+check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
 gcov-files-i386-y += hw/pci-host/q35.c
 check-qtest-i386-$(CONFIG_VHOST_NET_TEST_i386) += tests/vhost-user-test$(EXESUF)
 ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
@@ -565,6 +566,7 @@ tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-o
 tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
+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..9388180
--- /dev/null
+++ b/tests/vmgenid-test.c
@@ -0,0 +1,93 @@
+/*
+ * QTest testcase for VM Generation ID
+ *
+ * Copyright (c) 2016 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 <glib.h>
+#include <string.h>
+#include <unistd.h>
+#include "libqtest.h"
+
+/* Wait at most 1 minute */
+#define TEST_DELAY (1 * G_USEC_PER_SEC / 10)
+#define TEST_CYCLES MAX((60 * G_USEC_PER_SEC / TEST_DELAY), 1)
+
+#define VGID_GUID "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
+
+static void vmgenid_check_guid(const uint8_t *expected)
+{
+    uint8_t guid[16];
+    int i;
+    uint32_t addr = 0;
+    QDict *response;
+
+    for (i = 0; i < TEST_CYCLES; ++i) {
+        response = qmp("{ 'execute': 'qom-get', 'arguments': { "
+                       "'path': '/machine/peripheral/testvgid', "
+                       "'property': 'vmgid-addr' } }");
+        if (qdict_haskey(response, "return")) {
+            addr = qdict_get_int(response, "return");
+        }
+        QDECREF(response);
+        if (addr) {
+            break;
+        }
+        g_usleep(TEST_DELAY);
+    }
+    g_assert(addr);
+
+    /* Skip the ACPI ADDR method and read the GUID directly from memory */
+    for (i = 0; i < 16; i++) {
+        guid[i] = readb(addr + i);
+    }
+
+    g_assert(memcmp(guid, expected, sizeof(guid)) == 0);
+}
+
+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
+    };
+    vmgenid_check_guid(expected);
+}
+
+static void vmgenid_set_guid_test(void)
+{
+    QDict *response;
+    static const uint8_t expected[16] = {
+        0x12, 0x4e, 0x6e, 0xaf, 0xd1, 0xd1, 0x4b, 0xf6,
+        0xbf, 0x41, 0xb9, 0xbb, 0x6c, 0x91, 0xfb, 0x87
+    };
+
+    response = qmp("{ 'execute': 'qom-set', 'arguments': { "
+                   "'path': '/machine/peripheral/testvgid', "
+                   "'property': 'guid', 'value': '"
+                   "124e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87' } }");
+    g_assert(qdict_haskey(response, "return"));
+    QDECREF(response);
+
+    vmgenid_check_guid(expected);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_start("-machine accel=tcg -device vmgenid,id=testvgid,"
+                "guid=" VGID_GUID);
+    qtest_add_func("/vmgenid/vmgenid", vmgenid_test);
+    qtest_add_func("/vmgenid/vmgenid/set-guid", vmgenid_set_guid_test);
+    ret = g_test_run();
+
+    qtest_end();
+
+    return ret;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 5/9] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (3 preceding siblings ...)
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 4/9] tests: add a unit test for the vmgenid device Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 6/9] qmp/hmp: add set-vm-generation-id commands Igor Mammedov
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

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 <imammedo@redhat.com>
---
v18:
  - add a new QMP type GuidInfo instead of reusing UuidInfo
    Eric Blake <eblake@redhat.com>
---
 hmp-commands-info.hx | 13 +++++++++++++
 hmp.c                |  9 +++++++++
 hmp.h                |  1 +
 hw/misc/vmgenid.c    | 20 ++++++++++++++++++++
 qapi-schema.json     | 20 ++++++++++++++++++++
 qmp-commands.hx      | 19 +++++++++++++++++++
 stubs/Makefile.objs  |  1 +
 stubs/vmgenid.c      |  7 +++++++
 8 files changed, 90 insertions(+)
 create mode 100644 stubs/vmgenid.c

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 9b71351..b649a5d 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -787,6 +787,19 @@ Display the value of a storage key (s390 only)
 ETEXI
 
 STEXI
+@item info vm-generation-id
+Show Virtual Machine Generation ID
+ETEXI
+
+    {
+        .name       = "vm-generation-id",
+        .args_type  = "",
+        .params     = "",
+        .help       = "Show Virtual Machine Generation ID",
+        .mhandler.cmd = hmp_info_vm_generation_id,
+    },
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index 54f2620..aeb753d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2375,3 +2375,12 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
 
     qapi_free_RockerOfDpaGroupList(list);
 }
+
+void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
+{
+    GuidInfo *info = 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 a8c5b5a..21c5132 100644
--- a/hmp.h
+++ b/hmp.h
@@ -131,5 +131,6 @@ void hmp_rocker(Monitor *mon, const QDict *qdict);
 void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
 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_vm_generation_id(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
index a2fbdfc..24c0a4e 100644
--- a/hw/misc/vmgenid.c
+++ b/hw/misc/vmgenid.c
@@ -16,6 +16,7 @@
 #include "hw/misc/vmgenid.h"
 #include "hw/acpi/acpi.h"
 #include "qapi/visitor.h"
+#include "qmp-commands.h"
 
 #define VMGENID(obj) OBJECT_CHECK(VmGenIdState, (obj), VMGENID_DEVICE)
 
@@ -38,6 +39,25 @@ Object *find_vmgneid_dev(Error **errp)
     return obj;
 }
 
+GuidInfo *qmp_query_vm_generation_id(Error **errp)
+{
+    GuidInfo *info;
+    VmGenIdState *vdev;
+    Object *obj = find_vmgneid_dev(errp);
+
+    if (!obj) {
+        return NULL;
+    }
+    vdev = VMGENID(obj);
+    info = g_malloc0(sizeof(*info));
+    info->guid = g_strdup_printf(UUID_FMT, vdev->guid[0], vdev->guid[1],
+        vdev->guid[2], vdev->guid[3], vdev->guid[4], vdev->guid[5],
+        vdev->guid[6], vdev->guid[7], vdev->guid[8], vdev->guid[9],
+        vdev->guid[10], vdev->guid[11], vdev->guid[12], vdev->guid[13],
+        vdev->guid[14], vdev->guid[15]);
+    return info;
+}
+
 static void vmgenid_update_guest(VmGenIdState *s)
 {
     Object *acpi_obj;
diff --git a/qapi-schema.json b/qapi-schema.json
index b3038b2..d4e0463 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4081,3 +4081,23 @@
 ##
 { 'enum': 'ReplayMode',
   'data': [ 'none', 'record', 'play' ] }
+
+##
+# @GuidInfo:
+#
+# GUID information.
+#
+# @guid: the globally unique identifier
+#
+# Since: 2.6
+##
+{ 'struct': 'GuidInfo', 'data': {'guid': 'str'} }
+
+##
+# @query-vm-generation-id
+#
+# Show Virtual Machine Generation ID
+#
+# Since 2.6
+##
+{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index db072a6..38e4e16 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4795,3 +4795,22 @@ Example:
                  {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840,
                   "pop-vlan": 1, "id": 251658240}
    ]}
+
+EQMP
+
+    {
+        .name       = "query-vm-generation-id",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_query_vm_generation_id,
+    },
+
+SQMP
+Show Virtual Machine Generation ID counter
+-----
+
+Arguments: none
+
+Example:
+
+-> { "execute": "query-vm-generation-id" }
+<- {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index d7898a0..c1ebfcc 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -38,3 +38,4 @@ stub-obj-y += qmp_pc_dimm_device_list.o
 stub-obj-y += target-monitor-defs.o
 stub-obj-y += target-get-monitor-def.o
 stub-obj-y += vhost.o
+stub-obj-y += vmgenid.o
diff --git a/stubs/vmgenid.c b/stubs/vmgenid.c
new file mode 100644
index 0000000..1ff8cd2
--- /dev/null
+++ b/stubs/vmgenid.c
@@ -0,0 +1,7 @@
+#include "qmp-commands.h"
+
+GuidInfo *qmp_query_vm_generation_id(Error **errp)
+{
+    error_setg(errp, "this command is not currently supported");
+    return NULL;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 6/9] qmp/hmp: add set-vm-generation-id commands
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (4 preceding siblings ...)
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 5/9] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands Igor Mammedov
@ 2016-01-22 13:20 ` Igor Mammedov
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 7/9] add MachineClass->default_props for setting default device properties Igor Mammedov
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

Add set-vm-generation-id command to set Virtual Machine
Generation ID counter.

QMP command example:
    { "execute": "set-vm-generation-id",
          "arguments": {
              "guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
          }
    }

HMP command example:
    set-vm-generation-id 324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v18:
   - use new GuidInfo type introduced in previous patch and fix
     argument to lowercase and corresponding example.
     Eric Blake <eblake@redhat.com>
   - s/if (errp != NULL)/if (errp)/
     Eric Blake <eblake@redhat.com>
---
 hmp-commands.hx   | 13 +++++++++++++
 hmp.c             | 12 ++++++++++++
 hmp.h             |  1 +
 hw/misc/vmgenid.c | 11 +++++++++++
 qapi-schema.json  | 11 +++++++++++
 qmp-commands.hx   | 22 ++++++++++++++++++++++
 stubs/vmgenid.c   |  6 ++++++
 7 files changed, 76 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bb52e4d..d310707 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1756,5 +1756,18 @@ ETEXI
     },
 
 STEXI
+@item set-vm-generation-id @var{uuid}
+Set Virtual Machine Generation ID counter to @var{guid}
+ETEXI
+
+    {
+        .name       = "set-vm-generation-id",
+        .args_type  = "guid:s",
+        .params     = "guid",
+        .help       = "Set Virtual Machine Generation ID counter",
+        .mhandler.cmd = hmp_set_vm_generation_id,
+    },
+
+STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index aeb753d..c1f3a7a 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2384,3 +2384,15 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
     }
     qapi_free_GuidInfo(info);
 }
+
+void hmp_set_vm_generation_id(Monitor *mon, const QDict *qdict)
+{
+    Error *errp = NULL;
+    const char *guid = qdict_get_str(qdict, "guid");
+
+    qmp_set_vm_generation_id(guid, &errp);
+    if (errp) {
+        hmp_handle_error(mon, &errp);
+        return;
+    }
+}
diff --git a/hmp.h b/hmp.h
index 21c5132..cbf2045 100644
--- a/hmp.h
+++ b/hmp.h
@@ -132,5 +132,6 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
 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_vm_generation_id(Monitor *mon, const QDict *qdict);
+void hmp_set_vm_generation_id(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/hw/misc/vmgenid.c b/hw/misc/vmgenid.c
index 24c0a4e..4fa52bc 100644
--- a/hw/misc/vmgenid.c
+++ b/hw/misc/vmgenid.c
@@ -58,6 +58,17 @@ GuidInfo *qmp_query_vm_generation_id(Error **errp)
     return info;
 }
 
+void qmp_set_vm_generation_id(const char *guid, Error **errp)
+{
+    Object *obj = find_vmgneid_dev(errp);
+
+    if (!obj) {
+        return;
+    }
+
+    object_property_set_str(obj, guid, VMGENID_GUID, errp);
+}
+
 static void vmgenid_update_guest(VmGenIdState *s)
 {
     Object *acpi_obj;
diff --git a/qapi-schema.json b/qapi-schema.json
index d4e0463..87a0e25 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4101,3 +4101,14 @@
 # Since 2.6
 ##
 { 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
+
+##
+# @set-vm-generation-id
+#
+# Set Virtual Machine Generation ID
+#
+# @guid: new GUID to set as Virtual Machine Generation ID
+#
+# Since 2.6
+##
+{ 'command': 'set-vm-generation-id', 'data': { 'guid': 'str' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 38e4e16..84738c7 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4814,3 +4814,25 @@ Example:
 
 -> { "execute": "query-vm-generation-id" }
 <- {"return": {"guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"}}
+
+EQMP
+
+    {
+        .name       = "set-vm-generation-id",
+        .args_type  = "guid:s",
+        .mhandler.cmd_new = qmp_marshal_set_vm_generation_id,
+    },
+
+SQMP
+Set Virtual Machine Generation ID counter
+-----
+
+Arguments:
+
+- "guid": counter ID in GUID string representation (json-string)"
+
+Example:
+
+-> { "execute": "set-vm-generation-id" ,
+     "arguments": { "guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87" } }
+<- {"return": {}}
diff --git a/stubs/vmgenid.c b/stubs/vmgenid.c
index 1ff8cd2..6af0b73 100644
--- a/stubs/vmgenid.c
+++ b/stubs/vmgenid.c
@@ -5,3 +5,9 @@ GuidInfo *qmp_query_vm_generation_id(Error **errp)
     error_setg(errp, "this command is not currently supported");
     return NULL;
 }
+
+void qmp_set_vm_generation_id(const char *guid, Error **errp)
+{
+    error_setg(errp, "this command is not currently supported");
+    return;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 7/9] add MachineClass->default_props for setting default device properties
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (5 preceding siblings ...)
  2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 6/9] qmp/hmp: add set-vm-generation-id commands Igor Mammedov
@ 2016-01-22 13:21 ` Igor Mammedov
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 8/9] pc: put PIIX3 in slot 1 explicitly and cleanup functions assignment Igor Mammedov
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 9/9] pc/q53: by default put vmgenid device as an function of ISA bridge Igor Mammedov
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 include/hw/boards.h | 1 +
 vl.c                | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 0f30959..d495611 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -90,6 +90,7 @@ struct MachineClass {
     const char *default_machine_opts;
     const char *default_boot_order;
     const char *default_display;
+    GlobalProperty *default_props;
     GlobalProperty *compat_props;
     const char *hw_version;
     ram_addr_t default_ram_size;
diff --git a/vl.c b/vl.c
index f043009..3c5a936 100644
--- a/vl.c
+++ b/vl.c
@@ -4491,6 +4491,10 @@ int main(int argc, char **argv, char **envp)
             exit (i == 1 ? 1 : 0);
     }
 
+    if (machine_class->default_props) {
+        qdev_prop_register_global_list(machine_class->default_props);
+    }
+
     if (machine_class->compat_props) {
         qdev_prop_register_global_list(machine_class->compat_props);
     }
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 8/9] pc: put PIIX3 in slot 1 explicitly and cleanup functions assignment
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (6 preceding siblings ...)
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 7/9] add MachineClass->default_props for setting default device properties Igor Mammedov
@ 2016-01-22 13:21 ` Igor Mammedov
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 9/9] pc/q53: by default put vmgenid device as an function of ISA bridge Igor Mammedov
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

currently slot for PIIX3 bridge is selected
dynamically but it's always in slot 1 for
existing machine types.
However it's easy to regress if another PCI
device were added before PIIX3 is created and
also requires passing around devfn of the
created bridge.
Replace dynamic slot assignment with a static
one like it's done for ICH9_LPC, explicitly
setting slot # for the bridge.
While at it cleanup IDE/USB/PIIX4_PM functions
assignment, replacing magic offsets with defines.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
Static assignment will help with adding other
functions to multifunction bridge in following
patch.
---
 hw/i386/pc_piix.c    | 17 ++++++++++-------
 hw/pci-host/piix.c   |  9 ++++-----
 include/hw/i386/pc.h |  8 +++++++-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bc74557..2ea3d84 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -73,7 +73,6 @@ static void pc_init1(MachineState *machine,
     PCIBus *pci_bus;
     ISABus *isa_bus;
     PCII440FXState *i440fx_state;
-    int piix3_devfn = -1;
     qemu_irq *gsi;
     qemu_irq *i8259;
     qemu_irq smi_irq;
@@ -179,7 +178,7 @@ static void pc_init1(MachineState *machine,
     if (pcmc->pci_enabled) {
         pci_bus = i440fx_init(host_type,
                               pci_type,
-                              &i440fx_state, &piix3_devfn, &isa_bus, gsi,
+                              &i440fx_state, &isa_bus, gsi,
                               system_memory, system_io, machine->ram_size,
                               pcms->below_4g_mem_size,
                               pcms->above_4g_mem_size,
@@ -229,9 +228,11 @@ static void pc_init1(MachineState *machine,
     if (pcmc->pci_enabled) {
         PCIDevice *dev;
         if (xen_enabled()) {
-            dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
+            dev = pci_piix3_xen_ide_init(pci_bus, hd,
+                PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_IDE_FUNC));
         } else {
-            dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
+            dev = pci_piix3_ide_init(pci_bus, hd,
+                PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_IDE_FUNC));
         }
         idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
         idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
@@ -254,7 +255,8 @@ static void pc_init1(MachineState *machine,
     pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
 
     if (pcmc->pci_enabled && usb_enabled()) {
-        pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
+        pci_create_simple(pci_bus, PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_USB_FUNC),
+                          "piix3-usb-uhci");
     }
 
     if (pcmc->pci_enabled && acpi_enabled) {
@@ -263,8 +265,9 @@ static void pc_init1(MachineState *machine,
 
         smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
-                              gsi[9], smi_irq,
+        smbus = piix4_pm_init(pci_bus,
+                              PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_PIIX4_PM_FUNC),
+                              0xb100, gsi[9], smi_irq,
                               pc_machine_is_smm_enabled(pcms),
                               &piix4_pm);
         smbus_eeprom_init(smbus, 8, NULL, 0);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index b0d7e31..b8bf1fc 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -310,7 +310,6 @@ static void i440fx_realize(PCIDevice *dev, Error **errp)
 
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
                     PCII440FXState **pi440fx_state,
-                    int *piix3_devfn,
                     ISABus **isa_bus, qemu_irq *pic,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
@@ -382,13 +381,15 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
      * These additional routes can be discovered through ACPI. */
     if (xen_enabled()) {
         PCIDevice *pci_dev = pci_create_simple_multifunction(b,
-                             -1, true, "PIIX3-xen");
+                             PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_PCI_FUNC),
+                             true, "PIIX3-xen");
         piix3 = PIIX3_PCI_DEVICE(pci_dev);
         pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
                 piix3, XEN_PIIX_NUM_PIRQS);
     } else {
         PCIDevice *pci_dev = pci_create_simple_multifunction(b,
-                             -1, true, "PIIX3");
+                             PCI_DEVFN(PIIX3_PCI_SLOT, PIIX3_PCI_FUNC),
+                             true, "PIIX3");
         piix3 = PIIX3_PCI_DEVICE(pci_dev);
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
@@ -397,8 +398,6 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
     piix3->pic = pic;
     *isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));
 
-    *piix3_devfn = piix3->dev.devfn;
-
     ram_size = ram_size / 8 / 1024 / 1024;
     if (ram_size > 255) {
         ram_size = 255;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 5bac03d..4da5178 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -291,8 +291,14 @@ typedef struct PCII440FXState PCII440FXState;
 
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 
+#define PIIX3_PCI_SLOT                       1
+#define PIIX3_PCI_FUNC                       0
+#define PIIX3_IDE_FUNC                       1
+#define PIIX3_USB_FUNC                       2
+#define PIIX3_PIIX4_PM_FUNC                  3
+
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
-                    PCII440FXState **pi440fx_state, int *piix_devfn,
+                    PCII440FXState **pi440fx_state,
                     ISABus **isa_bus, qemu_irq *pic,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v18 9/9] pc/q53: by default put vmgenid device as an function of ISA bridge
  2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
                   ` (7 preceding siblings ...)
  2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 8/9] pc: put PIIX3 in slot 1 explicitly and cleanup functions assignment Igor Mammedov
@ 2016-01-22 13:21 ` Igor Mammedov
  8 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2016-01-22 13:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: ehabkost, mst, ghammer, lersek, lcapitulino, pbonzini

it will save a PCI slot that would be used otherwise.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/pc_piix.c      | 12 ++++++++++++
 hw/i386/pc_q35.c       | 12 ++++++++++++
 include/hw/i386/ich9.h |  3 ++-
 include/hw/i386/pc.h   |  1 +
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 2ea3d84..a31e8c6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -54,6 +54,7 @@
 #endif
 #include "migration/migration.h"
 #include "kvm_i386.h"
+#include "hw/misc/vmgenid.h"
 
 #define MAX_IDE_BUS 2
 
@@ -414,6 +415,17 @@ static void pc_xen_hvm_init(MachineState *machine)
 
 static void pc_i440fx_machine_options(MachineClass *m)
 {
+    static GlobalProperty dev_defaults[] = {
+        {
+            .driver   = VMGENID_DEVICE,
+            .property = "addr",
+            .value    = stringify(PIIX3_PCI_SLOT) "."
+                        stringify(PIIX3_VMGENID_FUNC),
+        },
+        {}
+    };
+
+    m->default_props = dev_defaults;
     m->family = "pc_piix";
     m->desc = "Standard PC (i440FX + PIIX, 1996)";
     m->hot_add_cpu = pc_hot_add_cpu;
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 6128b02..0a1df78 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -45,6 +45,7 @@
 #include "hw/usb.h"
 #include "qemu/error-report.h"
 #include "migration/migration.h"
+#include "hw/misc/vmgenid.h"
 
 /* ICH9 AHCI has 6 ports */
 #define MAX_SATA_PORTS     6
@@ -338,6 +339,17 @@ static void pc_compat_1_4(MachineState *machine)
 
 static void pc_q35_machine_options(MachineClass *m)
 {
+    static GlobalProperty dev_defaults[] = {
+        {
+            .driver   = VMGENID_DEVICE,
+            .property = "addr",
+            .value    = stringify(ICH9_LPC_DEV) "."
+                        stringify(ICH9_LPC_VMGENID_FUNC),
+        },
+        {}
+    };
+
+    m->default_props = dev_defaults;
     m->family = "pc_q35";
     m->desc = "Standard PC (Q35 + ICH9, 2009)";
     m->hot_add_cpu = pc_hot_add_cpu;
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index b9d2b04..271b0c7 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -129,8 +129,9 @@ Object *ich9_lpc_find(void);
 #define ICH9_A2_LPC                             "ICH9 A2 LPC"
 #define ICH9_A2_LPC_SAVEVM_VERSION              0
 
-#define ICH9_LPC_DEV                            31
+#define ICH9_LPC_DEV                            0x1f
 #define ICH9_LPC_FUNC                           0
+#define ICH9_LPC_VMGENID_FUNC                   6
 
 #define ICH9_A2_LPC_REVISION                    0x2
 #define ICH9_LPC_NB_PIRQS                       8       /* PCI A-H */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 4da5178..28b917a 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -296,6 +296,7 @@ typedef struct PCII440FXState PCII440FXState;
 #define PIIX3_IDE_FUNC                       1
 #define PIIX3_USB_FUNC                       2
 #define PIIX3_PIIX4_PM_FUNC                  3
+#define PIIX3_VMGENID_FUNC                   7
 
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
                     PCII440FXState **pi440fx_state,
-- 
1.8.3.1

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

end of thread, other threads:[~2016-01-22 13:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-22 13:20 [Qemu-devel] [PATCH v18 0/9] Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 1/9] acpi: extend ACPI interface to provide access to ACPI registers and SCI irq Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 2/9] docs: vm generation id device's description Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 3/9] pc: add a Virtual Machine Generation ID device Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 4/9] tests: add a unit test for the vmgenid device Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 5/9] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands Igor Mammedov
2016-01-22 13:20 ` [Qemu-devel] [PATCH v18 6/9] qmp/hmp: add set-vm-generation-id commands Igor Mammedov
2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 7/9] add MachineClass->default_props for setting default device properties Igor Mammedov
2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 8/9] pc: put PIIX3 in slot 1 explicitly and cleanup functions assignment Igor Mammedov
2016-01-22 13:21 ` [Qemu-devel] [PATCH v18 9/9] pc/q53: by default put vmgenid device as an function of ISA bridge 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.