qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/11] Add live migration unit tests
@ 2011-03-23  0:16 Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
                   ` (10 more replies)
  0 siblings, 11 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Juan Quintela

Here is a more sophisticated version of my patch from earlier today.  Short
summary is, this adds a 'make check-vmstate' that runs quickly, and would catch
a large percentage of the live migration regressions we introduce.

I hope it also shows how we can add similar things to other subsystems and build
a more rigorious unit test framework within QEMU.

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

* [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  8:13   ` Stefan Hajnoczi
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions Anthony Liguori
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

GLib is an extremely common library that has a portable thread implementation
along with tons of other goodies.

GLib and GObject have a fantastic amount of infrastructure we can leverage in
QEMU including an object oriented programming infrastructure.

Short term, it has a very nice thread pool implementation that we could leverage
in something like virtio-9p.  It also has a test harness implementation that
this series will use.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile        |    2 ++
 Makefile.objs   |    2 ++
 Makefile.target |    1 +
 configure       |   13 +++++++++++++
 4 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 89e88b4..5f9b120 100644
--- a/Makefile
+++ b/Makefile
@@ -104,6 +104,8 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
 
 QEMU_CFLAGS+=$(CURL_CFLAGS)
 
+QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
 ui/cocoa.o: ui/cocoa.m
 
 ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
diff --git a/Makefile.objs b/Makefile.objs
index f8cf199..b5e1c35 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -323,3 +323,5 @@ vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
 
+vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
diff --git a/Makefile.target b/Makefile.target
index 62b102a..4897e0f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -204,6 +204,7 @@ QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
 QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
 QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
+QEMU_CFLAGS += $(GLIB_CFLAGS)
 
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
diff --git a/configure b/configure
index 5a5827f..0302405 100755
--- a/configure
+++ b/configure
@@ -1670,6 +1670,18 @@ EOF
 fi
 
 ##########################################
+# glib support probe
+if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then
+    glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
+    glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
+    libs_softmmu="$glib_libs $libs_softmmu"
+    libs_tools="$glib_libs $libs_softmmu"
+else
+    echo "glib-2.0 required to compile QEMU"
+    exit 1
+fi
+
+##########################################
 # kvm probe
 if test "$kvm" != "no" ; then
     cat > $TMPC <<EOF
@@ -2770,6 +2782,7 @@ if test "$bluez" = "yes" ; then
   echo "CONFIG_BLUEZ=y" >> $config_host_mak
   echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 fi
+echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
 if test "$xen" = "yes" ; then
   echo "CONFIG_XEN=y" >> $config_host_mak
 fi
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  9:00   ` Alon Levy
  2011-03-23 12:30   ` Peter Maydell
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique Anthony Liguori
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

This is a purely mechanical change.  It was generated with a simple python
script and a little bit of hand tuning.  Without this, we can only see
VMStateDescriptions that are part of an active device which means that we have
to test migration with a VM configured with every possible device.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ac97.c                  |    8 ++++++
 hw/acpi_piix4.c            |    8 ++++++
 hw/apb_pci.c               |    8 ++++++
 hw/apic.c                  |    8 ++++++
 hw/arm_sysctl.c            |    8 ++++++
 hw/bonito.c                |    8 ++++++
 hw/cirrus_vga.c            |    8 ++++++
 hw/cs4231.c                |    8 ++++++
 hw/cs4231a.c               |    8 ++++++
 hw/dec_pci.c               |    8 ++++++
 hw/e1000.c                 |    8 ++++++
 hw/eccmemctl.c             |    8 ++++++
 hw/eeprom93xx.c            |    8 ++++++
 hw/es1370.c                |    8 ++++++
 hw/escc.c                  |    8 ++++++
 hw/esp.c                   |    8 ++++++
 hw/fdc.c                   |   16 ++++++++++++
 hw/fw_cfg.c                |    8 ++++++
 hw/gus.c                   |    8 ++++++
 hw/hda-audio.c             |    8 ++++++
 hw/hpet.c                  |    8 ++++++
 hw/hw.h                    |    3 ++
 hw/i2c.c                   |    8 ++++++
 hw/i8254.c                 |    8 ++++++
 hw/i8259.c                 |    8 ++++++
 hw/intel-hda.c             |    8 ++++++
 hw/ioapic.c                |    8 ++++++
 hw/ioh3420.c               |    8 ++++++
 hw/kvmclock.c              |    8 ++++++
 hw/lance.c                 |    8 ++++++
 hw/lm32_juart.c            |    8 ++++++
 hw/lm32_pic.c              |    8 ++++++
 hw/lm32_sys.c              |    8 ++++++
 hw/lm32_timer.c            |    8 ++++++
 hw/lm32_uart.c             |    8 ++++++
 hw/lm832x.c                |    8 ++++++
 hw/lsi53c895a.c            |    8 ++++++
 hw/marvell_88w8618_audio.c |    8 ++++++
 hw/max7310.c               |    8 ++++++
 hw/mc146818rtc.c           |    8 ++++++
 hw/mst_fpga.c              |    8 ++++++
 hw/musicpal.c              |   56 ++++++++++++++++++++++++++++++++++++++++++++
 hw/ne2000.c                |    8 ++++++
 hw/pc.c                    |    8 ++++++
 hw/pci.c                   |    8 ++++++
 hw/pckbd.c                 |   16 ++++++++++++
 hw/pcnet-pci.c             |    8 ++++++
 hw/piix_pci.c              |    8 ++++++
 hw/pl031.c                 |    8 ++++++
 hw/pl050.c                 |   16 ++++++++++++
 hw/pl080.c                 |   16 ++++++++++++
 hw/pl110.c                 |   16 ++++++++++++
 hw/pl190.c                 |    8 ++++++
 hw/ps2.c                   |   16 ++++++++++++
 hw/pxa2xx.c                |   16 ++++++++++++
 hw/pxa2xx_dma.c            |    8 ++++++
 hw/pxa2xx_pic.c            |    8 ++++++
 hw/pxa2xx_timer.c          |   16 ++++++++++++
 hw/qxl.c                   |   16 ++++++++++++
 hw/rtl8139.c               |   16 ++++++++++++
 hw/sb16.c                  |    8 ++++++
 hw/sbi.c                   |    8 ++++++
 hw/serial.c                |   10 ++++++-
 hw/slavio_intctl.c         |    8 ++++++
 hw/slavio_misc.c           |    8 ++++++
 hw/slavio_timer.c          |    8 ++++++
 hw/smc91c111.c             |    8 ++++++
 hw/sparc32_dma.c           |    8 ++++++
 hw/spitz.c                 |   32 +++++++++++++++++++++++++
 hw/ssd0303.c               |    8 ++++++
 hw/sun4c_intctl.c          |    8 ++++++
 hw/sun4m_iommu.c           |    8 ++++++
 hw/tcx.c                   |    8 ++++++
 hw/tmp105.c                |    8 ++++++
 hw/twl92230.c              |    8 ++++++
 hw/usb-hid.c               |    8 ++++++
 hw/usb-hub.c               |    8 ++++++
 hw/usb-uhci.c              |    8 ++++++
 hw/versatilepb.c           |    8 ++++++
 hw/vga-isa.c               |    8 ++++++
 hw/vga-pci.c               |    8 ++++++
 hw/vmmouse.c               |    8 ++++++
 hw/vmware_vga.c            |    8 ++++++
 hw/vt82c686.c              |   16 ++++++++++++
 hw/wdt_i6300esb.c          |    8 ++++++
 hw/wdt_ib700.c             |    8 ++++++
 hw/wm8750.c                |    8 ++++++
 hw/xio3130_downstream.c    |    8 ++++++
 hw/xio3130_upstream.c      |    8 ++++++
 hw/zaurus.c                |    8 ++++++
 module.h                   |    2 +
 savevm.c                   |    4 +++
 target-i386/machine.c      |    8 ++++++
 93 files changed, 889 insertions(+), 2 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index d71072d..bf818b8 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1343,6 +1343,14 @@ static PCIDeviceInfo ac97_info = {
     .init         = ac97_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ac97);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void ac97_register (void)
 {
     pci_qdev_register (&ac97_info);
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0b2bc97..aaa009b 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -460,6 +460,14 @@ static PCIDeviceInfo piix4_pm_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_acpi);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void piix4_pm_register(void)
 {
     pci_qdev_register(&piix4_pm_info);
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 84e9af7..e5d7954 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -472,6 +472,14 @@ static PCIDeviceInfo pbm_pci_bridge_info = {
     .is_bridge = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pci_device);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pbm_register_devices(void)
 {
     sysbus_register_withprop(&pbm_host_info);
diff --git a/hw/apic.c b/hw/apic.c
index 9febf40..cdf64dc 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -1025,6 +1025,14 @@ static SysBusDeviceInfo apic_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_apic);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void apic_register_devices(void)
 {
     sysbus_register_withprop(&apic_info);
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 9225b58..e11b1ee 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -363,6 +363,14 @@ static SysBusDeviceInfo arm_sysctl_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_arm_sysctl);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void arm_sysctl_register_devices(void)
 {
     sysbus_register_withprop(&arm_sysctl_info);
diff --git a/hw/bonito.c b/hw/bonito.c
index 65a4a63..6ec0777 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -798,6 +798,14 @@ static PCIDeviceInfo bonito_info = {
     .init         = bonito_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_bonito);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo bonito_pcihost_info = {
     .init         = bonito_pcihost_initfn,
     .qdev.name    = "Bonito-pcihost",
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 2724f7b..97a1c4c 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3145,6 +3145,14 @@ static PCIDeviceInfo cirrus_vga_info = {
     .config_write = pci_cirrus_write_config,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pci_cirrus_vga);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void cirrus_vga_register(void)
 {
     pci_qdev_register(&cirrus_vga_info);
diff --git a/hw/cs4231.c b/hw/cs4231.c
index a65b697..d9601d0 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -167,6 +167,14 @@ static SysBusDeviceInfo cs4231_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_cs4231);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void cs4231_register_devices(void)
 {
     sysbus_register_withprop(&cs4231_info);
diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index 598f032..e036faf 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -679,6 +679,14 @@ static ISADeviceInfo cs4231a_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_cs4231a);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void cs4231a_register (void)
 {
     isa_qdev_register (&cs4231a_info);
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index bf88f2a..4924a43 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -76,6 +76,14 @@ static PCIDeviceInfo dec_21154_pci_bridge_info = {
     .is_bridge = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pci_device);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 {
     PCIDevice *dev;
diff --git a/hw/e1000.c b/hw/e1000.c
index 2a4d5c7..e906c65 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1212,6 +1212,14 @@ static PCIDeviceInfo e1000_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_e1000);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void e1000_register_devices(void)
 {
     pci_qdev_register(&e1000_info);
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index 2bda87b..770b6aa 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -323,6 +323,14 @@ static SysBusDeviceInfo ecc_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ecc);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 
 static void ecc_register_devices(void)
 {
diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
index 660b28f..cfa695d 100644
--- a/hw/eeprom93xx.c
+++ b/hw/eeprom93xx.c
@@ -320,6 +320,14 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords)
     return eeprom;
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_eeprom);
+}
+
+vmstate_init(init_vmstate_description);
+
 void eeprom93xx_free(DeviceState *dev, eeprom_t *eeprom)
 {
     /* Destroy EEPROM. */
diff --git a/hw/es1370.c b/hw/es1370.c
index 40cb48c..d2f3671 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1045,6 +1045,14 @@ static PCIDeviceInfo es1370_info = {
     .init         = es1370_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_es1370);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void es1370_register (void)
 {
     pci_qdev_register (&es1370_info);
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..08062e7 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -953,6 +953,14 @@ static SysBusDeviceInfo escc_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_escc);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void escc_register_devices(void)
 {
     sysbus_register_withprop(&escc_info);
diff --git a/hw/esp.c b/hw/esp.c
index fa9d2a2..977890e 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -743,6 +743,14 @@ static SysBusDeviceInfo esp_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_esp);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void esp_register_devices(void)
 {
     sysbus_register_withprop(&esp_info);
diff --git a/hw/fdc.c b/hw/fdc.c
index 9fdbc75..4b02dce 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1938,6 +1938,14 @@ static ISADeviceInfo isa_fdc_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_isa_fdc);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static const VMStateDescription vmstate_sysbus_fdc ={
     .name = "fdc",
     .version_id = 2,
@@ -1961,6 +1969,14 @@ static SysBusDeviceInfo sysbus_fdc_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_sysbus_fdc);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static SysBusDeviceInfo sun4m_fdc_info = {
     .init = sun4m_fdc_init1,
     .qdev.name  = "SUNW,fdtwo",
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 85c8c3c..67603a9 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -399,6 +399,14 @@ static SysBusDeviceInfo fw_cfg_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_fw_cfg);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void fw_cfg_register_devices(void)
 {
     sysbus_register_withprop(&fw_cfg_info);
diff --git a/hw/gus.c b/hw/gus.c
index ff9e7c7..8e35ffb 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -315,6 +315,14 @@ static ISADeviceInfo gus_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_gus);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void gus_register (void)
 {
     isa_qdev_register (&gus_info);
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index c699d6f..f384de6 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -906,6 +906,14 @@ static HDACodecDeviceInfo hda_audio_info_output = {
     .stream       = hda_audio_stream,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_hda_audio);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static HDACodecDeviceInfo hda_audio_info_duplex = {
     .qdev.name    = "hda-duplex",
     .qdev.desc    = "HDA Audio Codec, duplex",
diff --git a/hw/hpet.c b/hw/hpet.c
index ef9a2a0..9010f45 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -737,6 +737,14 @@ static SysBusDeviceInfo hpet_device_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_hpet);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void hpet_register_device(void)
 {
     sysbus_register_withprop(&hpet_device_info);
diff --git a/hw/hw.h b/hw/hw.h
index 1b09039..81bbd7a 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -914,4 +914,7 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
                                    int required_for_version);
 void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
                         void *opaque);
+
+void register_vmstate_description(const VMStateDescription *desc);
+
 #endif
diff --git a/hw/i2c.c b/hw/i2c.c
index f80d12d..85ae1f9 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -66,6 +66,14 @@ i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
     return bus;
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_i2c_bus);
+}
+
+vmstate_init(init_vmstate_description);
+
 void i2c_set_slave_address(i2c_slave *dev, uint8_t address)
 {
     dev->address = address;
diff --git a/hw/i8254.c b/hw/i8254.c
index a9ca9f6..261f860 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -539,6 +539,14 @@ static ISADeviceInfo pit_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pit);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pit_register(void)
 {
     isa_qdev_register(&pit_info);
diff --git a/hw/i8259.c b/hw/i8259.c
index 84d330d..388e145 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -487,6 +487,14 @@ static void pic_init1(int io_addr, int elcr_addr, PicState *s)
     qemu_register_reset(pic_reset, s);
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_pic);
+}
+
+vmstate_init(init_vmstate_description);
+
 void pic_info(Monitor *mon)
 {
     int i;
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index b0b1d12..a32d28d 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1283,6 +1283,14 @@ static PCIDeviceInfo intel_hda_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_intel_hda);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void intel_hda_register(void)
 {
     pci_qdev_register(&intel_hda_info);
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 569327d..8ac6d34 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -350,6 +350,14 @@ static SysBusDeviceInfo ioapic_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ioapic);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void ioapic_register_devices(void)
 {
     sysbus_register_withprop(&ioapic_info);
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 95adf09..7b0b801 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -229,6 +229,14 @@ static PCIDeviceInfo ioh3420_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ioh3420);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void ioh3420_register(void)
 {
     pci_qdev_register(&ioh3420_info);
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index b6ceddf..f9c05cd 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -99,6 +99,14 @@ static SysBusDeviceInfo kvmclock_info = {
     .init = kvmclock_init,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&kvmclock_vmsd);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 /* Note: Must be called after VCPU initialization. */
 void kvmclock_create(void)
 {
diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb..32d81ca 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -153,6 +153,14 @@ static SysBusDeviceInfo lance_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lance);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lance_register_devices(void)
 {
     sysbus_register_withprop(&lance_info);
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index fddcf7e..a49308c 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -142,6 +142,14 @@ static SysBusDeviceInfo lm32_juart_info = {
     .qdev.reset = juart_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm32_juart);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm32_juart_register(void)
 {
     sysbus_register_withprop(&lm32_juart_info);
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index 02941a7..de4f310 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -182,6 +182,14 @@ static SysBusDeviceInfo lm32_pic_info = {
     .qdev.reset = pic_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm32_pic);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm32_pic_register(void)
 {
     sysbus_register_withprop(&lm32_pic_info);
diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index 427b05f..4c718b7 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -153,6 +153,14 @@ static SysBusDeviceInfo lm32_sys_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm32_sys);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm32_sys_register(void)
 {
     sysbus_register_withprop(&lm32_sys_info);
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index ed28984..445cfde 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -214,6 +214,14 @@ static SysBusDeviceInfo lm32_timer_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm32_timer);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm32_timer_register(void)
 {
     sysbus_register_withprop(&lm32_timer_info);
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index e225087..32c6ffd 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -280,6 +280,14 @@ static SysBusDeviceInfo lm32_uart_info = {
     .qdev.reset = uart_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm32_uart);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm32_uart_register(void)
 {
     sysbus_register_withprop(&lm32_uart_info);
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 590a4cc..ac097bd 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -504,6 +504,14 @@ static I2CSlaveInfo lm8323_info = {
     .send = lm_i2c_tx
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lm_kbd);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lm832x_register_devices(void)
 {
     i2c_register_slave(&lm8323_info);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 84a4992..699261b 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2211,6 +2211,14 @@ static PCIDeviceInfo lsi_info = {
     .exit       = lsi_scsi_uninit,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_lsi_scsi);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void lsi53c895a_register_devices(void)
 {
     pci_qdev_register(&lsi_info);
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index 3eff925..25437ea 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -291,6 +291,14 @@ static SysBusDeviceInfo mv88w8618_audio_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&mv88w8618_audio_vmsd);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void mv88w8618_register_devices(void)
 {
     sysbus_register_withprop(&mv88w8618_audio_info);
diff --git a/hw/max7310.c b/hw/max7310.c
index c1bdb2e..12b8769 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -196,6 +196,14 @@ static I2CSlaveInfo max7310_info = {
     .send = max7310_tx
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_max7310);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void max7310_register_devices(void)
 {
     i2c_register_slave(&max7310_info);
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 1c9a706..7b80c18 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -650,6 +650,14 @@ static ISADeviceInfo mc146818rtc_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_rtc);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void mc146818rtc_register(void)
 {
     isa_qdev_register(&mc146818rtc_info);
diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
index a04355c..c5111b9 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -248,6 +248,14 @@ static SysBusDeviceInfo mst_fpga_info = {
 	.qdev.vmsd = &vmstate_mst_fpga_regs,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_mst_fpga_regs);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void mst_fpga_register(void)
 {
 	sysbus_register_withprop(&mst_fpga_info);
diff --git a/hw/musicpal.c b/hw/musicpal.c
index d98aa8d..773b93c 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -423,6 +423,14 @@ static SysBusDeviceInfo mv88w8618_eth_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&mv88w8618_eth_vmsd);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 /* LCD register offsets */
 #define MP_LCD_IRQCTRL          0x180
 #define MP_LCD_IRQSTAT          0x184
@@ -637,6 +645,14 @@ static SysBusDeviceInfo musicpal_lcd_info = {
     .qdev.vmsd = &musicpal_lcd_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&musicpal_lcd_vmsd);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 /* PIC register offsets */
 #define MP_PIC_STATUS           0x00
 #define MP_PIC_ENABLE_SET       0x08
@@ -753,6 +769,14 @@ static SysBusDeviceInfo mv88w8618_pic_info = {
     .qdev.vmsd = &mv88w8618_pic_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_2(void)
+{
+    register_vmstate_description(&mv88w8618_pic_vmsd);
+}
+
+vmstate_init(init_vmstate_description_2);
+
 /* PIT register offsets */
 #define MP_PIT_TIMER1_LENGTH    0x00
 /* ... */
@@ -927,6 +951,14 @@ static SysBusDeviceInfo mv88w8618_pit_info = {
     .qdev.vmsd  = &mv88w8618_pit_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_3(void)
+{
+    register_vmstate_description(&mv88w8618_pit_vmsd);
+}
+
+vmstate_init(init_vmstate_description_3);
+
 /* Flash config register offsets */
 #define MP_FLASHCFG_CFGR0    0x04
 
@@ -1004,6 +1036,14 @@ static SysBusDeviceInfo mv88w8618_flashcfg_info = {
     .qdev.vmsd  = &mv88w8618_flashcfg_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_4(void)
+{
+    register_vmstate_description(&mv88w8618_flashcfg_vmsd);
+}
+
+vmstate_init(init_vmstate_description_4);
+
 /* Misc register offsets */
 #define MP_MISC_BOARD_REVISION  0x18
 
@@ -1335,6 +1375,14 @@ static SysBusDeviceInfo musicpal_gpio_info = {
     .qdev.vmsd  = &musicpal_gpio_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_5(void)
+{
+    register_vmstate_description(&musicpal_gpio_vmsd);
+}
+
+vmstate_init(init_vmstate_description_5);
+
 /* Keyboard codes & masks */
 #define KEY_RELEASED            0x80
 #define KEY_CODE                0x7f
@@ -1478,6 +1526,14 @@ static SysBusDeviceInfo musicpal_key_info = {
     .qdev.vmsd  = &musicpal_key_vmsd,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_6(void)
+{
+    register_vmstate_description(&musicpal_key_vmsd);
+}
+
+vmstate_init(init_vmstate_description_6);
+
 static struct arm_boot_info musicpal_binfo = {
     .loader_start = 0x0,
     .board_id = 0x20e,
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 5966359..270578b 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -773,6 +773,14 @@ static PCIDeviceInfo ne2000_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pci_ne2000);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void ne2000_register_devices(void)
 {
     pci_qdev_register(&ne2000_info);
diff --git a/hw/pc.c b/hw/pc.c
index 6939c04..5211b29 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -497,6 +497,14 @@ static ISADeviceInfo port92_info = {
     .init          = port92_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_port92_isa);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void port92_register(void)
 {
     isa_qdev_register(&port92_info);
diff --git a/hw/pci.c b/hw/pci.c
index 8b76cea..50b9a14 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -269,6 +269,14 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
     vmstate_register(NULL, -1, &vmstate_pcibus, bus);
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_pcibus);
+}
+
+vmstate_init(init_vmstate_description);
+
 PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
 {
     PCIBus *bus;
diff --git a/hw/pckbd.c b/hw/pckbd.c
index ae65c04..027f69e 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -433,6 +433,14 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
     qemu_register_reset(kbd_reset, s);
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_kbd);
+}
+
+vmstate_init(init_vmstate_description);
+
 typedef struct ISAKBDState {
     ISADevice dev;
     KBDState  kbd;
@@ -492,6 +500,14 @@ static ISADeviceInfo i8042_info = {
     .init          = i8042_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_kbd_isa);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void i8042_register(void)
 {
     isa_qdev_register(&i8042_info);
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 339a401..d3c2738 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -338,6 +338,14 @@ static PCIDeviceInfo pcnet_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pci_pcnet);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pci_pcnet_register_devices(void)
 {
     pci_qdev_register(&pcnet_info);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 358da58..1e5f379 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -364,6 +364,14 @@ static PCIDeviceInfo i440fx_info[] = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_piix3);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo i440fx_pcihost_info = {
     .init         = i440fx_pcihost_initfn,
     .qdev.name    = "i440FX-pcihost",
diff --git a/hw/pl031.c b/hw/pl031.c
index 8c2f9d0..5372e21 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -229,6 +229,14 @@ static SysBusDeviceInfo pl031_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pl031);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pl031_register_devices(void)
 {
     sysbus_register_withprop(&pl031_info);
diff --git a/hw/pl050.c b/hw/pl050.c
index b155cc0..4c2b279 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -171,6 +171,14 @@ static SysBusDeviceInfo pl050_kbd_info = {
     .qdev.vmsd = &vmstate_pl050,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pl050);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo pl050_mouse_info = {
     .init = pl050_init_mouse,
     .qdev.name  = "pl050_mouse",
@@ -178,6 +186,14 @@ static SysBusDeviceInfo pl050_mouse_info = {
     .qdev.vmsd = &vmstate_pl050,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_pl050);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void pl050_register_devices(void)
 {
     sysbus_register_withprop(&pl050_kbd_info);
diff --git a/hw/pl080.c b/hw/pl080.c
index 901f04a..1c6198b 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -388,6 +388,14 @@ static SysBusDeviceInfo pl080_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pl080);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo pl081_info = {
     .init = pl081_init,
     .qdev.name = "pl081",
@@ -396,6 +404,14 @@ static SysBusDeviceInfo pl081_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_pl080);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 /* The PL080 and PL081 are the same except for the number of channels
    they implement (8 and 2 respectively).  */
 static void pl080_register_devices(void)
diff --git a/hw/pl110.c b/hw/pl110.c
index 06d2dfa..9073a40 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -405,6 +405,14 @@ static SysBusDeviceInfo pl110_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pl110);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo pl110_versatile_info = {
     .init = pl110_versatile_init,
     .qdev.name = "pl110_versatile",
@@ -413,6 +421,14 @@ static SysBusDeviceInfo pl110_versatile_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_pl110);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void pl110_register_devices(void)
 {
     sysbus_register_withprop(&pl110_info);
diff --git a/hw/pl190.c b/hw/pl190.c
index 75f2ba1..a03db5c 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -270,6 +270,14 @@ static SysBusDeviceInfo pl190_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pl190);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pl190_register_devices(void)
 {
     sysbus_register_withprop(&pl190_info);
diff --git a/hw/ps2.c b/hw/ps2.c
index 91b73e0..c77d5fc 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -615,6 +615,14 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
     return s;
 }
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ps2_keyboard);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
 {
     PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
@@ -626,3 +634,11 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
     qemu_register_reset(ps2_mouse_reset, s);
     return s;
 }
+
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_ps2_mouse);
+}
+
+vmstate_init(init_vmstate_description_1);
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 9b95e2c..d8f2943 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1293,6 +1293,14 @@ static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = {
     .qdev.vmsd  = &vmstate_pxa2xx_rtc_regs,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_rtc_regs);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 /* I2C Interface */
 typedef struct {
     i2c_slave i2c;
@@ -1595,6 +1603,14 @@ static SysBusDeviceInfo pxa2xx_i2c_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_i2c);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 /* PXA Inter-IC Sound Controller */
 static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s)
 {
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index a67498b..6d5fb56 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -561,6 +561,14 @@ static SysBusDeviceInfo pxa2xx_dma_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_dma);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pxa2xx_dma_register(void)
 {
     sysbus_register_withprop(&pxa2xx_dma_info);
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index e9a5361..fa6abba 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -309,6 +309,14 @@ static SysBusDeviceInfo pxa2xx_pic_info = {
     .qdev.vmsd  = &vmstate_pxa2xx_pic_regs,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_pic_regs);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void pxa2xx_pic_register(void)
 {
     sysbus_register_withprop(&pxa2xx_pic_info);
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index f777a21..db0603e 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -496,6 +496,14 @@ static SysBusDeviceInfo pxa25x_timer_dev_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_timer_regs);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo pxa27x_timer_dev_info = {
     .init       = pxa2xx_timer_init,
     .qdev.name  = "pxa27x-timer",
@@ -510,6 +518,14 @@ static SysBusDeviceInfo pxa27x_timer_dev_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_pxa2xx_timer_regs);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void pxa2xx_timer_register(void)
 {
     sysbus_register_withprop(&pxa25x_timer_dev_info);
diff --git a/hw/qxl.c b/hw/qxl.c
index fe4212b..2a0d090 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1504,6 +1504,14 @@ static PCIDeviceInfo qxl_info_primary = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&qxl_vmstate);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static PCIDeviceInfo qxl_info_secondary = {
     .qdev.name    = "qxl",
     .qdev.desc    = "Spice QXL GPU (secondary)",
@@ -1522,6 +1530,14 @@ static PCIDeviceInfo qxl_info_secondary = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&qxl_vmstate);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void qxl_register(void)
 {
     pci_qdev_register(&qxl_info_primary);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 0ba51fc..3b2f61e 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3269,6 +3269,14 @@ static const VMStateDescription vmstate_rtl8139 = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_rtl8139_hotplug_ready);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 /***********************************************************/
 /* PCI RTL8139 definitions */
 
@@ -3422,6 +3430,14 @@ static PCIDeviceInfo rtl8139_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_rtl8139);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void rtl8139_register_devices(void)
 {
     pci_qdev_register(&rtl8139_info);
diff --git a/hw/sb16.c b/hw/sb16.c
index a76df1b..c98546a 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1413,6 +1413,14 @@ static ISADeviceInfo sb16_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_sb16);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void sb16_register (void)
 {
     isa_qdev_register (&sb16_info);
diff --git a/hw/sbi.c b/hw/sbi.c
index 53f66f2..53a236c 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -140,6 +140,14 @@ static SysBusDeviceInfo sbi_info = {
     .qdev.reset = sbi_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_sbi);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void sbi_register_devices(void)
 {
     sysbus_register_withprop(&sbi_info);
diff --git a/hw/serial.c b/hw/serial.c
index 0ee61dd..c7ba97c 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -804,8 +804,6 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
     s->chr = chr;
     serial_init_core(s);
 
-    vmstate_register(NULL, base, &vmstate_serial, s);
-
     register_ioport_write(base, 8, 1, serial_ioport_write, s);
     register_ioport_read(base, 8, 1, serial_ioport_read, s);
     return s;
@@ -971,6 +969,14 @@ static ISADeviceInfo serial_isa_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_isa_serial);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void serial_register_devices(void)
 {
     isa_qdev_register(&serial_isa_info);
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index a83e5b8..8b3bdb5 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -455,6 +455,14 @@ static SysBusDeviceInfo slavio_intctl_info = {
     .qdev.reset = slavio_intctl_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_intctl);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void slavio_intctl_register_devices(void)
 {
     sysbus_register_withprop(&slavio_intctl_info);
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 198360d..0b415b9 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -484,6 +484,14 @@ static SysBusDeviceInfo slavio_misc_info = {
     .qdev.reset  = slavio_misc_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_misc);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static SysBusDeviceInfo apc_info = {
     .init = apc_init1,
     .qdev.name  = "apc",
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 5511313..0f95113 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -416,6 +416,14 @@ static SysBusDeviceInfo slavio_timer_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_slavio_timer);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void slavio_timer_register_devices(void)
 {
     sysbus_register_withprop(&slavio_timer_info);
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index dafea5c..63b4507 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -774,6 +774,14 @@ static SysBusDeviceInfo smc91c111_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_smc91c111);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void smc91c111_register_devices(void)
 {
     sysbus_register_withprop(&smc91c111_info);
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index e75694b..d8be398 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -297,6 +297,14 @@ static SysBusDeviceInfo sparc32_dma_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_dma);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void sparc32_dma_register_devices(void)
 {
     sysbus_register_withprop(&sparc32_dma_info);
diff --git a/hw/spitz.c b/hw/spitz.c
index 006f7a9..1078486 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1043,6 +1043,14 @@ static SysBusDeviceInfo sl_nand_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_sl_nand_info);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static VMStateDescription vmstate_spitz_kbd = {
     .name = "spitz-keyboard",
     .version_id = 1,
@@ -1067,6 +1075,14 @@ static SysBusDeviceInfo spitz_keyboard_info = {
     },
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_spitz_kbd);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static const VMStateDescription vmstate_corgi_ssp_regs = {
     .name = "corgi-ssp",
     .version_id = 1,
@@ -1086,6 +1102,14 @@ static SSISlaveInfo corgi_ssp_info = {
     .transfer = corgi_ssp_transfer
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_2(void)
+{
+    register_vmstate_description(&vmstate_corgi_ssp_regs);
+}
+
+vmstate_init(init_vmstate_description_2);
+
 static const VMStateDescription vmstate_spitz_lcdtg_regs = {
     .name = "spitz-lcdtg",
     .version_id = 1,
@@ -1106,6 +1130,14 @@ static SSISlaveInfo spitz_lcdtg_info = {
     .transfer = spitz_lcdtg_transfer
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_3(void)
+{
+    register_vmstate_description(&vmstate_spitz_lcdtg_regs);
+}
+
+vmstate_init(init_vmstate_description_3);
+
 static void spitz_register_devices(void)
 {
     ssi_register_slave(&corgi_ssp_info);
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 108c068..dc3012d 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -304,6 +304,14 @@ static I2CSlaveInfo ssd0303_info = {
     .send = ssd0303_send
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ssd0303);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void ssd0303_register_devices(void)
 {
     i2c_register_slave(&ssd0303_info);
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index 5c7fdef..025ea92 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -216,6 +216,14 @@ static SysBusDeviceInfo sun4c_intctl_info = {
     .qdev.reset = sun4c_intctl_reset,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_sun4c_intctl);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void sun4c_intctl_register_devices(void)
 {
     sysbus_register_withprop(&sun4c_intctl_info);
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index bba69ee..bb24412 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -370,6 +370,14 @@ static SysBusDeviceInfo iommu_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_iommu);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void iommu_register_devices(void)
 {
     sysbus_register_withprop(&iommu_info);
diff --git a/hw/tcx.c b/hw/tcx.c
index 0e32830..40a771b 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -643,6 +643,14 @@ static SysBusDeviceInfo tcx_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_tcx);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void tcx_register_devices(void)
 {
     sysbus_register_withprop(&tcx_info);
diff --git a/hw/tmp105.c b/hw/tmp105.c
index f7e6f2b..9d3325c 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -236,6 +236,14 @@ static I2CSlaveInfo tmp105_info = {
     .send = tmp105_tx
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_tmp105);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void tmp105_register_devices(void)
 {
     i2c_register_slave(&tmp105_info);
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 8e74acc..2b570a6 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -868,6 +868,14 @@ static I2CSlaveInfo twl92230_info = {
     .send = menelaus_tx
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_menelaus);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void twl92230_register_devices(void)
 {
     i2c_register_slave(&twl92230_info);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c25362c..e8fff11 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -999,6 +999,14 @@ static struct USBDeviceInfo hid_info[] = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_usb_kbd);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void usb_hid_register_devices(void)
 {
     usb_qdev_register_many(hid_info);
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 3dd31ba..dfac0ed 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -583,6 +583,14 @@ static struct USBDeviceInfo hub_info = {
     .handle_destroy = usb_hub_handle_destroy,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_usb_hub);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void usb_hub_register_devices(void)
 {
     usb_qdev_register(&hub_info);
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 346db3e..bc8fc5b 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1207,6 +1207,14 @@ static PCIDeviceInfo uhci_info[] = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_uhci);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void uhci_register(void)
 {
     pci_qdev_register_many(uhci_info);
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 9f1bfcf..659359c 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -354,6 +354,14 @@ static SysBusDeviceInfo vpb_sic_info = {
     .qdev.no_user = 1,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_vpb_sic);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void versatilepb_register_devices(void)
 {
     sysbus_register_withprop(&vpb_sic_info);
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index fde0d56..5f1ef76 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -81,6 +81,14 @@ static ISADeviceInfo vga_info = {
     .init          = vga_initfn,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_vga_common);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void vga_register(void)
 {
     isa_qdev_register(&vga_info);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index ce9ec45..c91739f 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -116,6 +116,14 @@ static PCIDeviceInfo vga_info = {
     .romfile      = "vgabios-stdvga.bin",
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_vga_pci);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void vga_register(void)
 {
     pci_qdev_register(&vga_info);
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index 1113f33..f2de7d8 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -282,6 +282,14 @@ static ISADeviceInfo vmmouse_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_vmmouse);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void vmmouse_dev_register(void)
 {
     isa_qdev_register(&vmmouse_info);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 4656767..106c9b4 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1318,6 +1318,14 @@ static PCIDeviceInfo vmsvga_info = {
     .romfile      = "vgabios-vmware.bin",
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_vmware_vga);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void vmsvga_register(void)
 {
     pci_qdev_register(&vmsvga_info);
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 818460d..62b8c63 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -522,6 +522,14 @@ static PCIDeviceInfo via_pm_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_acpi);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void vt82c686b_pm_register(void)
 {
     pci_qdev_register(&via_pm_info);
@@ -587,6 +595,14 @@ static PCIDeviceInfo via_info = {
     .config_write = vt82c686b_write_config,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_1(void)
+{
+    register_vmstate_description(&vmstate_via);
+}
+
+vmstate_init(init_vmstate_description_1);
+
 static void vt82c686b_register(void)
 {
     pci_qdev_register(&via_info);
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 4a7fba7..99f3c9b 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -439,6 +439,14 @@ static PCIDeviceInfo i6300esb_info = {
     .init         = i6300esb_init,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_i6300esb);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void i6300esb_register_devices(void)
 {
     watchdog_add_model(&model);
diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c
index 81f22d0..4cd24b9 100644
--- a/hw/wdt_ib700.c
+++ b/hw/wdt_ib700.c
@@ -128,6 +128,14 @@ static ISADeviceInfo wdt_ib700_info = {
     .init       = wdt_ib700_init,
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_ib700);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void wdt_ib700_register_devices(void)
 {
     watchdog_add_model(&model);
diff --git a/hw/wm8750.c b/hw/wm8750.c
index c9c6744..dc46577 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -699,6 +699,14 @@ static I2CSlaveInfo wm8750_info = {
     .send = wm8750_tx
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_wm8750);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void wm8750_register_devices(void)
 {
     i2c_register_slave(&wm8750_info);
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 5aa6a6b..f6fd902 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -194,6 +194,14 @@ static PCIDeviceInfo xio3130_downstream_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_xio3130_downstream);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void xio3130_downstream_register(void)
 {
     pci_qdev_register(&xio3130_downstream_info);
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index a7640f5..0b503ee 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -168,6 +168,14 @@ static PCIDeviceInfo xio3130_upstream_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_xio3130_upstream);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void xio3130_upstream_register(void)
 {
     pci_qdev_register(&xio3130_upstream_info);
diff --git a/hw/zaurus.c b/hw/zaurus.c
index c24aeb5..6ce61af 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -236,6 +236,14 @@ static SysBusDeviceInfo scoop_sysbus_info = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description_0(void)
+{
+    register_vmstate_description(&vmstate_scoop_regs);
+}
+
+vmstate_init(init_vmstate_description_0);
+
 static void scoop_register(void)
 {
     sysbus_register_withprop(&scoop_sysbus_info);
diff --git a/module.h b/module.h
index 9263f1c..70c33a5 100644
--- a/module.h
+++ b/module.h
@@ -24,12 +24,14 @@ typedef enum {
     MODULE_INIT_BLOCK,
     MODULE_INIT_DEVICE,
     MODULE_INIT_MACHINE,
+    MODULE_INIT_VMSTATE,
     MODULE_INIT_MAX
 } module_init_type;
 
 #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
 #define device_init(function) module_init(function, MODULE_INIT_DEVICE)
 #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
+#define vmstate_init(function) module_init(function, MODULE_INIT_MACHINE)
 
 void register_module_init(void (*fn)(void), module_init_type type);
 
diff --git a/savevm.c b/savevm.c
index 03fce62..4a37917 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1285,6 +1285,10 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
     }
 }
 
+void register_vmstate_description(const VMStateDescription *desc)
+{
+}
+
 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
                                     void *opaque);
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
diff --git a/target-i386/machine.c b/target-i386/machine.c
index d78eceb..3a40520 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -504,6 +504,14 @@ static const VMStateDescription vmstate_cpu = {
     }
 };
 
+/* Register the VMState Description to support VMState introspection */
+static void init_vmstate_description(void)
+{
+    register_vmstate_description(&vmstate_cpu);
+}
+
+vmstate_init(init_vmstate_description);
+
 void cpu_save(QEMUFile *f, void *opaque)
 {
     vmstate_save_state(f, &vmstate_cpu, opaque);
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  2:29   ` Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 04/11] sb16: fix migration quirk Anthony Liguori
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

For a schema to work, we need to make sure that each field name is unique.  We
have a number of derivative types today that reuse the base name.  This patch
fixes this.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/hw.h |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 81bbd7a..9a9012f 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -390,6 +390,16 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset       = vmstate_offset_value(_state, _field, _type),     \
 }
 
+#define VMSTATE_SINGLE_TEST_HACK(_field, _state, _test, _version, _info, _type) { \
+    .name         = (stringify(_field) "-hack"),                     \
+    .version_id   = (_version),                                      \
+    .field_exists = (_test),                                         \
+    .size         = sizeof(_type),                                   \
+    .info         = &(_info),                                        \
+    .flags        = VMS_SINGLE,                                      \
+    .offset       = vmstate_offset_value(_state, _field, _type),     \
+}
+
 #define VMSTATE_POINTER(_field, _state, _version, _info, _type) {    \
     .name       = (stringify(_field)),                               \
     .version_id = (_version),                                        \
@@ -419,7 +429,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
 }
 
 #define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
-    .name         = (stringify(_field)),                              \
+    .name         = (stringify(_field) "-" stringify(_test)),         \
     .field_exists = (_test),                                          \
     .num          = (_num),                                           \
     .info         = &(_info),                                         \
@@ -429,7 +439,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
 }
 
 #define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \
-    .name       = (stringify(_field)),                               \
+    .name       = (stringify(_field) "[" stringify(_start) "]"),      \
     .version_id = (_version),                                        \
     .num        = (_num),                                            \
     .info       = &(_info),                                          \
@@ -621,7 +631,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
 }
 
 #define VMSTATE_UNUSED_BUFFER(_test, _version, _size) {              \
-    .name         = "unused",                                        \
+    .name         = "unused" stringify(__LINE__),                    \
     .field_exists = (_test),                                         \
     .version_id   = (_version),                                      \
     .size         = (_size),                                         \
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 04/11] sb16: fix migration quirk
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (2 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  9:51   ` [Qemu-devel] " Juan Quintela
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 05/11] vga-isa: fix migration by breaking it Anthony Liguori
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

We seem to migrate the same field twice.  It's been this way since Fabrice
committed the original file.  Since semantically, we basically ignore the first
value, make this an unused entry.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/sb16.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/sb16.c b/hw/sb16.c
index c98546a..1c30e4c 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -77,6 +77,7 @@ typedef struct SB16State {
 
     int v2x6;
 
+    uint8_t csp_param_dummy;
     uint8_t csp_param;
     uint8_t csp_value;
     uint8_t csp_mode;
@@ -1313,7 +1314,7 @@ static const VMStateDescription vmstate_sb16 = {
         VMSTATE_INT32(can_write, SB16State),
         VMSTATE_INT32(v2x6, SB16State),
 
-        VMSTATE_UINT8(csp_param, SB16State),
+        VMSTATE_UINT8(csp_param_dummy, SB16State),
         VMSTATE_UINT8(csp_value, SB16State),
         VMSTATE_UINT8(csp_mode, SB16State),
         VMSTATE_UINT8(csp_param, SB16State),
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 05/11] vga-isa: fix migration by breaking it
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (3 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 04/11] sb16: fix migration quirk Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  9:54   ` [Qemu-devel] " Juan Quintela
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 06/11] fdc: fix migration of non-ISA fdc devices Anthony Liguori
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

This is pretty sad.  We use the same section name for vga-isa as we do for
vga-pci even though we use separate formats.  This breaks the live migration
protocol because we may misinterpret the vga-isa as a vga-pci device.

vga-isa should use it's own wrapper just like vga-pci does.  That's what we do
in this patch.

Signed-by-off: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/vga-isa.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 5f1ef76..eaae2e0 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -72,10 +72,19 @@ static int vga_initfn(ISADevice *dev)
     return 0;
 }
 
+static const VMStateDescription vmstate_vga_isa = {
+    .name = "isa-vga",
+    .version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_STRUCT(state, ISAVGAState, 0, vmstate_vga_common, VGACommonState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
 static ISADeviceInfo vga_info = {
     .qdev.name     = "isa-vga",
     .qdev.size     = sizeof(ISAVGAState),
-    .qdev.vmsd     = &vmstate_vga_common,
+    .qdev.vmsd     = &vmstate_vga_isa,
     .qdev.reset     = vga_reset_isa,
     .qdev.no_user  = 1,
     .init          = vga_initfn,
@@ -84,7 +93,7 @@ static ISADeviceInfo vga_info = {
 /* Register the VMState Description to support VMState introspection */
 static void init_vmstate_description_0(void)
 {
-    register_vmstate_description(&vmstate_vga_common);
+    register_vmstate_description(&vmstate_vga_isa);
 }
 
 vmstate_init(init_vmstate_description_0);
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 06/11] fdc: fix migration of non-ISA fdc devices
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (4 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 05/11] vga-isa: fix migration by breaking it Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names Anthony Liguori
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

Again, we are not using a unique name for non-ISA fdc devices and as a result,
we may misinterpret an ISA fdc device as a non-ISA fdc device.

In this case, both ISA fdc and non-ISA fdc are using too generic of a name.
Since ISA fdc is more common, let it keep the old name.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/fdc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index 4b02dce..9432d09 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1947,7 +1947,7 @@ static void init_vmstate_description_0(void)
 vmstate_init(init_vmstate_description_0);
 
 static const VMStateDescription vmstate_sysbus_fdc ={
-    .name = "fdc",
+    .name = "sysbus-fdc",
     .version_id = 2,
     .minimum_version_id = 2,
     .fields = (VMStateField []) {
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (5 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 06/11] fdc: fix migration of non-ISA fdc devices Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  9:58   ` [Qemu-devel] " Juan Quintela
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 08/11] fw_cfg: make sure all VMState fields are unique Anthony Liguori
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

I don't fully understand this hack business but we need field to be unique so..

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/eeprom93xx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
index cfa695d..f1d75ec 100644
--- a/hw/eeprom93xx.c
+++ b/hw/eeprom93xx.c
@@ -114,7 +114,7 @@ static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
 };
 
 #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
-    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
+    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
 
 static bool is_old_eeprom_version(void *opaque, int version_id)
 {
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 08/11] fw_cfg: make sure all VMState fields are unique.
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (6 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 09/11] pckbd: make non-ISA pckbd use a unique name Anthony Liguori
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/fw_cfg.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 67603a9..fd0c5ce 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -194,7 +194,7 @@ static const VMStateInfo vmstate_hack_uint32_as_uint16 = {
 };
 
 #define VMSTATE_UINT16_HACK(_f, _s, _t)                                    \
-    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint32_as_uint16, uint32_t)
+    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint32_as_uint16, uint32_t)
 
 
 static bool is_version_1(void *opaque, int version_id)
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 09/11] pckbd: make non-ISA pckbd use a unique name
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (7 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 08/11] fw_cfg: make sure all VMState fields are unique Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
  10 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

Another problem with non-PC versions of devices reusing the PC section name.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/pckbd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/pckbd.c b/hw/pckbd.c
index 027f69e..7e90388 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -366,7 +366,7 @@ static void kbd_reset(void *opaque)
 }
 
 static const VMStateDescription vmstate_kbd = {
-    .name = "pckbd",
+    .name = "mm-pckbd",
     .version_id = 3,
     .minimum_version_id = 3,
     .minimum_version_id_old = 3,
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (8 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 09/11] pckbd: make non-ISA pckbd use a unique name Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
  10 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

This ends up being pretty slick as we can store the JSON schema in the tree and
then use a test wrapper to validate whether fields change.

Current schema will come with the test wrapper.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/hw.h         |    2 +
 qemu-options.hx |   10 ++++++++
 savevm.c        |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vl.c            |   10 ++++++++
 4 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 9a9012f..531ee30 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -927,4 +927,6 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
 
 void register_vmstate_description(const VMStateDescription *desc);
 
+void vmstate_dump_schema(void);
+
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index ef60730..0faaea5 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2368,6 +2368,16 @@ Specify a trace file to log output traces to.
 ETEXI
 #endif
 
+DEF("vmstate-dump", 0, QEMU_OPTION_vmstate_dump,
+    "-vmstate-dump   output the current VMState schema and exit\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -vmstate-dump
+@findex -vmstate-dump
+This option is only used for an internal test suite.  The output format may
+change in the future.
+ETEXI
+
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
diff --git a/savevm.c b/savevm.c
index 4a37917..d35ce8d 100644
--- a/savevm.c
+++ b/savevm.c
@@ -82,6 +82,7 @@
 #include "migration.h"
 #include "qemu_socket.h"
 #include "qemu-queue.h"
+#include "qemu-objects.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
@@ -1285,8 +1286,69 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
     }
 }
 
+typedef struct VmsdEntry
+{
+    const VMStateDescription *desc;
+    QTAILQ_ENTRY(VmsdEntry) node;
+} VmsdEntry;
+
+static QTAILQ_HEAD(, VmsdEntry) vmsd_description_list =
+    QTAILQ_HEAD_INITIALIZER(vmsd_description_list);
+
 void register_vmstate_description(const VMStateDescription *desc)
 {
+    VmsdEntry *e = qemu_mallocz(sizeof(*e));
+
+    e->desc = desc;
+    QTAILQ_INSERT_TAIL(&vmsd_description_list, e, node);
+}
+
+static QDict *vmstate_dump_state(const VMStateDescription *desc)
+{
+    VMStateField *f;
+    QDict *ret;
+
+    ret = qdict_new();
+
+    qdict_put(ret, "__version__", qint_from_int(desc->version_id));
+    for (f = desc->fields; f && f->name; f++) {
+        if (qdict_haskey(ret, f->name)) {
+            fprintf(stderr, "vmstate: duplicate key `%s' in `%s'\n",
+                    f->name, desc->name);
+            exit(1);
+        }
+        if (f->vmsd) {
+            qdict_put(ret, f->name, vmstate_dump_state(f->vmsd));
+        } else {
+            qdict_put(ret, f->name, qstring_from_str(f->info->name));
+        }
+    }
+
+    return ret;
+}
+
+void vmstate_dump_schema(void)
+{
+    QDict *items;
+    QString *str;
+    VmsdEntry *e;
+
+    items = qdict_new();
+
+    QTAILQ_FOREACH(e, &vmsd_description_list, node) {
+        if (qdict_haskey(items, e->desc->name)) {
+            fprintf(stderr, "vmstate: duplicate devices of name `%s'\n",
+                    e->desc->name);
+            exit(1);
+        }
+        qdict_put(items, e->desc->name, vmstate_dump_state(e->desc));
+    }
+
+    str = qobject_to_json_pretty(QOBJECT(items));
+    printf("%s\n", qstring_get_str(str));
+
+    QDECREF(str);
+    QDECREF(items);
 }
 
 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
diff --git a/vl.c b/vl.c
index dbb927d..f91875b 100644
--- a/vl.c
+++ b/vl.c
@@ -2038,6 +2038,7 @@ int main(int argc, char **argv, char **envp)
 #endif
     int defconfig = 1;
     const char *trace_file = NULL;
+    bool vmstate_dump = false;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2876,6 +2877,9 @@ int main(int argc, char **argv, char **envp)
                     fclose(fp);
                     break;
                 }
+            case QEMU_OPTION_vmstate_dump:
+                vmstate_dump = true;
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -3124,6 +3128,12 @@ int main(int argc, char **argv, char **envp)
     }
     qemu_add_globals();
 
+    if (vmstate_dump) {
+        module_call_init(MODULE_INIT_VMSTATE);
+        vmstate_dump_schema();
+        exit(0);
+    }
+
     machine->init(ram_size, boot_devices,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 
-- 
1.7.0.4

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

* [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
                   ` (9 preceding siblings ...)
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema Anthony Liguori
@ 2011-03-23  0:16 ` Anthony Liguori
  2011-03-23  2:31   ` Anthony Liguori
                     ` (2 more replies)
  10 siblings, 3 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori, Juan Quintela

We've had lots of issues surrounding live migration breaking.  This is because
we haven't had a good way to validate that what we're migrating isn't changing
underneath of us.

This test works by first converting the in-tree schema to C source as a string.
This is built into the test case.  The test case will then query QEMU for the
current schema.

It converts both strings to QObjects via the JSON parser and then does a
recursive diff.  Unlike a simple diff command, this lets us say exactly what you
did to break migration.  For instance, you get error messages like:

  You broke migration by changing the type of field 'par' in device 'cpu',
  version 1 from 'uint32' to 'uint64'.

It only covers devices that support VMState and it currently doesn't look at
subsections yet.

The in-tree schema needs to be updated whenever migration changes but this ends
up being a very nice way to ensure that we're reviewing migration protocol
changes.

The test case is built in the default build, and can be run by `make check'.

I've also added a `make check-help' to encourage people to use more specific
check commands.

Finally, there's a make test-report which generates a nice HTML version of the
test output.

The current test case would catch the couple recent migration regressions.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile            |   34 ++-
 scripts/json2c.sh   |    5 +
 test-vmstate.c      |  142 +++++++
 vmstate/schema.json | 1176 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1355 insertions(+), 2 deletions(-)
 create mode 100755 scripts/json2c.sh
 create mode 100644 test-vmstate.c
 create mode 100644 vmstate/schema.json

diff --git a/Makefile b/Makefile
index 5f9b120..f813208 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,8 @@ Makefile: ;
 configure: ;
 
 .PHONY: all clean cscope distclean dvi html info install install-doc \
-	pdf recurse-all speed tar tarbin test build-all
+	pdf recurse-all speed tar tarbin test build-all check-vmstate check \
+        check-help
 
 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
@@ -71,7 +72,9 @@ defconfig:
 
 -include config-all-devices.mak
 
-build-all: $(DOCS) $(TOOLS) recurse-all
+TESTS=test-vmstate
+
+build-all: $(DOCS) $(TOOLS) $(TESTS) recurse-all
 
 config-host.h: config-host.h-timestamp
 config-host.h-timestamp: config-host.mak
@@ -146,6 +149,33 @@ trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
 
 simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
 
+vmstate-schema.c: $(SRC_PATH)/vmstate/schema.json
+	$(call quiet-command,$(SRC_PATH)/scripts/json2c.sh < $^ > $@,"  GEN   $@")
+
+test-vmstate-obj-y  = qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o
+test-vmstate-obj-y += json-streamer.o json-lexer.o json-parser.o 
+test-vmstate-obj-y += vmstate-schema.o qemu-malloc.o $(oslib-obj-y)
+
+test-vmstate: test-vmstate.o $(test-vmstate-obj-y)
+
+check-vmstate: test-vmstate
+	@./test-vmstate
+
+check: check-vmstate
+
+check-help:
+	@echo " make check             run all check tests against build"
+	@echo " make check-vmstate     run VMState checks"
+	@echo " make test-report.html  make an HTML report of make check"
+
+test-report.log: $(TESTS)
+	@gtester -k -o $@ $^
+
+test-report.html: test-report.log
+	@gtester-report $^ > $@
+
+-include $(SUBDIR_DEVICES_MAK_DEP)
+
 version.o: $(SRC_PATH)/version.rc config-host.mak
 	$(call quiet-command,$(WINDRES) -I. -o $@ $<,"  RC    $(TARGET_DIR)$@")
 
diff --git a/scripts/json2c.sh b/scripts/json2c.sh
new file mode 100755
index 0000000..0947211
--- /dev/null
+++ b/scripts/json2c.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo 'const char *vmstate_schema_json = '
+sed -e "s:\":\':g;s:^\(.*\)$:    \"\1\":g"
+echo '    ;'
diff --git a/test-vmstate.c b/test-vmstate.c
new file mode 100644
index 0000000..e2ac711
--- /dev/null
+++ b/test-vmstate.c
@@ -0,0 +1,142 @@
+/*
+ * VMState test case
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <glib.h>
+#include "qemu-objects.h"
+
+/* TODO
+ * 1) verify subsection semantics
+ */
+
+extern const char *vmstate_schema_json;
+
+static void compare_section(const char *device, QDict *old, QDict *new)
+{
+    const QDictEntry *e;
+    int old_version, new_version;
+
+    old_version = qdict_get_int(old, "__version__");
+    new_version = qdict_get_int(new, "__version__");
+
+    if (old_version != new_version) {
+        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
+                new_version, device, old_version);
+    }
+
+    for (e = qdict_first(new); e; e = qdict_next(new, e)) {
+        QObject *old_field, *new_field;
+
+        if (strcmp(e->key, "__version__") == 0) {
+            continue;
+        }
+
+        if (!qdict_haskey(old, e->key)) {
+            g_error("You broke migration by adding a new field, `%s', to device `%s', version %d, without changing version.\n",
+                    e->key, device, new_version);
+        }
+
+        old_field = qdict_get(old, e->key);
+        new_field = qdict_get(new, e->key);
+
+        if (qobject_type(old_field) != qobject_type(new_field)) {
+            g_error("You broke migration by changing the type of field, `%s', in device `%s', version %d, without changing version.\n",
+                    e->key, device, new_version);
+        }
+
+        if (qobject_type(old_field) == QTYPE_QSTRING) {
+            const char *old_field_type, *new_field_type;
+
+            old_field_type = qdict_get_str(old, e->key);
+            new_field_type = qdict_get_str(new, e->key);
+
+            if (strcmp(old_field_type, new_field_type) != 0) {
+                g_error("You broke migration by changing the type of field, `%s' in device `%s', version %d from `%s' to `%s'\n",
+                        e->key, device, new_version, old_field_type, new_field_type);
+            }
+        } else {
+            char buffer[1024];
+
+            snprintf(buffer, sizeof(buffer), "%s.%s", device, e->key);
+            compare_section(buffer, qobject_to_qdict(old_field), qobject_to_qdict(new_field));
+        }
+    }
+
+    for (e = qdict_first(old); e; e = qdict_next(old, e)) {
+        if (!qdict_haskey(new, e->key)) {
+            g_error("You broke migration by removing the field, `%s', from device `%s', version %d, without changing version.\n",
+                    e->key, device, new_version);
+        }
+    }
+}
+
+static void compare_schema(QDict *old, QDict *new)
+{
+    const QDictEntry *e;
+
+    for (e = qdict_first(new); e; e = qdict_next(new, e)) {
+        if (!qdict_haskey(old, e->key)) {
+            g_error("New device introduced, '%s', that's not in current schema.  Please update.\n", e->key);
+        }
+
+        compare_section(e->key, qobject_to_qdict(qdict_get(old, e->key)),
+                        qobject_to_qdict(qdict_get(new, e->key)));
+    }
+}
+
+static QObject *read_current_schema(void)
+{
+    char buffer[65536];
+    int fd;
+    int ret;
+    size_t offset = 0;
+    ssize_t len;
+
+    ret = system("i386-softmmu/qemu -vmstate-dump > /tmp/schema.json");
+    g_assert_cmpint(ret, ==, 0);
+
+    fd = open("/tmp/schema.json", O_RDONLY);
+    g_assert_cmpint(fd, !=, -1);
+
+    do {
+        len = read(fd, buffer + offset, sizeof(buffer) - 1 - offset);
+        offset += len;
+    } while (len > 0);
+
+    buffer[offset] = 0;
+
+    close(fd);
+
+    return qobject_from_json(buffer);
+}
+
+static void test_missing_fields(void)
+{
+    QObject *schema = qobject_from_json(vmstate_schema_json);
+    QObject *cur_schema = read_current_schema();
+
+    compare_schema(qobject_to_qdict(schema), qobject_to_qdict(cur_schema));
+
+    qobject_decref(schema);
+    qobject_decref(cur_schema);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_func("/latest/schema-change", test_missing_fields);
+
+    g_test_run();
+
+    return 0;
+}
diff --git a/vmstate/schema.json b/vmstate/schema.json
new file mode 100644
index 0000000..23483ab
--- /dev/null
+++ b/vmstate/schema.json
@@ -0,0 +1,1176 @@
+{
+    "cpu": {
+        "mcg_cap": "uint64", 
+        "a20_mask": "int32", 
+        "tsc_offset": "uint64", 
+        "idt": {
+            "flags": "uint32", 
+            "limit": "uint32", 
+            "selector": "uint32", 
+            "base": "uint32", 
+            "__version__": 1
+        }, 
+        "intercept_cr_write": "uint16", 
+        "nmi_injected": "uint8", 
+        "vm_hsave": "uint64", 
+        "fpregs-fpregs_is_0": "fpreg", 
+        "fpus_vmstate": "uint16", 
+        "interrupt_injected": "int32", 
+        "intercept_exceptions": "uint32", 
+        "system_time_msr": "uint64", 
+        "hflags2": "uint32", 
+        "sysenter_eip": "uint32", 
+        "vm_vmcb": "uint64", 
+        "mtrr_fixed": "uint64", 
+        "mce_banks": "uint64", 
+        "nmi_pending": "uint8", 
+        "fptag_vmstate": "uint16", 
+        "pat": "uint64", 
+        "intercept_dr_read": "uint16", 
+        "mcg_ctl": "uint64", 
+        "v_tpr": "uint8", 
+        "hflags": "uint32", 
+        "ymmh_regs": {
+            "_q[1]": "uint64", 
+            "_q[0]": "uint64", 
+            "__version__": 1
+        }, 
+        "mp_state": "uint32", 
+        "dr": "uint32", 
+        "mcg_status": "uint64", 
+        "cr[4]": "uint32", 
+        "cr[3]": "uint32", 
+        "cr[2]": "uint32", 
+        "cr[0]": "uint32", 
+        "xcr0": "uint64", 
+        "xmm_regs": {
+            "_q[1]": "uint64", 
+            "_q[0]": "uint64", 
+            "__version__": 1
+        }, 
+        "mtrr_deftype": "uint64", 
+        "intercept": "uint64", 
+        "exception_injected": "int32", 
+        "intercept_cr_read": "uint16", 
+        "gdt": {
+            "flags": "uint32", 
+            "limit": "uint32", 
+            "selector": "uint32", 
+            "base": "uint32", 
+            "__version__": 1
+        }, 
+        "sipi_vector": "uint32", 
+        "sysenter_cs": "uint32", 
+        "eip": "uint32", 
+        "tsc": "uint64", 
+        "ldt": {
+            "flags": "uint32", 
+            "limit": "uint32", 
+            "selector": "uint32", 
+            "base": "uint32", 
+            "__version__": 1
+        }, 
+        "soft_interrupt": "uint8", 
+        "regs": "uint32", 
+        "sysenter_esp": "uint32", 
+        "fpuc": "uint16", 
+        "wall_clock_msr": "uint64", 
+        "smbase": "uint32", 
+        "xstate_bv": "uint64", 
+        "mxcsr": "uint32", 
+        "halted": "uint32", 
+        "tsc_aux": "uint64", 
+        "eflags": "uint32", 
+        "fpregs-fpregs_is_1_no_mmx": "fpreg_1_no_mmx", 
+        "segs": {
+            "flags": "uint32", 
+            "limit": "uint32", 
+            "selector": "uint32", 
+            "base": "uint32", 
+            "__version__": 1
+        }, 
+        "tr": {
+            "flags": "uint32", 
+            "limit": "uint32", 
+            "selector": "uint32", 
+            "base": "uint32", 
+            "__version__": 1
+        }, 
+        "fpregs-fpregs_is_1_mmx": "fpreg_1_mmx", 
+        "intercept_dr_write": "uint16", 
+        "mtrr_var": {
+            "base": "uint64", 
+            "mask": "uint64", 
+            "__version__": 1
+        }, 
+        "__version__": 12, 
+        "has_error_code": "uint8", 
+        "fpregs_format_vmstate": "uint16"
+    }, 
+    "PCIBUS": {
+        "irq_count": "int32", 
+        "nirq": "int32 equal", 
+        "__version__": 1
+    }, 
+    "ne2000": {
+        "ne2000": {
+            "stop": "uint32", 
+            "imr": "uint8", 
+            "rsr": "uint8", 
+            "start": "uint32", 
+            "rsar": "uint32", 
+            "rcnt": "uint16", 
+            "phys": "buffer", 
+            "isr": "uint8", 
+            "dcfg": "uint8", 
+            "unused": "unused_buffer", 
+            "mem": "buffer", 
+            "mult": "buffer", 
+            "tsr": "uint8", 
+            "tpsr": "uint8", 
+            "tcnt": "uint16", 
+            "curpag": "uint8", 
+            "rxcr": "uint8", 
+            "boundary": "uint8", 
+            "__version__": 2, 
+            "cmd": "uint8"
+        }, 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 3
+    }, 
+    "isa-vga": {
+        "state": {
+            "ar_index": "uint8", 
+            "dac_cache": "buffer", 
+            "palette": "buffer", 
+            "dac_write_index": "uint8", 
+            "vbe_start_addr": "uint32", 
+            "vbe_line_offset": "uint32", 
+            "gr": "buffer", 
+            "msr": "uint8", 
+            "st01": "uint8", 
+            "st00": "uint8", 
+            "dac_state": "uint8", 
+            "vbe_bank_mask": "uint32", 
+            "dac_read_index": "uint8", 
+            "gr_index": "uint8", 
+            "vbe_index": "uint16", 
+            "ar_flip_flop": "int32", 
+            "cr": "buffer", 
+            "cr_index": "uint8", 
+            "vbe_regs": "uint16", 
+            "dac_sub_index": "uint8", 
+            "sr": "buffer", 
+            "is_vbe_vmstate": "uint8 equal", 
+            "bank_offset": "int32", 
+            "fcr": "uint8", 
+            "latch": "uint32", 
+            "sr_index": "uint8", 
+            "ar": "buffer", 
+            "__version__": 2
+        }, 
+        "__version__": 1
+    }, 
+    "hpet": {
+        "num_timers": "uint8", 
+        "isr": "uint64", 
+        "config": "uint64", 
+        "hpet_counter": "uint64", 
+        "timer": {
+            "tn": "uint8", 
+            "wrap_flag": "uint8", 
+            "period": "uint64", 
+            "config": "uint64", 
+            "fsb": "uint64", 
+            "qemu_timer": "timer", 
+            "__version__": 1, 
+            "cmp": "uint64"
+        }, 
+        "__version__": 2
+    }, 
+    "intel-hda": {
+        "st": {
+            "lvi": "uint32", 
+            "cbl": "uint32", 
+            "fmt": "uint32", 
+            "bdlp_ubase": "uint32", 
+            "ctl": "uint32", 
+            "__version__": 1, 
+            "bdlp_lbase": "uint32", 
+            "lpib": "uint32"
+        }, 
+        "wall_base_ns": "int64", 
+        "wall_clk": "uint32", 
+        "int_ctl": "uint32", 
+        "corb_size": "uint32", 
+        "rirb_size": "uint32", 
+        "dp_ubase": "uint32", 
+        "dp_lbase": "uint32", 
+        "corb_sts": "uint32", 
+        "rirb_sts": "uint32", 
+        "corb_rp": "uint32", 
+        "g_ctl": "uint32", 
+        "rirb_cnt": "uint32", 
+        "ics": "uint32", 
+        "icw": "uint32", 
+        "corb_wp": "uint32", 
+        "rirb_wp": "uint32", 
+        "state_sts": "uint32", 
+        "corb_ubase": "uint32", 
+        "rirb_ubase": "uint32", 
+        "corb_ctl": "uint32", 
+        "rirb_ctl": "uint32", 
+        "wake_en": "uint32", 
+        "irr": "uint32", 
+        "corb_lbase": "uint32", 
+        "rirb_lbase": "uint32", 
+        "int_sts": "uint32", 
+        "pci": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "rirb_count": "uint32", 
+        "__version__": 1
+    }, 
+    "serial": {
+        "state": {
+            "msr": "uint8", 
+            "mcr": "uint8", 
+            "fcr_vmstate": "uint8", 
+            "scr": "uint8", 
+            "iir": "uint8", 
+            "rbr": "uint8", 
+            "divider": "uint16", 
+            "ier": "uint8", 
+            "__version__": 3, 
+            "lsr": "uint8", 
+            "lcr": "uint8"
+        }, 
+        "__version__": 3
+    }, 
+    "vmmouse": {
+        "nb_queue": "uint16", 
+        "status": "uint16", 
+        "queue": "uint32", 
+        "queue_size": "int32 equal", 
+        "absolute": "uint8", 
+        "__version__": 0
+    }, 
+    "port92": {
+        "outport": "uint8", 
+        "__version__": 1
+    }, 
+    "ioh-3240-express-root-port": {
+        "port.br.dev.exp.aer_log": {
+            "log_max": "uint16", 
+            "log": {
+                "flags": "uint16", 
+                "header": "uint32", 
+                "status": "uint32", 
+                "prefix": "uint32", 
+                "__version__": 1, 
+                "source_id": "uint16"
+            }, 
+            "log_num": "uint16", 
+            "__version__": 1
+        }, 
+        "__version__": 1, 
+        "port.br.dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }
+    }, 
+    "ioapic": {
+        "ioredtbl": "uint64", 
+        "unused290": "unused_buffer", 
+        "irr": "uint32", 
+        "ioregsel": "uint8", 
+        "__version__": 3, 
+        "id": "uint8"
+    }, 
+    "xio3130-express-downstream-port": {
+        "port.br.dev.exp.aer_log": {
+            "log_max": "uint16", 
+            "log": {
+                "flags": "uint16", 
+                "header": "uint32", 
+                "status": "uint32", 
+                "prefix": "uint32", 
+                "__version__": 1, 
+                "source_id": "uint16"
+            }, 
+            "log_num": "uint16", 
+            "__version__": 1
+        }, 
+        "__version__": 1, 
+        "port.br.dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }
+    }, 
+    "ps2mouse": {
+        "mouse_type": "uint8", 
+        "mouse_wrap": "uint8", 
+        "common": {
+            "queue.count": "int32", 
+            "queue.data": "buffer", 
+            "queue.wptr": "int32", 
+            "write_cmd": "int32", 
+            "queue.rptr": "int32", 
+            "__version__": 3
+        }, 
+        "mouse_detect_state": "uint8", 
+        "mouse_sample_rate": "uint8", 
+        "mouse_resolution": "uint8", 
+        "mouse_buttons": "uint8", 
+        "__version__": 2, 
+        "mouse_status": "uint8", 
+        "mouse_dz": "int32", 
+        "mouse_dy": "int32", 
+        "mouse_dx": "int32"
+    }, 
+    "xio3130-express-upstream-port": {
+        "br.dev.exp.aer_log": {
+            "log_max": "uint16", 
+            "log": {
+                "flags": "uint16", 
+                "header": "uint32", 
+                "status": "uint32", 
+                "prefix": "uint32", 
+                "__version__": 1, 
+                "source_id": "uint16"
+            }, 
+            "log_num": "uint16", 
+            "__version__": 1
+        }, 
+        "br.dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 1
+    }, 
+    "e1000": {
+        "unused965": "unused_buffer", 
+        "unused964": "unused_buffer", 
+        "eecd_state.reading": "uint16", 
+        "mac_reg[MPC]": "uint32", 
+        "mac_reg[IMC]": "uint32", 
+        "tx.tcp": "int8", 
+        "mac_reg[WUFC]": "uint32", 
+        "mac_reg[GPRC]": "uint32", 
+        "tx.ip": "int8", 
+        "tx.data": "buffer", 
+        "mac_reg[TDH]": "uint32", 
+        "mac_reg[RDH]": "uint32", 
+        "tx.size": "uint16", 
+        "rxbuf_min_shift": "uint32", 
+        "mac_reg[VET]": "uint32", 
+        "mac_reg[TPT]": "uint32", 
+        "mac_reg[TDT]": "uint32", 
+        "mac_reg[RDT]": "uint32", 
+        "tx.sum_needed": "uint8", 
+        "mac_reg[VFTA]": "uint32", 
+        "mac_reg[TDBAL]": "uint32", 
+        "mac_reg[TDBAH]": "uint32", 
+        "mac_reg[RDBAL]": "uint32", 
+        "mac_reg[RDBAH]": "uint32", 
+        "tx.mss": "uint16", 
+        "phy_reg": "uint16", 
+        "mac_reg[EECD]": "uint32", 
+        "mac_reg[MTA]": "uint32", 
+        "mac_reg[PBA]": "uint32", 
+        "mac_reg[IMS]": "uint32", 
+        "mac_reg[ICS]": "uint32", 
+        "mac_reg[SWSM]": "uint32", 
+        "tx.header": "buffer", 
+        "mac_reg[TOTL]": "uint32", 
+        "mac_reg[TOTH]": "uint32", 
+        "mac_reg[TCTL]": "uint32", 
+        "mac_reg[RCTL]": "uint32", 
+        "tx.paylen": "uint32", 
+        "mac_reg[TPR]": "uint32", 
+        "mac_reg[ICR]": "uint32", 
+        "mac_reg[TXDCTL]": "uint32", 
+        "mac_reg[LEDCTL]": "uint32", 
+        "mac_reg[MDIC]": "uint32", 
+        "eecd_state.old_eecd": "uint32", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "eecd_state.bitnum_out": "uint16", 
+        "tx.tso_frames": "uint16", 
+        "mac_reg[TDLEN]": "uint32", 
+        "mac_reg[RDLEN]": "uint32", 
+        "eeprom_data": "uint16", 
+        "eecd_state.bitnum_in": "uint16", 
+        "mac_reg[MANC]": "uint32", 
+        "mac_reg[GPTC]": "uint32", 
+        "mac_reg[STATUS]": "uint32", 
+        "tx.hdr_len": "uint8", 
+        "mac_reg[TORL]": "uint32", 
+        "mac_reg[TORH]": "uint32", 
+        "mac_reg[EERD]": "uint32", 
+        "mac_reg[CTRL]": "uint32", 
+        "__version__": 2, 
+        "tx.tucse": "uint16", 
+        "tx.tucso": "uint8", 
+        "tx.tucss": "uint8", 
+        "tx.ipcse": "uint16", 
+        "tx.ipcso": "uint8", 
+        "tx.ipcss": "uint8", 
+        "eecd_state.val_in": "uint32", 
+        "mac_reg[RA]": "uint32", 
+        "rxbuf_size": "uint32"
+    }, 
+    "vmware_vga": {
+        "chip": {
+            "index": "int32", 
+            "scratch": "uint32", 
+            "fb_size": "int32", 
+            "guest": "uint32", 
+            "syncing": "int32", 
+            "enable": "int32", 
+            "svgaid": "uint32", 
+            "new_width": "int32", 
+            "config": "int32", 
+            "cursor.y": "int32", 
+            "cursor.x": "int32", 
+            "cursor.on": "int32", 
+            "cursor.id": "int32", 
+            "depth": "int32 equal", 
+            "new_height": "int32", 
+            "__version__": 0
+        }, 
+        "card": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 0
+    }, 
+    "rtl8139/hotplug_ready": {
+        "__version__": 1
+    }, 
+    "mc146818rtc": {
+        "current_tm.tm_mday": "int32", 
+        "current_tm.tm_wday": "int32", 
+        "period": "uint32", 
+        "next_second_time": "int64", 
+        "current_tm.tm_hour": "int32", 
+        "cmos_data": "buffer", 
+        "cmos_index": "uint8", 
+        "irq_coalesced": "uint32", 
+        "periodic_timer": "timer", 
+        "current_tm.tm_sec": "int32", 
+        "second_timer": "timer", 
+        "current_tm.tm_year": "int32", 
+        "second_timer2": "timer", 
+        "next_periodic_time": "int64", 
+        "__version__": 2, 
+        "current_tm.tm_min": "int32", 
+        "current_tm.tm_mon": "int32"
+    }, 
+    "uhci": {
+        "frame_timer": "timer", 
+        "frnum": "uint16", 
+        "ports": {
+            "ctrl": "uint16", 
+            "__version__": 1
+        }, 
+        "status2": "uint8", 
+        "status": "uint16", 
+        "fl_base_addr": "uint32", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "num_ports_vmstate": "uint8 equal", 
+        "expire_time": "int64", 
+        "__version__": 2, 
+        "sof_timing": "uint8", 
+        "cmd": "uint16", 
+        "intr": "uint16"
+    }, 
+    "PIIX3": {
+        "pci_irq_levels": "int32", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 3
+    }, 
+    "fdc": {
+        "state": {
+            "timer0": "uint8", 
+            "msr": "uint8", 
+            "status2": "uint8", 
+            "dor_vmstate": "uint8", 
+            "lock": "uint8", 
+            "dsr": "uint8", 
+            "data_len": "uint32", 
+            "tdr": "uint8", 
+            "data_dir": "uint8", 
+            "timer1": "uint8", 
+            "status0": "uint8", 
+            "config": "uint8", 
+            "pwrd": "uint8", 
+            "precomp_trk": "uint8", 
+            "data_pos": "uint32", 
+            "srb": "uint8", 
+            "sra": "uint8", 
+            "eot": "uint8", 
+            "status1": "uint8", 
+            "num_floppies": "uint8 equal", 
+            "drives": {
+                "track": "uint8", 
+                "head": "uint8", 
+                "sect": "uint8", 
+                "__version__": 1
+            }, 
+            "fifo": "uint8", 
+            "__version__": 2, 
+            "data_state": "uint8"
+        }, 
+        "__version__": 2
+    }, 
+    "cirrus_vga": {
+        "cirrus_vga": {
+            "cirrus_hidden_dac_lockindex": "uint8", 
+            "vga.ar_flip_flop": "int32", 
+            "vga.cr_index": "uint8", 
+            "vga.ar_index": "uint8", 
+            "vga.gr_index": "uint8", 
+            "vga.sr_index": "uint8", 
+            "cirrus_hidden_dac_data": "uint8", 
+            "vga.fcr": "uint8", 
+            "vga.bank_offset": "int32", 
+            "vga.dac_state": "uint8", 
+            "vga.latch": "uint32", 
+            "vga.dac_write_index": "uint8", 
+            "vga.dac_read_index": "uint8", 
+            "cirrus_shadow_gr0": "uint8", 
+            "hw_cursor_y": "uint32", 
+            "vga.dac_sub_index": "uint8", 
+            "hw_cursor_x": "uint32", 
+            "vga.st01": "uint8", 
+            "vga.st00": "uint8", 
+            "vga.cr": "buffer", 
+            "vga.ar": "buffer", 
+            "vga.gr": "buffer", 
+            "vga.sr": "buffer", 
+            "cirrus_shadow_gr1": "uint8", 
+            "vga.palette": "buffer", 
+            "vga.msr": "uint8", 
+            "__version__": 2, 
+            "vga.dac_cache": "buffer"
+        }, 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 2
+    }, 
+    "ib700_wdt": {
+        "timer": "timer", 
+        "__version__": 0
+    }, 
+    "usb-kbd": {
+        "kbd.keys": "int32", 
+        "idle": "uint8", 
+        "kbd.leds": "uint8", 
+        "n": "uint32", 
+        "protocol": "int32", 
+        "head": "uint32", 
+        "kbd.modifiers": "uint16", 
+        "dev": {
+            "state": "int32", 
+            "remote_wakeup": "int32", 
+            "addr": "uint8", 
+            "setup_len": "int32", 
+            "setup_state": "int32", 
+            "setup_buf": "uint8", 
+            "setup_index": "int32", 
+            "__version__": 1
+        }, 
+        "__version__": 1, 
+        "kbd.key": "uint8", 
+        "kbd.keycodes": "uint32"
+    }, 
+    "eeprom": {
+        "unused141": "unused_buffer", 
+        "command": "uint8", 
+        "addrbits": "uint8", 
+        "contents": "uint16", 
+        "writeable": "uint8", 
+        "size": "uint16 equal", 
+        "size-hack": "uint16_from_uint8", 
+        "address": "uint8", 
+        "tick": "uint8", 
+        "__version__": 20061113, 
+        "eedo": "uint8", 
+        "eesk": "uint8", 
+        "eecs": "uint8", 
+        "data": "uint16"
+    }, 
+    "hda-audio": {
+        "st": {
+            "gain_right": "uint32", 
+            "mute_right": "bool", 
+            "buf": "buffer", 
+            "channel": "uint32", 
+            "format": "uint32", 
+            "bpos": "uint32", 
+            "stream": "uint32", 
+            "__version__": 1, 
+            "gain_left": "uint32", 
+            "mute_left": "bool"
+        }, 
+        "running": "bool", 
+        "__version__": 1
+    }, 
+    "apic": {
+        "lvt": "uint32", 
+        "next_time": "int64", 
+        "divide_conf": "uint32", 
+        "dest_mode": "uint8", 
+        "icr": "uint32", 
+        "isr": "uint32", 
+        "esr": "uint32", 
+        "tmr": "uint32", 
+        "tpr": "uint8", 
+        "apicbase": "uint32", 
+        "irr": "uint32", 
+        "count_shift": "int32", 
+        "initial_count_load_time": "int64", 
+        "timer": "timer", 
+        "log_dest": "uint8", 
+        "__version__": 3, 
+        "id": "uint8", 
+        "spurious_vec": "uint32", 
+        "initial_count": "uint32", 
+        "arb_id": "uint8"
+    }, 
+    "lsiscsi": {
+        "sxfer": "uint8", 
+        "istat1": "uint8", 
+        "script_ram": "buffer", 
+        "respid1": "uint8", 
+        "temp": "uint32", 
+        "scratch": "buffer", 
+        "mmws": "uint32", 
+        "mmrs": "uint32", 
+        "sstat1": "uint8", 
+        "scntl1": "uint8", 
+        "ctest5": "uint8", 
+        "csbc": "uint32", 
+        "msg": "buffer", 
+        "sdid": "uint8", 
+        "stest2": "uint8", 
+        "dsp": "uint32", 
+        "dsa": "uint32", 
+        "ctest3": "uint8", 
+        "dmode": "uint8", 
+        "ccntl0": "uint8", 
+        "dsps": "uint32", 
+        "dcmd": "uint8", 
+        "pmjad1": "uint32", 
+        "stime0": "uint8", 
+        "ua": "uint32", 
+        "dcntl": "uint8", 
+        "dstat": "uint8", 
+        "sfs": "uint32", 
+        "dien": "uint8", 
+        "ssid": "uint8", 
+        "scid": "uint8", 
+        "dfifo": "uint8", 
+        "rbc": "uint32", 
+        "scntl2": "uint8", 
+        "msg_action": "int32", 
+        "sfbr": "uint8", 
+        "drs": "uint32", 
+        "dbc": "uint32", 
+        "istat0": "uint8", 
+        "sidl": "uint8", 
+        "mbox1": "uint8", 
+        "mbox0": "uint8", 
+        "stest3": "uint8", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "dbms": "uint32", 
+        "respid0": "uint8", 
+        "sien1": "uint8", 
+        "sien0": "uint8", 
+        "sist1": "uint8", 
+        "sist0": "uint8", 
+        "sstat0": "uint8", 
+        "scntl0": "uint8", 
+        "ctest4": "uint8", 
+        "sbr": "uint8", 
+        "sbc": "uint32", 
+        "socl": "uint8", 
+        "waiting": "int32", 
+        "ccntl1": "uint8", 
+        "pmjad2": "uint32", 
+        "dnad64": "uint32", 
+        "sbms": "uint32", 
+        "stest1": "uint8", 
+        "carry": "int32", 
+        "ctest2": "uint8", 
+        "ia": "uint32", 
+        "dnad": "uint32", 
+        "msg_len": "int32", 
+        "__version__": 0, 
+        "sense": "int32", 
+        "scntl3": "uint8"
+    }, 
+    "kvmclock": {
+        "clock": "uint64", 
+        "__version__": 1
+    }, 
+    "fw_cfg": {
+        "cur_entry": "uint16", 
+        "cur_offset-hack": "int32_as_uint16", 
+        "cur_offset": "uint32", 
+        "__version__": 2
+    }, 
+    "ac97": {
+        "mixer_data": "buffer", 
+        "glob_sta": "uint32", 
+        "unused1232": "unused_buffer", 
+        "glob_cnt": "uint32", 
+        "bm_regs": {
+            "lvi": "uint8", 
+            "civ": "uint8", 
+            "cr": "uint8", 
+            "bd.addr": "uint32", 
+            "bd_valid": "uint32", 
+            "sr": "uint16", 
+            "bdbar": "uint32", 
+            "bd.ctl_len": "uint32", 
+            "piv": "uint8", 
+            "__version__": 1, 
+            "picb": "uint16"
+        }, 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "cas": "uint32", 
+        "__version__": 3
+    }, 
+    "es1370": {
+        "status": "uint32", 
+        "codec": "uint32", 
+        "sctl": "uint32", 
+        "chan": {
+            "shift": "uint32", 
+            "scount": "uint32", 
+            "frame_cnt": "uint32", 
+            "frame_addr": "uint32", 
+            "leftover": "uint32", 
+            "__version__": 2
+        }, 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "mempage": "uint32", 
+        "ctl": "uint32", 
+        "__version__": 2
+    }, 
+    "usb-hub": {
+        "ports": {
+            "wPortStatus": "uint16", 
+            "wPortChange": "uint16", 
+            "__version__": 1
+        }, 
+        "dev": {
+            "state": "int32", 
+            "remote_wakeup": "int32", 
+            "addr": "uint8", 
+            "setup_len": "int32", 
+            "setup_state": "int32", 
+            "setup_buf": "uint8", 
+            "setup_index": "int32", 
+            "__version__": 1
+        }, 
+        "__version__": 1
+    }, 
+    "vga": {
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "vga": {
+            "ar_index": "uint8", 
+            "dac_cache": "buffer", 
+            "palette": "buffer", 
+            "dac_write_index": "uint8", 
+            "vbe_start_addr": "uint32", 
+            "vbe_line_offset": "uint32", 
+            "gr": "buffer", 
+            "msr": "uint8", 
+            "st01": "uint8", 
+            "st00": "uint8", 
+            "dac_state": "uint8", 
+            "vbe_bank_mask": "uint32", 
+            "dac_read_index": "uint8", 
+            "gr_index": "uint8", 
+            "vbe_index": "uint16", 
+            "ar_flip_flop": "int32", 
+            "cr": "buffer", 
+            "cr_index": "uint8", 
+            "vbe_regs": "uint16", 
+            "dac_sub_index": "uint8", 
+            "sr": "buffer", 
+            "is_vbe_vmstate": "uint8 equal", 
+            "bank_offset": "int32", 
+            "fcr": "uint8", 
+            "latch": "uint32", 
+            "sr_index": "uint8", 
+            "ar": "buffer", 
+            "__version__": 2
+        }, 
+        "__version__": 2
+    }, 
+    "sb16": {
+        "freq": "int32", 
+        "port": "uint32", 
+        "can_write": "int32", 
+        "dma": "uint32", 
+        "left_till_irq": "int32", 
+        "mixer_regs": "buffer", 
+        "time_const": "int32", 
+        "csp_regs": "buffer", 
+        "in2_data": "buffer", 
+        "fmt_bits": "int32", 
+        "nzero": "int32", 
+        "csp_mode": "uint8", 
+        "csp_reg83": "buffer", 
+        "out_data": "buffer", 
+        "highspeed": "int32", 
+        "block_size": "int32", 
+        "csp_reg83w": "int32", 
+        "csp_reg83r": "int32", 
+        "ver": "uint32", 
+        "v2x6": "int32", 
+        "fmt_stereo": "int32", 
+        "needed_bytes": "int32", 
+        "csp_value": "uint8", 
+        "last_read_byte": "uint8", 
+        "fmt": "uint32", 
+        "csp_param_dummy": "uint8", 
+        "out_data_len": "int32", 
+        "fmt_signed": "int32", 
+        "speaker": "int32", 
+        "irq": "uint32", 
+        "bytes_per_second": "int32", 
+        "mixer_nreg": "int32", 
+        "csp_param": "uint8", 
+        "use_hdma": "int32", 
+        "hdma": "uint32", 
+        "test_reg": "uint8", 
+        "fifo": "int32", 
+        "dma_auto": "int32", 
+        "__version__": 1, 
+        "in_index": "int32", 
+        "cmd": "int32", 
+        "csp_index": "uint8", 
+        "align": "int32", 
+        "dma_running": "int32"
+    }, 
+    "ps2kbd": {
+        "scancode_set": "int32", 
+        "common": {
+            "queue.count": "int32", 
+            "queue.data": "buffer", 
+            "queue.wptr": "int32", 
+            "write_cmd": "int32", 
+            "queue.rptr": "int32", 
+            "__version__": 3
+        }, 
+        "translate": "int32", 
+        "__version__": 3, 
+        "scan_enabled": "int32"
+    }, 
+    "mm-pckbd": {
+        "pending": "uint8", 
+        "status": "uint8", 
+        "mode": "uint8", 
+        "write_cmd": "uint8", 
+        "__version__": 3
+    }, 
+    "rtl8139": {
+        "conf.macaddr": "buffer", 
+        "TCTR": "uint32", 
+        "eeprom.eedi": "uint8", 
+        "eeprom.eedo": "uint8", 
+        "MultiIntr": "uint16", 
+        "RxBufAddr": "uint32", 
+        "TxThresh": "uint8", 
+        "TxStatus": "uint32", 
+        "Config3": "uint8", 
+        "RxBuf": "uint32", 
+        "eeprom.input": "uint16", 
+        "TimerInt": "uint32", 
+        "BasicModeStatus": "uint16", 
+        "rtl8139_mmio_io_addr_dummy": "int32", 
+        "IntrMask": "uint16", 
+        "TxAddr": "uint32", 
+        "RxBufPtr": "uint32", 
+        "eeprom.contents": "uint16", 
+        "RxMissed": "uint32", 
+        "phys": "buffer", 
+        "RxConfig": "uint32", 
+        "NWayExpansion": "uint16", 
+        "cplus_enabled": "uint32", 
+        "Config1": "uint8", 
+        "eeprom.eecs": "uint8", 
+        "CSCR": "uint16", 
+        "CpCmd": "uint16", 
+        "Config4": "uint8", 
+        "eeprom.address": "uint8", 
+        "bChipCmdState": "uint8", 
+        "currCPlusTxDesc": "uint32", 
+        "currCPlusRxDesc": "uint32", 
+        "IntrStatus": "uint16", 
+        "tally_counters": {
+            "RxOk": "uint64", 
+            "RxOkPhy": "uint64", 
+            "RxERR": "uint32", 
+            "MissPkt": "uint16", 
+            "RxOkBrd": "uint64", 
+            "TxOk": "uint64", 
+            "TxAbt": "uint16", 
+            "TxERR": "uint64", 
+            "TxUndrn": "uint16", 
+            "FAE": "uint16", 
+            "TxMCol": "uint32", 
+            "Tx1Col": "uint32", 
+            "__version__": 1
+        }, 
+        "clock_enabled": "uint8", 
+        "NWayLPAR": "uint16", 
+        "currTxDesc": "uint32", 
+        "mult": "buffer", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "eeprom.mode": "int32", 
+        "eeprom.eesk": "uint8", 
+        "eeprom.tick": "uint32", 
+        "TCTR_base": "int64", 
+        "Cfg9346": "uint8", 
+        "TxConfig": "uint32", 
+        "eeprom.output": "uint16", 
+        "BasicModeCtrl": "uint16", 
+        "RxRingAddrLO": "uint32", 
+        "unused3230": "unused_buffer", 
+        "Config5": "uint8", 
+        "RxBufferSize": "uint32", 
+        "__version__": 4, 
+        "RxRingAddrHI": "uint32", 
+        "Config0": "uint8", 
+        "NWayAdvert": "uint16"
+    }, 
+    "i8254": {
+        "channels": {
+            "write_latch": "uint8", 
+            "latched_count": "uint16", 
+            "status_latched": "uint8", 
+            "status": "uint8", 
+            "write_state": "uint8", 
+            "count": "int32", 
+            "mode": "uint8", 
+            "gate": "uint8", 
+            "read_state": "uint8", 
+            "next_transition_time": "int64", 
+            "count_load_time": "int64", 
+            "bcd": "uint8", 
+            "rw_mode": "uint8", 
+            "__version__": 2, 
+            "count_latched": "uint8"
+        }, 
+        "channels[0].irq_timer": "timer", 
+        "__version__": 2
+    }, 
+    "i8259": {
+        "init4": "uint8", 
+        "poll": "uint8", 
+        "imr": "uint8", 
+        "auto_eoi": "uint8", 
+        "isr": "uint8", 
+        "single_mode": "uint8", 
+        "special_fully_nested_mode": "uint8", 
+        "read_reg_select": "uint8", 
+        "special_mask": "uint8", 
+        "rotate_on_auto_eoi": "uint8", 
+        "last_irr": "uint8", 
+        "irr": "uint8", 
+        "irq_base": "uint8", 
+        "priority_add": "uint8", 
+        "elcr": "uint8", 
+        "__version__": 1, 
+        "init_state": "uint8"
+    }, 
+    "pckbd": {
+        "kbd": {
+            "pending": "uint8", 
+            "status": "uint8", 
+            "mode": "uint8", 
+            "write_cmd": "uint8", 
+            "__version__": 3
+        }, 
+        "__version__": 3
+    }, 
+    "pcnet": {
+        "state": {
+            "csr": "uint16", 
+            "unused1712": "unused_buffer", 
+            "buffer": "buffer", 
+            "xmit_pos": "int32", 
+            "prom": "buffer", 
+            "isr": "int32", 
+            "tdra": "uint32", 
+            "poll_timer": "timer", 
+            "lnkst": "int32", 
+            "tx_busy": "int32", 
+            "rap": "int32", 
+            "bcr": "uint16", 
+            "timer": "uint64", 
+            "__version__": 3, 
+            "rdra": "uint32"
+        }, 
+        "pci_dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "__version__": 3
+    }, 
+    "i2c_bus": {
+        "saved_address": "uint8", 
+        "__version__": 1
+    }, 
+    "i6300esb_wdt": {
+        "enabled": "int32", 
+        "clock_scale": "int32", 
+        "unlock_state": "int32", 
+        "timer1_preload": "uint32", 
+        "locked": "int32", 
+        "stage": "int32", 
+        "previous_reboot_flag": "int32", 
+        "reboot_enabled": "int32", 
+        "timer2_preload": "uint32", 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "int_type": "int32", 
+        "timer": "timer", 
+        "free_run": "int32", 
+        "__version__": 720
+    }, 
+    "piix4_pm": {
+        "pci0_status": {
+            "down": "uint32", 
+            "up": "uint32", 
+            "__version__": 1
+        }, 
+        "pmcntrl": "uint16", 
+        "tmr_overflow_time": "int64", 
+        "apm": {
+            "apms": "uint8", 
+            "apmc": "uint8", 
+            "__version__": 1
+        }, 
+        "dev": {
+            "version_id": "int32 equal", 
+            "config": "pci config", 
+            "__version__": 2, 
+            "irq_state": "pci irq state"
+        }, 
+        "tmr_timer": "timer", 
+        "pmen": "uint16", 
+        "pmsts": "uint16", 
+        "gpe": {
+            "sts": "uint16", 
+            "__version__": 1, 
+            "en": "uint16"
+        }, 
+        "__version__": 2
+    }, 
+    "sysbus-fdc": {
+        "state": {
+            "timer0": "uint8", 
+            "msr": "uint8", 
+            "status2": "uint8", 
+            "dor_vmstate": "uint8", 
+            "lock": "uint8", 
+            "dsr": "uint8", 
+            "data_len": "uint32", 
+            "tdr": "uint8", 
+            "data_dir": "uint8", 
+            "timer1": "uint8", 
+            "status0": "uint8", 
+            "config": "uint8", 
+            "pwrd": "uint8", 
+            "precomp_trk": "uint8", 
+            "data_pos": "uint32", 
+            "srb": "uint8", 
+            "sra": "uint8", 
+            "eot": "uint8", 
+            "status1": "uint8", 
+            "num_floppies": "uint8 equal", 
+            "drives": {
+                "track": "uint8", 
+                "head": "uint8", 
+                "sect": "uint8", 
+                "__version__": 1
+            }, 
+            "fifo": "uint8", 
+            "__version__": 2, 
+            "data_state": "uint8"
+        }, 
+        "__version__": 2
+    }
+}
-- 
1.7.0.4

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

* Re: [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique Anthony Liguori
@ 2011-03-23  2:29   ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  2:29 UTC (permalink / raw)
  Cc: Jan Kiszka, qemu-devel, Juan Quintela

On 03/22/2011 07:16 PM, Anthony Liguori wrote:
> For a schema to work, we need to make sure that each field name is unique.  We
> have a number of derivative types today that reuse the base name.  This patch
> fixes this.
>
> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
> ---
>   hw/hw.h |   16 +++++++++++++---
>   1 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/hw/hw.h b/hw/hw.h
> index 81bbd7a..9a9012f 100644
> --- a/hw/hw.h
> +++ b/hw/hw.h
> @@ -390,6 +390,16 @@ extern const VMStateInfo vmstate_info_unused_buffer;
>       .offset       = vmstate_offset_value(_state, _field, _type),     \
>   }
>
> +#define VMSTATE_SINGLE_TEST_HACK(_field, _state, _test, _version, _info, _type) { \
> +    .name         = (stringify(_field) "-hack"),                     \
> +    .version_id   = (_version),                                      \
> +    .field_exists = (_test),                                         \
> +    .size         = sizeof(_type),                                   \
> +    .info         =&(_info),                                        \
> +    .flags        = VMS_SINGLE,                                      \
> +    .offset       = vmstate_offset_value(_state, _field, _type),     \
> +}
> +
>   #define VMSTATE_POINTER(_field, _state, _version, _info, _type) {    \
>       .name       = (stringify(_field)),                               \
>       .version_id = (_version),                                        \
> @@ -419,7 +429,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
>   }
>
>   #define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
> -    .name         = (stringify(_field)),                              \
> +    .name         = (stringify(_field) "-" stringify(_test)),         \
>       .field_exists = (_test),                                          \
>       .num          = (_num),                                           \
>       .info         =&(_info),                                         \
> @@ -429,7 +439,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
>   }
>
>   #define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \
> -    .name       = (stringify(_field)),                               \
> +    .name       = (stringify(_field) "[" stringify(_start) "]"),      \
>       .version_id = (_version),                                        \
>       .num        = (_num),                                            \
>       .info       =&(_info),                                          \
> @@ -621,7 +631,7 @@ extern const VMStateInfo vmstate_info_unused_buffer;
>   }
>
>   #define VMSTATE_UNUSED_BUFFER(_test, _version, _size) {              \
> -    .name         = "unused",                                        \
> +    .name         = "unused" stringify(__LINE__),                    \

Why this does generate a unique name, it does not generate a stable 
name.  We need to add a name argument to this macro and all its 
derivatives.  I'll update tomorrow.

If the test suite fails saying you added a new field labelled 
"unusedXXXX", this is why.

Regards,

Anthony Liguori

>       .field_exists = (_test),                                         \
>       .version_id   = (_version),                                      \
>       .size         = (_size),                                         \

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

* Re: [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
@ 2011-03-23  2:31   ` Anthony Liguori
  2011-03-23  8:37   ` Stefan Hajnoczi
  2011-03-23 10:22   ` Peter Maydell
  2 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23  2:31 UTC (permalink / raw)
  Cc: Jan Kiszka, qemu-devel, Juan Quintela

On 03/22/2011 07:16 PM, Anthony Liguori wrote:
> We've had lots of issues surrounding live migration breaking.  This is because
> we haven't had a good way to validate that what we're migrating isn't changing
> underneath of us.
>
> This test works by first converting the in-tree schema to C source as a string.
> This is built into the test case.  The test case will then query QEMU for the
> current schema.
>
> It converts both strings to QObjects via the JSON parser and then does a
> recursive diff.  Unlike a simple diff command, this lets us say exactly what you
> did to break migration.  For instance, you get error messages like:
>
>    You broke migration by changing the type of field 'par' in device 'cpu',
>    version 1 from 'uint32' to 'uint64'.
>
> It only covers devices that support VMState and it currently doesn't look at
> subsections yet.
>
> The in-tree schema needs to be updated whenever migration changes but this ends
> up being a very nice way to ensure that we're reviewing migration protocol
> changes.
>
> The test case is built in the default build, and can be run by `make check'.

This test takes a disturbingly long time to run considering what it's 
doing (~3 seconds).  Turns out, the JSON parser is horribly slow because 
it allocates and frees memory faster than a hummingbird on steroids.

I have a local patch that removes this and afterwards the test runs in 
just 70ms.  I'll send that fix out tomorrow.

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
@ 2011-03-23  8:13   ` Stefan Hajnoczi
  2011-03-23  8:19     ` Roy Tam
  0 siblings, 1 reply; 49+ messages in thread
From: Stefan Hajnoczi @ 2011-03-23  8:13 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On Wed, Mar 23, 2011 at 12:16 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
> GLib is an extremely common library that has a portable thread implementation
> along with tons of other goodies.
>
> GLib and GObject have a fantastic amount of infrastructure we can leverage in
> QEMU including an object oriented programming infrastructure.
>
> Short term, it has a very nice thread pool implementation that we could leverage
> in something like virtio-9p.  It also has a test harness implementation that
> this series will use.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  Makefile        |    2 ++
>  Makefile.objs   |    2 ++
>  Makefile.target |    1 +
>  configure       |   13 +++++++++++++
>  4 files changed, 18 insertions(+), 0 deletions(-)

Yes, please.  I'd like to use glib to make simpletrace portable.

To paraphrase the saying about non-trivial C programs and LISP interpreters:

"In every cross-platform C program there is a glib."

Stefan

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

* Re: [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  8:13   ` Stefan Hajnoczi
@ 2011-03-23  8:19     ` Roy Tam
  2011-03-23  8:41       ` Stefan Hajnoczi
  0 siblings, 1 reply; 49+ messages in thread
From: Roy Tam @ 2011-03-23  8:19 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel, Juan Quintela

2011/3/23 Stefan Hajnoczi <stefanha@gmail.com>:
> On Wed, Mar 23, 2011 at 12:16 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
>> GLib is an extremely common library that has a portable thread implementation
>> along with tons of other goodies.
>>
>> GLib and GObject have a fantastic amount of infrastructure we can leverage in
>> QEMU including an object oriented programming infrastructure.
>>
>> Short term, it has a very nice thread pool implementation that we could leverage
>> in something like virtio-9p.  It also has a test harness implementation that
>> this series will use.
>>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
>>  Makefile        |    2 ++
>>  Makefile.objs   |    2 ++
>>  Makefile.target |    1 +
>>  configure       |   13 +++++++++++++
>>  4 files changed, 18 insertions(+), 0 deletions(-)
>
> Yes, please.  I'd like to use glib to make simpletrace portable.
>
> To paraphrase the saying about non-trivial C programs and LISP interpreters:
>
> "In every cross-platform C program there is a glib."
>
> Stefan
>
>

So, breaking win32 support again?

Roy

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

* Re: [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
  2011-03-23  2:31   ` Anthony Liguori
@ 2011-03-23  8:37   ` Stefan Hajnoczi
  2011-03-23 10:22   ` Peter Maydell
  2 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2011-03-23  8:37 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On Wed, Mar 23, 2011 at 12:16 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
> +static QObject *read_current_schema(void)
> +{
> +    char buffer[65536];
> +    int fd;
> +    int ret;
> +    size_t offset = 0;
> +    ssize_t len;
> +
> +    ret = system("i386-softmmu/qemu -vmstate-dump > /tmp/schema.json");

Please don't hardcode i386-softmmu, there should at least be a way to
override it.  For example, I tend to build x86_64-softmmu only.

Using a temporary file is not ideal because as soon as this program
runs as part of an automated build system we could be clobbering the
file if multiple runs are going in parallel.  How about popen(3)?

> diff --git a/vmstate/schema.json b/vmstate/schema.json
> new file mode 100644
> index 0000000..23483ab
> --- /dev/null
> +++ b/vmstate/schema.json
> @@ -0,0 +1,1176 @@
> +{
> +    "cpu": {
> +        "mcg_cap": "uint64",
> +        "a20_mask": "int32",
> +        "tsc_offset": "uint64",
> +        "idt": {
> +            "flags": "uint32",
> +            "limit": "uint32",
> +            "selector": "uint32",
> +            "base": "uint32",
> +            "__version__": 1
> +        },

Is field ordering important and did we lose that information as soon
as we started using dicts to represent vmstate dumps?

Stefan

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

* Re: [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  8:19     ` Roy Tam
@ 2011-03-23  8:41       ` Stefan Hajnoczi
  2011-03-23  8:58         ` Roy Tam
  0 siblings, 1 reply; 49+ messages in thread
From: Stefan Hajnoczi @ 2011-03-23  8:41 UTC (permalink / raw)
  To: Roy Tam; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel, Juan Quintela

On Wed, Mar 23, 2011 at 8:19 AM, Roy Tam <roytam@gmail.com> wrote:
> 2011/3/23 Stefan Hajnoczi <stefanha@gmail.com>:
>> On Wed, Mar 23, 2011 at 12:16 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
>>> GLib is an extremely common library that has a portable thread implementation
>>> along with tons of other goodies.
>>>
>>> GLib and GObject have a fantastic amount of infrastructure we can leverage in
>>> QEMU including an object oriented programming infrastructure.
>>>
>>> Short term, it has a very nice thread pool implementation that we could leverage
>>> in something like virtio-9p.  It also has a test harness implementation that
>>> this series will use.
>>>
>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>> ---
>>>  Makefile        |    2 ++
>>>  Makefile.objs   |    2 ++
>>>  Makefile.target |    1 +
>>>  configure       |   13 +++++++++++++
>>>  4 files changed, 18 insertions(+), 0 deletions(-)
>>
>> Yes, please.  I'd like to use glib to make simpletrace portable.
>>
>> To paraphrase the saying about non-trivial C programs and LISP interpreters:
>>
>> "In every cross-platform C program there is a glib."
>>
>> Stefan
>>
>>
>
> So, breaking win32 support again?

Can you please explain the win32 issue with glib?

Stefan

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

* Re: [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  8:41       ` Stefan Hajnoczi
@ 2011-03-23  8:58         ` Roy Tam
  2011-03-23  9:19           ` [Qemu-devel] " Paolo Bonzini
  2011-03-23  9:22           ` [Qemu-devel] " Stefan Hajnoczi
  0 siblings, 2 replies; 49+ messages in thread
From: Roy Tam @ 2011-03-23  8:58 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel, Juan Quintela

2011/3/23 Stefan Hajnoczi <stefanha@gmail.com>:
> On Wed, Mar 23, 2011 at 8:19 AM, Roy Tam <roytam@gmail.com> wrote:
>> 2011/3/23 Stefan Hajnoczi <stefanha@gmail.com>:
>>> On Wed, Mar 23, 2011 at 12:16 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
>>>> GLib is an extremely common library that has a portable thread implementation
>>>> along with tons of other goodies.
>>>>
>>>> GLib and GObject have a fantastic amount of infrastructure we can leverage in
>>>> QEMU including an object oriented programming infrastructure.
>>>>
>>>> Short term, it has a very nice thread pool implementation that we could leverage
>>>> in something like virtio-9p.  It also has a test harness implementation that
>>>> this series will use.
>>>>
>>>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>>>> ---
>>>>  Makefile        |    2 ++
>>>>  Makefile.objs   |    2 ++
>>>>  Makefile.target |    1 +
>>>>  configure       |   13 +++++++++++++
>>>>  4 files changed, 18 insertions(+), 0 deletions(-)
>>>
>>> Yes, please.  I'd like to use glib to make simpletrace portable.
>>>
>>> To paraphrase the saying about non-trivial C programs and LISP interpreters:
>>>
>>> "In every cross-platform C program there is a glib."
>>>
>>> Stefan
>>>
>>>
>>
>> So, breaking win32 support again?
>
> Can you please explain the win32 issue with glib?
>
> Stefan
>

I think I have to change my words. Glib works in win32, but adding
Glib to QEMU will bloat the binary size. It adds more dependency on
building and the result binary. I wonder if it is a must to add it.

Roy

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

* Re: [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions Anthony Liguori
@ 2011-03-23  9:00   ` Alon Levy
  2011-03-23 12:30   ` Peter Maydell
  1 sibling, 0 replies; 49+ messages in thread
From: Alon Levy @ 2011-03-23  9:00 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On Tue, Mar 22, 2011 at 07:16:07PM -0500, Anthony Liguori wrote:
> This is a purely mechanical change.  It was generated with a simple python
> script and a little bit of hand tuning.  Without this, we can only see
> VMStateDescriptions that are part of an active device which means that we have
> to test migration with a VM configured with every possible device.
> 

Is it possible to make the names meaningful instead of numeric?
you get a simpler script if you do that because you don't have to
track the number, and it's guranteed unique because you start from unique
function names. i.e. instead of

 +static void init_vmstate_description_0(void)
 +{
 +    register_vmstate_description(&vmstate_ac97);
 +}
 +
 +vmstate_init(init_vmstate_description_0);
 +


Have

 +static void init_vmstate_description_ac97(void)
 +{
 +    register_vmstate_description(&vmstate_ac97);
 +}
 +
 +vmstate_init(init_vmstate_description_ac97);
 +

Alon

> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/ac97.c                  |    8 ++++++
>  hw/acpi_piix4.c            |    8 ++++++
>  hw/apb_pci.c               |    8 ++++++
>  hw/apic.c                  |    8 ++++++
>  hw/arm_sysctl.c            |    8 ++++++
>  hw/bonito.c                |    8 ++++++
>  hw/cirrus_vga.c            |    8 ++++++
>  hw/cs4231.c                |    8 ++++++
>  hw/cs4231a.c               |    8 ++++++
>  hw/dec_pci.c               |    8 ++++++
>  hw/e1000.c                 |    8 ++++++
>  hw/eccmemctl.c             |    8 ++++++
>  hw/eeprom93xx.c            |    8 ++++++
>  hw/es1370.c                |    8 ++++++
>  hw/escc.c                  |    8 ++++++
>  hw/esp.c                   |    8 ++++++
>  hw/fdc.c                   |   16 ++++++++++++
>  hw/fw_cfg.c                |    8 ++++++
>  hw/gus.c                   |    8 ++++++
>  hw/hda-audio.c             |    8 ++++++
>  hw/hpet.c                  |    8 ++++++
>  hw/hw.h                    |    3 ++
>  hw/i2c.c                   |    8 ++++++
>  hw/i8254.c                 |    8 ++++++
>  hw/i8259.c                 |    8 ++++++
>  hw/intel-hda.c             |    8 ++++++
>  hw/ioapic.c                |    8 ++++++
>  hw/ioh3420.c               |    8 ++++++
>  hw/kvmclock.c              |    8 ++++++
>  hw/lance.c                 |    8 ++++++
>  hw/lm32_juart.c            |    8 ++++++
>  hw/lm32_pic.c              |    8 ++++++
>  hw/lm32_sys.c              |    8 ++++++
>  hw/lm32_timer.c            |    8 ++++++
>  hw/lm32_uart.c             |    8 ++++++
>  hw/lm832x.c                |    8 ++++++
>  hw/lsi53c895a.c            |    8 ++++++
>  hw/marvell_88w8618_audio.c |    8 ++++++
>  hw/max7310.c               |    8 ++++++
>  hw/mc146818rtc.c           |    8 ++++++
>  hw/mst_fpga.c              |    8 ++++++
>  hw/musicpal.c              |   56 ++++++++++++++++++++++++++++++++++++++++++++
>  hw/ne2000.c                |    8 ++++++
>  hw/pc.c                    |    8 ++++++
>  hw/pci.c                   |    8 ++++++
>  hw/pckbd.c                 |   16 ++++++++++++
>  hw/pcnet-pci.c             |    8 ++++++
>  hw/piix_pci.c              |    8 ++++++
>  hw/pl031.c                 |    8 ++++++
>  hw/pl050.c                 |   16 ++++++++++++
>  hw/pl080.c                 |   16 ++++++++++++
>  hw/pl110.c                 |   16 ++++++++++++
>  hw/pl190.c                 |    8 ++++++
>  hw/ps2.c                   |   16 ++++++++++++
>  hw/pxa2xx.c                |   16 ++++++++++++
>  hw/pxa2xx_dma.c            |    8 ++++++
>  hw/pxa2xx_pic.c            |    8 ++++++
>  hw/pxa2xx_timer.c          |   16 ++++++++++++
>  hw/qxl.c                   |   16 ++++++++++++
>  hw/rtl8139.c               |   16 ++++++++++++
>  hw/sb16.c                  |    8 ++++++
>  hw/sbi.c                   |    8 ++++++
>  hw/serial.c                |   10 ++++++-
>  hw/slavio_intctl.c         |    8 ++++++
>  hw/slavio_misc.c           |    8 ++++++
>  hw/slavio_timer.c          |    8 ++++++
>  hw/smc91c111.c             |    8 ++++++
>  hw/sparc32_dma.c           |    8 ++++++
>  hw/spitz.c                 |   32 +++++++++++++++++++++++++
>  hw/ssd0303.c               |    8 ++++++
>  hw/sun4c_intctl.c          |    8 ++++++
>  hw/sun4m_iommu.c           |    8 ++++++
>  hw/tcx.c                   |    8 ++++++
>  hw/tmp105.c                |    8 ++++++
>  hw/twl92230.c              |    8 ++++++
>  hw/usb-hid.c               |    8 ++++++
>  hw/usb-hub.c               |    8 ++++++
>  hw/usb-uhci.c              |    8 ++++++
>  hw/versatilepb.c           |    8 ++++++
>  hw/vga-isa.c               |    8 ++++++
>  hw/vga-pci.c               |    8 ++++++
>  hw/vmmouse.c               |    8 ++++++
>  hw/vmware_vga.c            |    8 ++++++
>  hw/vt82c686.c              |   16 ++++++++++++
>  hw/wdt_i6300esb.c          |    8 ++++++
>  hw/wdt_ib700.c             |    8 ++++++
>  hw/wm8750.c                |    8 ++++++
>  hw/xio3130_downstream.c    |    8 ++++++
>  hw/xio3130_upstream.c      |    8 ++++++
>  hw/zaurus.c                |    8 ++++++
>  module.h                   |    2 +
>  savevm.c                   |    4 +++
>  target-i386/machine.c      |    8 ++++++
>  93 files changed, 889 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ac97.c b/hw/ac97.c
> index d71072d..bf818b8 100644
> --- a/hw/ac97.c
> +++ b/hw/ac97.c
> @@ -1343,6 +1343,14 @@ static PCIDeviceInfo ac97_info = {
>      .init         = ac97_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ac97);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void ac97_register (void)
>  {
>      pci_qdev_register (&ac97_info);
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 0b2bc97..aaa009b 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -460,6 +460,14 @@ static PCIDeviceInfo piix4_pm_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_acpi);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void piix4_pm_register(void)
>  {
>      pci_qdev_register(&piix4_pm_info);
> diff --git a/hw/apb_pci.c b/hw/apb_pci.c
> index 84e9af7..e5d7954 100644
> --- a/hw/apb_pci.c
> +++ b/hw/apb_pci.c
> @@ -472,6 +472,14 @@ static PCIDeviceInfo pbm_pci_bridge_info = {
>      .is_bridge = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pci_device);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pbm_register_devices(void)
>  {
>      sysbus_register_withprop(&pbm_host_info);
> diff --git a/hw/apic.c b/hw/apic.c
> index 9febf40..cdf64dc 100644
> --- a/hw/apic.c
> +++ b/hw/apic.c
> @@ -1025,6 +1025,14 @@ static SysBusDeviceInfo apic_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_apic);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void apic_register_devices(void)
>  {
>      sysbus_register_withprop(&apic_info);
> diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
> index 9225b58..e11b1ee 100644
> --- a/hw/arm_sysctl.c
> +++ b/hw/arm_sysctl.c
> @@ -363,6 +363,14 @@ static SysBusDeviceInfo arm_sysctl_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_arm_sysctl);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void arm_sysctl_register_devices(void)
>  {
>      sysbus_register_withprop(&arm_sysctl_info);
> diff --git a/hw/bonito.c b/hw/bonito.c
> index 65a4a63..6ec0777 100644
> --- a/hw/bonito.c
> +++ b/hw/bonito.c
> @@ -798,6 +798,14 @@ static PCIDeviceInfo bonito_info = {
>      .init         = bonito_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_bonito);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo bonito_pcihost_info = {
>      .init         = bonito_pcihost_initfn,
>      .qdev.name    = "Bonito-pcihost",
> diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
> index 2724f7b..97a1c4c 100644
> --- a/hw/cirrus_vga.c
> +++ b/hw/cirrus_vga.c
> @@ -3145,6 +3145,14 @@ static PCIDeviceInfo cirrus_vga_info = {
>      .config_write = pci_cirrus_write_config,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pci_cirrus_vga);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void cirrus_vga_register(void)
>  {
>      pci_qdev_register(&cirrus_vga_info);
> diff --git a/hw/cs4231.c b/hw/cs4231.c
> index a65b697..d9601d0 100644
> --- a/hw/cs4231.c
> +++ b/hw/cs4231.c
> @@ -167,6 +167,14 @@ static SysBusDeviceInfo cs4231_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_cs4231);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void cs4231_register_devices(void)
>  {
>      sysbus_register_withprop(&cs4231_info);
> diff --git a/hw/cs4231a.c b/hw/cs4231a.c
> index 598f032..e036faf 100644
> --- a/hw/cs4231a.c
> +++ b/hw/cs4231a.c
> @@ -679,6 +679,14 @@ static ISADeviceInfo cs4231a_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_cs4231a);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void cs4231a_register (void)
>  {
>      isa_qdev_register (&cs4231a_info);
> diff --git a/hw/dec_pci.c b/hw/dec_pci.c
> index bf88f2a..4924a43 100644
> --- a/hw/dec_pci.c
> +++ b/hw/dec_pci.c
> @@ -76,6 +76,14 @@ static PCIDeviceInfo dec_21154_pci_bridge_info = {
>      .is_bridge = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pci_device);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
>  {
>      PCIDevice *dev;
> diff --git a/hw/e1000.c b/hw/e1000.c
> index 2a4d5c7..e906c65 100644
> --- a/hw/e1000.c
> +++ b/hw/e1000.c
> @@ -1212,6 +1212,14 @@ static PCIDeviceInfo e1000_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_e1000);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void e1000_register_devices(void)
>  {
>      pci_qdev_register(&e1000_info);
> diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
> index 2bda87b..770b6aa 100644
> --- a/hw/eccmemctl.c
> +++ b/hw/eccmemctl.c
> @@ -323,6 +323,14 @@ static SysBusDeviceInfo ecc_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ecc);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  
>  static void ecc_register_devices(void)
>  {
> diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
> index 660b28f..cfa695d 100644
> --- a/hw/eeprom93xx.c
> +++ b/hw/eeprom93xx.c
> @@ -320,6 +320,14 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords)
>      return eeprom;
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_eeprom);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  void eeprom93xx_free(DeviceState *dev, eeprom_t *eeprom)
>  {
>      /* Destroy EEPROM. */
> diff --git a/hw/es1370.c b/hw/es1370.c
> index 40cb48c..d2f3671 100644
> --- a/hw/es1370.c
> +++ b/hw/es1370.c
> @@ -1045,6 +1045,14 @@ static PCIDeviceInfo es1370_info = {
>      .init         = es1370_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_es1370);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void es1370_register (void)
>  {
>      pci_qdev_register (&es1370_info);
> diff --git a/hw/escc.c b/hw/escc.c
> index f6fd919..08062e7 100644
> --- a/hw/escc.c
> +++ b/hw/escc.c
> @@ -953,6 +953,14 @@ static SysBusDeviceInfo escc_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_escc);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void escc_register_devices(void)
>  {
>      sysbus_register_withprop(&escc_info);
> diff --git a/hw/esp.c b/hw/esp.c
> index fa9d2a2..977890e 100644
> --- a/hw/esp.c
> +++ b/hw/esp.c
> @@ -743,6 +743,14 @@ static SysBusDeviceInfo esp_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_esp);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void esp_register_devices(void)
>  {
>      sysbus_register_withprop(&esp_info);
> diff --git a/hw/fdc.c b/hw/fdc.c
> index 9fdbc75..4b02dce 100644
> --- a/hw/fdc.c
> +++ b/hw/fdc.c
> @@ -1938,6 +1938,14 @@ static ISADeviceInfo isa_fdc_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_isa_fdc);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static const VMStateDescription vmstate_sysbus_fdc ={
>      .name = "fdc",
>      .version_id = 2,
> @@ -1961,6 +1969,14 @@ static SysBusDeviceInfo sysbus_fdc_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_sysbus_fdc);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static SysBusDeviceInfo sun4m_fdc_info = {
>      .init = sun4m_fdc_init1,
>      .qdev.name  = "SUNW,fdtwo",
> diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
> index 85c8c3c..67603a9 100644
> --- a/hw/fw_cfg.c
> +++ b/hw/fw_cfg.c
> @@ -399,6 +399,14 @@ static SysBusDeviceInfo fw_cfg_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_fw_cfg);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void fw_cfg_register_devices(void)
>  {
>      sysbus_register_withprop(&fw_cfg_info);
> diff --git a/hw/gus.c b/hw/gus.c
> index ff9e7c7..8e35ffb 100644
> --- a/hw/gus.c
> +++ b/hw/gus.c
> @@ -315,6 +315,14 @@ static ISADeviceInfo gus_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_gus);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void gus_register (void)
>  {
>      isa_qdev_register (&gus_info);
> diff --git a/hw/hda-audio.c b/hw/hda-audio.c
> index c699d6f..f384de6 100644
> --- a/hw/hda-audio.c
> +++ b/hw/hda-audio.c
> @@ -906,6 +906,14 @@ static HDACodecDeviceInfo hda_audio_info_output = {
>      .stream       = hda_audio_stream,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_hda_audio);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static HDACodecDeviceInfo hda_audio_info_duplex = {
>      .qdev.name    = "hda-duplex",
>      .qdev.desc    = "HDA Audio Codec, duplex",
> diff --git a/hw/hpet.c b/hw/hpet.c
> index ef9a2a0..9010f45 100644
> --- a/hw/hpet.c
> +++ b/hw/hpet.c
> @@ -737,6 +737,14 @@ static SysBusDeviceInfo hpet_device_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_hpet);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void hpet_register_device(void)
>  {
>      sysbus_register_withprop(&hpet_device_info);
> diff --git a/hw/hw.h b/hw/hw.h
> index 1b09039..81bbd7a 100644
> --- a/hw/hw.h
> +++ b/hw/hw.h
> @@ -914,4 +914,7 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
>                                     int required_for_version);
>  void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
>                          void *opaque);
> +
> +void register_vmstate_description(const VMStateDescription *desc);
> +
>  #endif
> diff --git a/hw/i2c.c b/hw/i2c.c
> index f80d12d..85ae1f9 100644
> --- a/hw/i2c.c
> +++ b/hw/i2c.c
> @@ -66,6 +66,14 @@ i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
>      return bus;
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_i2c_bus);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  void i2c_set_slave_address(i2c_slave *dev, uint8_t address)
>  {
>      dev->address = address;
> diff --git a/hw/i8254.c b/hw/i8254.c
> index a9ca9f6..261f860 100644
> --- a/hw/i8254.c
> +++ b/hw/i8254.c
> @@ -539,6 +539,14 @@ static ISADeviceInfo pit_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pit);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pit_register(void)
>  {
>      isa_qdev_register(&pit_info);
> diff --git a/hw/i8259.c b/hw/i8259.c
> index 84d330d..388e145 100644
> --- a/hw/i8259.c
> +++ b/hw/i8259.c
> @@ -487,6 +487,14 @@ static void pic_init1(int io_addr, int elcr_addr, PicState *s)
>      qemu_register_reset(pic_reset, s);
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_pic);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  void pic_info(Monitor *mon)
>  {
>      int i;
> diff --git a/hw/intel-hda.c b/hw/intel-hda.c
> index b0b1d12..a32d28d 100644
> --- a/hw/intel-hda.c
> +++ b/hw/intel-hda.c
> @@ -1283,6 +1283,14 @@ static PCIDeviceInfo intel_hda_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_intel_hda);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void intel_hda_register(void)
>  {
>      pci_qdev_register(&intel_hda_info);
> diff --git a/hw/ioapic.c b/hw/ioapic.c
> index 569327d..8ac6d34 100644
> --- a/hw/ioapic.c
> +++ b/hw/ioapic.c
> @@ -350,6 +350,14 @@ static SysBusDeviceInfo ioapic_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ioapic);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void ioapic_register_devices(void)
>  {
>      sysbus_register_withprop(&ioapic_info);
> diff --git a/hw/ioh3420.c b/hw/ioh3420.c
> index 95adf09..7b0b801 100644
> --- a/hw/ioh3420.c
> +++ b/hw/ioh3420.c
> @@ -229,6 +229,14 @@ static PCIDeviceInfo ioh3420_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ioh3420);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void ioh3420_register(void)
>  {
>      pci_qdev_register(&ioh3420_info);
> diff --git a/hw/kvmclock.c b/hw/kvmclock.c
> index b6ceddf..f9c05cd 100644
> --- a/hw/kvmclock.c
> +++ b/hw/kvmclock.c
> @@ -99,6 +99,14 @@ static SysBusDeviceInfo kvmclock_info = {
>      .init = kvmclock_init,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&kvmclock_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  /* Note: Must be called after VCPU initialization. */
>  void kvmclock_create(void)
>  {
> diff --git a/hw/lance.c b/hw/lance.c
> index ddb1cbb..32d81ca 100644
> --- a/hw/lance.c
> +++ b/hw/lance.c
> @@ -153,6 +153,14 @@ static SysBusDeviceInfo lance_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lance);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lance_register_devices(void)
>  {
>      sysbus_register_withprop(&lance_info);
> diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
> index fddcf7e..a49308c 100644
> --- a/hw/lm32_juart.c
> +++ b/hw/lm32_juart.c
> @@ -142,6 +142,14 @@ static SysBusDeviceInfo lm32_juart_info = {
>      .qdev.reset = juart_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm32_juart);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm32_juart_register(void)
>  {
>      sysbus_register_withprop(&lm32_juart_info);
> diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
> index 02941a7..de4f310 100644
> --- a/hw/lm32_pic.c
> +++ b/hw/lm32_pic.c
> @@ -182,6 +182,14 @@ static SysBusDeviceInfo lm32_pic_info = {
>      .qdev.reset = pic_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm32_pic);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm32_pic_register(void)
>  {
>      sysbus_register_withprop(&lm32_pic_info);
> diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
> index 427b05f..4c718b7 100644
> --- a/hw/lm32_sys.c
> +++ b/hw/lm32_sys.c
> @@ -153,6 +153,14 @@ static SysBusDeviceInfo lm32_sys_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm32_sys);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm32_sys_register(void)
>  {
>      sysbus_register_withprop(&lm32_sys_info);
> diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
> index ed28984..445cfde 100644
> --- a/hw/lm32_timer.c
> +++ b/hw/lm32_timer.c
> @@ -214,6 +214,14 @@ static SysBusDeviceInfo lm32_timer_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm32_timer);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm32_timer_register(void)
>  {
>      sysbus_register_withprop(&lm32_timer_info);
> diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
> index e225087..32c6ffd 100644
> --- a/hw/lm32_uart.c
> +++ b/hw/lm32_uart.c
> @@ -280,6 +280,14 @@ static SysBusDeviceInfo lm32_uart_info = {
>      .qdev.reset = uart_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm32_uart);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm32_uart_register(void)
>  {
>      sysbus_register_withprop(&lm32_uart_info);
> diff --git a/hw/lm832x.c b/hw/lm832x.c
> index 590a4cc..ac097bd 100644
> --- a/hw/lm832x.c
> +++ b/hw/lm832x.c
> @@ -504,6 +504,14 @@ static I2CSlaveInfo lm8323_info = {
>      .send = lm_i2c_tx
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lm_kbd);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lm832x_register_devices(void)
>  {
>      i2c_register_slave(&lm8323_info);
> diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
> index 84a4992..699261b 100644
> --- a/hw/lsi53c895a.c
> +++ b/hw/lsi53c895a.c
> @@ -2211,6 +2211,14 @@ static PCIDeviceInfo lsi_info = {
>      .exit       = lsi_scsi_uninit,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_lsi_scsi);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void lsi53c895a_register_devices(void)
>  {
>      pci_qdev_register(&lsi_info);
> diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
> index 3eff925..25437ea 100644
> --- a/hw/marvell_88w8618_audio.c
> +++ b/hw/marvell_88w8618_audio.c
> @@ -291,6 +291,14 @@ static SysBusDeviceInfo mv88w8618_audio_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&mv88w8618_audio_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void mv88w8618_register_devices(void)
>  {
>      sysbus_register_withprop(&mv88w8618_audio_info);
> diff --git a/hw/max7310.c b/hw/max7310.c
> index c1bdb2e..12b8769 100644
> --- a/hw/max7310.c
> +++ b/hw/max7310.c
> @@ -196,6 +196,14 @@ static I2CSlaveInfo max7310_info = {
>      .send = max7310_tx
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_max7310);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void max7310_register_devices(void)
>  {
>      i2c_register_slave(&max7310_info);
> diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
> index 1c9a706..7b80c18 100644
> --- a/hw/mc146818rtc.c
> +++ b/hw/mc146818rtc.c
> @@ -650,6 +650,14 @@ static ISADeviceInfo mc146818rtc_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_rtc);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void mc146818rtc_register(void)
>  {
>      isa_qdev_register(&mc146818rtc_info);
> diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
> index a04355c..c5111b9 100644
> --- a/hw/mst_fpga.c
> +++ b/hw/mst_fpga.c
> @@ -248,6 +248,14 @@ static SysBusDeviceInfo mst_fpga_info = {
>  	.qdev.vmsd = &vmstate_mst_fpga_regs,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_mst_fpga_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void mst_fpga_register(void)
>  {
>  	sysbus_register_withprop(&mst_fpga_info);
> diff --git a/hw/musicpal.c b/hw/musicpal.c
> index d98aa8d..773b93c 100644
> --- a/hw/musicpal.c
> +++ b/hw/musicpal.c
> @@ -423,6 +423,14 @@ static SysBusDeviceInfo mv88w8618_eth_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&mv88w8618_eth_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  /* LCD register offsets */
>  #define MP_LCD_IRQCTRL          0x180
>  #define MP_LCD_IRQSTAT          0x184
> @@ -637,6 +645,14 @@ static SysBusDeviceInfo musicpal_lcd_info = {
>      .qdev.vmsd = &musicpal_lcd_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&musicpal_lcd_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  /* PIC register offsets */
>  #define MP_PIC_STATUS           0x00
>  #define MP_PIC_ENABLE_SET       0x08
> @@ -753,6 +769,14 @@ static SysBusDeviceInfo mv88w8618_pic_info = {
>      .qdev.vmsd = &mv88w8618_pic_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_2(void)
> +{
> +    register_vmstate_description(&mv88w8618_pic_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_2);
> +
>  /* PIT register offsets */
>  #define MP_PIT_TIMER1_LENGTH    0x00
>  /* ... */
> @@ -927,6 +951,14 @@ static SysBusDeviceInfo mv88w8618_pit_info = {
>      .qdev.vmsd  = &mv88w8618_pit_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_3(void)
> +{
> +    register_vmstate_description(&mv88w8618_pit_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_3);
> +
>  /* Flash config register offsets */
>  #define MP_FLASHCFG_CFGR0    0x04
>  
> @@ -1004,6 +1036,14 @@ static SysBusDeviceInfo mv88w8618_flashcfg_info = {
>      .qdev.vmsd  = &mv88w8618_flashcfg_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_4(void)
> +{
> +    register_vmstate_description(&mv88w8618_flashcfg_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_4);
> +
>  /* Misc register offsets */
>  #define MP_MISC_BOARD_REVISION  0x18
>  
> @@ -1335,6 +1375,14 @@ static SysBusDeviceInfo musicpal_gpio_info = {
>      .qdev.vmsd  = &musicpal_gpio_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_5(void)
> +{
> +    register_vmstate_description(&musicpal_gpio_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_5);
> +
>  /* Keyboard codes & masks */
>  #define KEY_RELEASED            0x80
>  #define KEY_CODE                0x7f
> @@ -1478,6 +1526,14 @@ static SysBusDeviceInfo musicpal_key_info = {
>      .qdev.vmsd  = &musicpal_key_vmsd,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_6(void)
> +{
> +    register_vmstate_description(&musicpal_key_vmsd);
> +}
> +
> +vmstate_init(init_vmstate_description_6);
> +
>  static struct arm_boot_info musicpal_binfo = {
>      .loader_start = 0x0,
>      .board_id = 0x20e,
> diff --git a/hw/ne2000.c b/hw/ne2000.c
> index 5966359..270578b 100644
> --- a/hw/ne2000.c
> +++ b/hw/ne2000.c
> @@ -773,6 +773,14 @@ static PCIDeviceInfo ne2000_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pci_ne2000);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void ne2000_register_devices(void)
>  {
>      pci_qdev_register(&ne2000_info);
> diff --git a/hw/pc.c b/hw/pc.c
> index 6939c04..5211b29 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -497,6 +497,14 @@ static ISADeviceInfo port92_info = {
>      .init          = port92_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_port92_isa);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void port92_register(void)
>  {
>      isa_qdev_register(&port92_info);
> diff --git a/hw/pci.c b/hw/pci.c
> index 8b76cea..50b9a14 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -269,6 +269,14 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
>      vmstate_register(NULL, -1, &vmstate_pcibus, bus);
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_pcibus);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
>  {
>      PCIBus *bus;
> diff --git a/hw/pckbd.c b/hw/pckbd.c
> index ae65c04..027f69e 100644
> --- a/hw/pckbd.c
> +++ b/hw/pckbd.c
> @@ -433,6 +433,14 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
>      qemu_register_reset(kbd_reset, s);
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_kbd);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  typedef struct ISAKBDState {
>      ISADevice dev;
>      KBDState  kbd;
> @@ -492,6 +500,14 @@ static ISADeviceInfo i8042_info = {
>      .init          = i8042_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_kbd_isa);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void i8042_register(void)
>  {
>      isa_qdev_register(&i8042_info);
> diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
> index 339a401..d3c2738 100644
> --- a/hw/pcnet-pci.c
> +++ b/hw/pcnet-pci.c
> @@ -338,6 +338,14 @@ static PCIDeviceInfo pcnet_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pci_pcnet);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pci_pcnet_register_devices(void)
>  {
>      pci_qdev_register(&pcnet_info);
> diff --git a/hw/piix_pci.c b/hw/piix_pci.c
> index 358da58..1e5f379 100644
> --- a/hw/piix_pci.c
> +++ b/hw/piix_pci.c
> @@ -364,6 +364,14 @@ static PCIDeviceInfo i440fx_info[] = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_piix3);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo i440fx_pcihost_info = {
>      .init         = i440fx_pcihost_initfn,
>      .qdev.name    = "i440FX-pcihost",
> diff --git a/hw/pl031.c b/hw/pl031.c
> index 8c2f9d0..5372e21 100644
> --- a/hw/pl031.c
> +++ b/hw/pl031.c
> @@ -229,6 +229,14 @@ static SysBusDeviceInfo pl031_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pl031);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pl031_register_devices(void)
>  {
>      sysbus_register_withprop(&pl031_info);
> diff --git a/hw/pl050.c b/hw/pl050.c
> index b155cc0..4c2b279 100644
> --- a/hw/pl050.c
> +++ b/hw/pl050.c
> @@ -171,6 +171,14 @@ static SysBusDeviceInfo pl050_kbd_info = {
>      .qdev.vmsd = &vmstate_pl050,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pl050);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo pl050_mouse_info = {
>      .init = pl050_init_mouse,
>      .qdev.name  = "pl050_mouse",
> @@ -178,6 +186,14 @@ static SysBusDeviceInfo pl050_mouse_info = {
>      .qdev.vmsd = &vmstate_pl050,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_pl050);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void pl050_register_devices(void)
>  {
>      sysbus_register_withprop(&pl050_kbd_info);
> diff --git a/hw/pl080.c b/hw/pl080.c
> index 901f04a..1c6198b 100644
> --- a/hw/pl080.c
> +++ b/hw/pl080.c
> @@ -388,6 +388,14 @@ static SysBusDeviceInfo pl080_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pl080);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo pl081_info = {
>      .init = pl081_init,
>      .qdev.name = "pl081",
> @@ -396,6 +404,14 @@ static SysBusDeviceInfo pl081_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_pl080);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  /* The PL080 and PL081 are the same except for the number of channels
>     they implement (8 and 2 respectively).  */
>  static void pl080_register_devices(void)
> diff --git a/hw/pl110.c b/hw/pl110.c
> index 06d2dfa..9073a40 100644
> --- a/hw/pl110.c
> +++ b/hw/pl110.c
> @@ -405,6 +405,14 @@ static SysBusDeviceInfo pl110_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pl110);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo pl110_versatile_info = {
>      .init = pl110_versatile_init,
>      .qdev.name = "pl110_versatile",
> @@ -413,6 +421,14 @@ static SysBusDeviceInfo pl110_versatile_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_pl110);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void pl110_register_devices(void)
>  {
>      sysbus_register_withprop(&pl110_info);
> diff --git a/hw/pl190.c b/hw/pl190.c
> index 75f2ba1..a03db5c 100644
> --- a/hw/pl190.c
> +++ b/hw/pl190.c
> @@ -270,6 +270,14 @@ static SysBusDeviceInfo pl190_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pl190);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pl190_register_devices(void)
>  {
>      sysbus_register_withprop(&pl190_info);
> diff --git a/hw/ps2.c b/hw/ps2.c
> index 91b73e0..c77d5fc 100644
> --- a/hw/ps2.c
> +++ b/hw/ps2.c
> @@ -615,6 +615,14 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
>      return s;
>  }
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ps2_keyboard);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
>  {
>      PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
> @@ -626,3 +634,11 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
>      qemu_register_reset(ps2_mouse_reset, s);
>      return s;
>  }
> +
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_ps2_mouse);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
> index 9b95e2c..d8f2943 100644
> --- a/hw/pxa2xx.c
> +++ b/hw/pxa2xx.c
> @@ -1293,6 +1293,14 @@ static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = {
>      .qdev.vmsd  = &vmstate_pxa2xx_rtc_regs,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_rtc_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  /* I2C Interface */
>  typedef struct {
>      i2c_slave i2c;
> @@ -1595,6 +1603,14 @@ static SysBusDeviceInfo pxa2xx_i2c_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_i2c);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  /* PXA Inter-IC Sound Controller */
>  static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s)
>  {
> diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
> index a67498b..6d5fb56 100644
> --- a/hw/pxa2xx_dma.c
> +++ b/hw/pxa2xx_dma.c
> @@ -561,6 +561,14 @@ static SysBusDeviceInfo pxa2xx_dma_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_dma);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pxa2xx_dma_register(void)
>  {
>      sysbus_register_withprop(&pxa2xx_dma_info);
> diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
> index e9a5361..fa6abba 100644
> --- a/hw/pxa2xx_pic.c
> +++ b/hw/pxa2xx_pic.c
> @@ -309,6 +309,14 @@ static SysBusDeviceInfo pxa2xx_pic_info = {
>      .qdev.vmsd  = &vmstate_pxa2xx_pic_regs,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_pic_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void pxa2xx_pic_register(void)
>  {
>      sysbus_register_withprop(&pxa2xx_pic_info);
> diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
> index f777a21..db0603e 100644
> --- a/hw/pxa2xx_timer.c
> +++ b/hw/pxa2xx_timer.c
> @@ -496,6 +496,14 @@ static SysBusDeviceInfo pxa25x_timer_dev_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_timer_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo pxa27x_timer_dev_info = {
>      .init       = pxa2xx_timer_init,
>      .qdev.name  = "pxa27x-timer",
> @@ -510,6 +518,14 @@ static SysBusDeviceInfo pxa27x_timer_dev_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_pxa2xx_timer_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void pxa2xx_timer_register(void)
>  {
>      sysbus_register_withprop(&pxa25x_timer_dev_info);
> diff --git a/hw/qxl.c b/hw/qxl.c
> index fe4212b..2a0d090 100644
> --- a/hw/qxl.c
> +++ b/hw/qxl.c
> @@ -1504,6 +1504,14 @@ static PCIDeviceInfo qxl_info_primary = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&qxl_vmstate);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static PCIDeviceInfo qxl_info_secondary = {
>      .qdev.name    = "qxl",
>      .qdev.desc    = "Spice QXL GPU (secondary)",
> @@ -1522,6 +1530,14 @@ static PCIDeviceInfo qxl_info_secondary = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&qxl_vmstate);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void qxl_register(void)
>  {
>      pci_qdev_register(&qxl_info_primary);
> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> index 0ba51fc..3b2f61e 100644
> --- a/hw/rtl8139.c
> +++ b/hw/rtl8139.c
> @@ -3269,6 +3269,14 @@ static const VMStateDescription vmstate_rtl8139 = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_rtl8139_hotplug_ready);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  /***********************************************************/
>  /* PCI RTL8139 definitions */
>  
> @@ -3422,6 +3430,14 @@ static PCIDeviceInfo rtl8139_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_rtl8139);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void rtl8139_register_devices(void)
>  {
>      pci_qdev_register(&rtl8139_info);
> diff --git a/hw/sb16.c b/hw/sb16.c
> index a76df1b..c98546a 100644
> --- a/hw/sb16.c
> +++ b/hw/sb16.c
> @@ -1413,6 +1413,14 @@ static ISADeviceInfo sb16_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_sb16);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void sb16_register (void)
>  {
>      isa_qdev_register (&sb16_info);
> diff --git a/hw/sbi.c b/hw/sbi.c
> index 53f66f2..53a236c 100644
> --- a/hw/sbi.c
> +++ b/hw/sbi.c
> @@ -140,6 +140,14 @@ static SysBusDeviceInfo sbi_info = {
>      .qdev.reset = sbi_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_sbi);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void sbi_register_devices(void)
>  {
>      sysbus_register_withprop(&sbi_info);
> diff --git a/hw/serial.c b/hw/serial.c
> index 0ee61dd..c7ba97c 100644
> --- a/hw/serial.c
> +++ b/hw/serial.c
> @@ -804,8 +804,6 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
>      s->chr = chr;
>      serial_init_core(s);
>  
> -    vmstate_register(NULL, base, &vmstate_serial, s);
> -
>      register_ioport_write(base, 8, 1, serial_ioport_write, s);
>      register_ioport_read(base, 8, 1, serial_ioport_read, s);
>      return s;
> @@ -971,6 +969,14 @@ static ISADeviceInfo serial_isa_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_isa_serial);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void serial_register_devices(void)
>  {
>      isa_qdev_register(&serial_isa_info);
> diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
> index a83e5b8..8b3bdb5 100644
> --- a/hw/slavio_intctl.c
> +++ b/hw/slavio_intctl.c
> @@ -455,6 +455,14 @@ static SysBusDeviceInfo slavio_intctl_info = {
>      .qdev.reset = slavio_intctl_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_intctl);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void slavio_intctl_register_devices(void)
>  {
>      sysbus_register_withprop(&slavio_intctl_info);
> diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
> index 198360d..0b415b9 100644
> --- a/hw/slavio_misc.c
> +++ b/hw/slavio_misc.c
> @@ -484,6 +484,14 @@ static SysBusDeviceInfo slavio_misc_info = {
>      .qdev.reset  = slavio_misc_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_misc);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static SysBusDeviceInfo apc_info = {
>      .init = apc_init1,
>      .qdev.name  = "apc",
> diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
> index 5511313..0f95113 100644
> --- a/hw/slavio_timer.c
> +++ b/hw/slavio_timer.c
> @@ -416,6 +416,14 @@ static SysBusDeviceInfo slavio_timer_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_slavio_timer);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void slavio_timer_register_devices(void)
>  {
>      sysbus_register_withprop(&slavio_timer_info);
> diff --git a/hw/smc91c111.c b/hw/smc91c111.c
> index dafea5c..63b4507 100644
> --- a/hw/smc91c111.c
> +++ b/hw/smc91c111.c
> @@ -774,6 +774,14 @@ static SysBusDeviceInfo smc91c111_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_smc91c111);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void smc91c111_register_devices(void)
>  {
>      sysbus_register_withprop(&smc91c111_info);
> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
> index e75694b..d8be398 100644
> --- a/hw/sparc32_dma.c
> +++ b/hw/sparc32_dma.c
> @@ -297,6 +297,14 @@ static SysBusDeviceInfo sparc32_dma_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_dma);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void sparc32_dma_register_devices(void)
>  {
>      sysbus_register_withprop(&sparc32_dma_info);
> diff --git a/hw/spitz.c b/hw/spitz.c
> index 006f7a9..1078486 100644
> --- a/hw/spitz.c
> +++ b/hw/spitz.c
> @@ -1043,6 +1043,14 @@ static SysBusDeviceInfo sl_nand_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_sl_nand_info);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static VMStateDescription vmstate_spitz_kbd = {
>      .name = "spitz-keyboard",
>      .version_id = 1,
> @@ -1067,6 +1075,14 @@ static SysBusDeviceInfo spitz_keyboard_info = {
>      },
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_spitz_kbd);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static const VMStateDescription vmstate_corgi_ssp_regs = {
>      .name = "corgi-ssp",
>      .version_id = 1,
> @@ -1086,6 +1102,14 @@ static SSISlaveInfo corgi_ssp_info = {
>      .transfer = corgi_ssp_transfer
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_2(void)
> +{
> +    register_vmstate_description(&vmstate_corgi_ssp_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_2);
> +
>  static const VMStateDescription vmstate_spitz_lcdtg_regs = {
>      .name = "spitz-lcdtg",
>      .version_id = 1,
> @@ -1106,6 +1130,14 @@ static SSISlaveInfo spitz_lcdtg_info = {
>      .transfer = spitz_lcdtg_transfer
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_3(void)
> +{
> +    register_vmstate_description(&vmstate_spitz_lcdtg_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_3);
> +
>  static void spitz_register_devices(void)
>  {
>      ssi_register_slave(&corgi_ssp_info);
> diff --git a/hw/ssd0303.c b/hw/ssd0303.c
> index 108c068..dc3012d 100644
> --- a/hw/ssd0303.c
> +++ b/hw/ssd0303.c
> @@ -304,6 +304,14 @@ static I2CSlaveInfo ssd0303_info = {
>      .send = ssd0303_send
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ssd0303);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void ssd0303_register_devices(void)
>  {
>      i2c_register_slave(&ssd0303_info);
> diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
> index 5c7fdef..025ea92 100644
> --- a/hw/sun4c_intctl.c
> +++ b/hw/sun4c_intctl.c
> @@ -216,6 +216,14 @@ static SysBusDeviceInfo sun4c_intctl_info = {
>      .qdev.reset = sun4c_intctl_reset,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_sun4c_intctl);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void sun4c_intctl_register_devices(void)
>  {
>      sysbus_register_withprop(&sun4c_intctl_info);
> diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
> index bba69ee..bb24412 100644
> --- a/hw/sun4m_iommu.c
> +++ b/hw/sun4m_iommu.c
> @@ -370,6 +370,14 @@ static SysBusDeviceInfo iommu_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_iommu);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void iommu_register_devices(void)
>  {
>      sysbus_register_withprop(&iommu_info);
> diff --git a/hw/tcx.c b/hw/tcx.c
> index 0e32830..40a771b 100644
> --- a/hw/tcx.c
> +++ b/hw/tcx.c
> @@ -643,6 +643,14 @@ static SysBusDeviceInfo tcx_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_tcx);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void tcx_register_devices(void)
>  {
>      sysbus_register_withprop(&tcx_info);
> diff --git a/hw/tmp105.c b/hw/tmp105.c
> index f7e6f2b..9d3325c 100644
> --- a/hw/tmp105.c
> +++ b/hw/tmp105.c
> @@ -236,6 +236,14 @@ static I2CSlaveInfo tmp105_info = {
>      .send = tmp105_tx
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_tmp105);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void tmp105_register_devices(void)
>  {
>      i2c_register_slave(&tmp105_info);
> diff --git a/hw/twl92230.c b/hw/twl92230.c
> index 8e74acc..2b570a6 100644
> --- a/hw/twl92230.c
> +++ b/hw/twl92230.c
> @@ -868,6 +868,14 @@ static I2CSlaveInfo twl92230_info = {
>      .send = menelaus_tx
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_menelaus);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void twl92230_register_devices(void)
>  {
>      i2c_register_slave(&twl92230_info);
> diff --git a/hw/usb-hid.c b/hw/usb-hid.c
> index c25362c..e8fff11 100644
> --- a/hw/usb-hid.c
> +++ b/hw/usb-hid.c
> @@ -999,6 +999,14 @@ static struct USBDeviceInfo hid_info[] = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_usb_kbd);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void usb_hid_register_devices(void)
>  {
>      usb_qdev_register_many(hid_info);
> diff --git a/hw/usb-hub.c b/hw/usb-hub.c
> index 3dd31ba..dfac0ed 100644
> --- a/hw/usb-hub.c
> +++ b/hw/usb-hub.c
> @@ -583,6 +583,14 @@ static struct USBDeviceInfo hub_info = {
>      .handle_destroy = usb_hub_handle_destroy,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_usb_hub);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void usb_hub_register_devices(void)
>  {
>      usb_qdev_register(&hub_info);
> diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
> index 346db3e..bc8fc5b 100644
> --- a/hw/usb-uhci.c
> +++ b/hw/usb-uhci.c
> @@ -1207,6 +1207,14 @@ static PCIDeviceInfo uhci_info[] = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_uhci);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void uhci_register(void)
>  {
>      pci_qdev_register_many(uhci_info);
> diff --git a/hw/versatilepb.c b/hw/versatilepb.c
> index 9f1bfcf..659359c 100644
> --- a/hw/versatilepb.c
> +++ b/hw/versatilepb.c
> @@ -354,6 +354,14 @@ static SysBusDeviceInfo vpb_sic_info = {
>      .qdev.no_user = 1,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_vpb_sic);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void versatilepb_register_devices(void)
>  {
>      sysbus_register_withprop(&vpb_sic_info);
> diff --git a/hw/vga-isa.c b/hw/vga-isa.c
> index fde0d56..5f1ef76 100644
> --- a/hw/vga-isa.c
> +++ b/hw/vga-isa.c
> @@ -81,6 +81,14 @@ static ISADeviceInfo vga_info = {
>      .init          = vga_initfn,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_vga_common);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void vga_register(void)
>  {
>      isa_qdev_register(&vga_info);
> diff --git a/hw/vga-pci.c b/hw/vga-pci.c
> index ce9ec45..c91739f 100644
> --- a/hw/vga-pci.c
> +++ b/hw/vga-pci.c
> @@ -116,6 +116,14 @@ static PCIDeviceInfo vga_info = {
>      .romfile      = "vgabios-stdvga.bin",
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_vga_pci);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void vga_register(void)
>  {
>      pci_qdev_register(&vga_info);
> diff --git a/hw/vmmouse.c b/hw/vmmouse.c
> index 1113f33..f2de7d8 100644
> --- a/hw/vmmouse.c
> +++ b/hw/vmmouse.c
> @@ -282,6 +282,14 @@ static ISADeviceInfo vmmouse_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_vmmouse);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void vmmouse_dev_register(void)
>  {
>      isa_qdev_register(&vmmouse_info);
> diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
> index 4656767..106c9b4 100644
> --- a/hw/vmware_vga.c
> +++ b/hw/vmware_vga.c
> @@ -1318,6 +1318,14 @@ static PCIDeviceInfo vmsvga_info = {
>      .romfile      = "vgabios-vmware.bin",
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_vmware_vga);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void vmsvga_register(void)
>  {
>      pci_qdev_register(&vmsvga_info);
> diff --git a/hw/vt82c686.c b/hw/vt82c686.c
> index 818460d..62b8c63 100644
> --- a/hw/vt82c686.c
> +++ b/hw/vt82c686.c
> @@ -522,6 +522,14 @@ static PCIDeviceInfo via_pm_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_acpi);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void vt82c686b_pm_register(void)
>  {
>      pci_qdev_register(&via_pm_info);
> @@ -587,6 +595,14 @@ static PCIDeviceInfo via_info = {
>      .config_write = vt82c686b_write_config,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_1(void)
> +{
> +    register_vmstate_description(&vmstate_via);
> +}
> +
> +vmstate_init(init_vmstate_description_1);
> +
>  static void vt82c686b_register(void)
>  {
>      pci_qdev_register(&via_info);
> diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
> index 4a7fba7..99f3c9b 100644
> --- a/hw/wdt_i6300esb.c
> +++ b/hw/wdt_i6300esb.c
> @@ -439,6 +439,14 @@ static PCIDeviceInfo i6300esb_info = {
>      .init         = i6300esb_init,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_i6300esb);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void i6300esb_register_devices(void)
>  {
>      watchdog_add_model(&model);
> diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c
> index 81f22d0..4cd24b9 100644
> --- a/hw/wdt_ib700.c
> +++ b/hw/wdt_ib700.c
> @@ -128,6 +128,14 @@ static ISADeviceInfo wdt_ib700_info = {
>      .init       = wdt_ib700_init,
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ib700);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void wdt_ib700_register_devices(void)
>  {
>      watchdog_add_model(&model);
> diff --git a/hw/wm8750.c b/hw/wm8750.c
> index c9c6744..dc46577 100644
> --- a/hw/wm8750.c
> +++ b/hw/wm8750.c
> @@ -699,6 +699,14 @@ static I2CSlaveInfo wm8750_info = {
>      .send = wm8750_tx
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_wm8750);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void wm8750_register_devices(void)
>  {
>      i2c_register_slave(&wm8750_info);
> diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
> index 5aa6a6b..f6fd902 100644
> --- a/hw/xio3130_downstream.c
> +++ b/hw/xio3130_downstream.c
> @@ -194,6 +194,14 @@ static PCIDeviceInfo xio3130_downstream_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_xio3130_downstream);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void xio3130_downstream_register(void)
>  {
>      pci_qdev_register(&xio3130_downstream_info);
> diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
> index a7640f5..0b503ee 100644
> --- a/hw/xio3130_upstream.c
> +++ b/hw/xio3130_upstream.c
> @@ -168,6 +168,14 @@ static PCIDeviceInfo xio3130_upstream_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_xio3130_upstream);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void xio3130_upstream_register(void)
>  {
>      pci_qdev_register(&xio3130_upstream_info);
> diff --git a/hw/zaurus.c b/hw/zaurus.c
> index c24aeb5..6ce61af 100644
> --- a/hw/zaurus.c
> +++ b/hw/zaurus.c
> @@ -236,6 +236,14 @@ static SysBusDeviceInfo scoop_sysbus_info = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_scoop_regs);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +
>  static void scoop_register(void)
>  {
>      sysbus_register_withprop(&scoop_sysbus_info);
> diff --git a/module.h b/module.h
> index 9263f1c..70c33a5 100644
> --- a/module.h
> +++ b/module.h
> @@ -24,12 +24,14 @@ typedef enum {
>      MODULE_INIT_BLOCK,
>      MODULE_INIT_DEVICE,
>      MODULE_INIT_MACHINE,
> +    MODULE_INIT_VMSTATE,
>      MODULE_INIT_MAX
>  } module_init_type;
>  
>  #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
>  #define device_init(function) module_init(function, MODULE_INIT_DEVICE)
>  #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
> +#define vmstate_init(function) module_init(function, MODULE_INIT_MACHINE)
>  
>  void register_module_init(void (*fn)(void), module_init_type type);
>  
> diff --git a/savevm.c b/savevm.c
> index 03fce62..4a37917 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1285,6 +1285,10 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
>      }
>  }
>  
> +void register_vmstate_description(const VMStateDescription *desc)
> +{
> +}
> +
>  static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
>                                      void *opaque);
>  static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
> diff --git a/target-i386/machine.c b/target-i386/machine.c
> index d78eceb..3a40520 100644
> --- a/target-i386/machine.c
> +++ b/target-i386/machine.c
> @@ -504,6 +504,14 @@ static const VMStateDescription vmstate_cpu = {
>      }
>  };
>  
> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description(void)
> +{
> +    register_vmstate_description(&vmstate_cpu);
> +}
> +
> +vmstate_init(init_vmstate_description);
> +
>  void cpu_save(QEMUFile *f, void *opaque)
>  {
>      vmstate_save_state(f, &vmstate_cpu, opaque);
> -- 
> 1.7.0.4
> 
> 

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

* [Qemu-devel] Re: [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  8:58         ` Roy Tam
@ 2011-03-23  9:19           ` Paolo Bonzini
  2011-03-23  9:22           ` [Qemu-devel] " Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Paolo Bonzini @ 2011-03-23  9:19 UTC (permalink / raw)
  To: Roy Tam
  Cc: Stefan Hajnoczi, Anthony Liguori, Juan Quintela, qemu-devel,
	Jan Kiszka

On 03/23/2011 09:58 AM, Roy Tam wrote:
> I think I have to change my words. Glib works in win32, but adding
> Glib to QEMU will bloat the binary size. It adds more dependency on
> building and the result binary. I wonder if it is a must to add it.

That's very far from my definition of "breaking".

Paolo

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

* Re: [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib
  2011-03-23  8:58         ` Roy Tam
  2011-03-23  9:19           ` [Qemu-devel] " Paolo Bonzini
@ 2011-03-23  9:22           ` Stefan Hajnoczi
  1 sibling, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2011-03-23  9:22 UTC (permalink / raw)
  To: Roy Tam
  Cc: Jan Kiszka, Anthony Liguori, Paolo Bonzini, qemu-devel,
	Juan Quintela

On Wed, Mar 23, 2011 at 8:58 AM, Roy Tam <roytam@gmail.com> wrote:
> I think I have to change my words. Glib works in win32, but adding
> Glib to QEMU will bloat the binary size. It adds more dependency on
> building and the result binary. I wonder if it is a must to add it.

If we stick to re-implementing cross-platform wrappers then Windows
support will always lag behind POSIX and developers will spend effort
working around platform quirks rather than improving QEMU.  Very few
QEMU developers build on Windows, for example Paolo's latest Windows
iothread support patches were tested under Wine.

Will introducing glib add a dependency and at worst some temporary
breakage?  Yes, there's a risk.  But longer term this is great news
for Windows because it gives it a chance of actually working on a
level close to *nix.

Stefan

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

* [Qemu-devel] Re: [PATCH 04/11] sb16: fix migration quirk
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 04/11] sb16: fix migration quirk Anthony Liguori
@ 2011-03-23  9:51   ` Juan Quintela
  2011-03-23 12:16     ` Anthony Liguori
  0 siblings, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23  9:51 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel

Anthony Liguori <aliguori@us.ibm.com> wrote:
> We seem to migrate the same field twice.  It's been this way since Fabrice
> committed the original file.  Since semantically, we basically ignore the first
> value, make this an unused entry.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/sb16.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/hw/sb16.c b/hw/sb16.c
> index c98546a..1c30e4c 100644
> --- a/hw/sb16.c
> +++ b/hw/sb16.c
> @@ -77,6 +77,7 @@ typedef struct SB16State {
>  
>      int v2x6;
>  
> +    uint8_t csp_param_dummy;
>      uint8_t csp_param;
>      uint8_t csp_value;
>      uint8_t csp_mode;
> @@ -1313,7 +1314,7 @@ static const VMStateDescription vmstate_sb16 = {
>          VMSTATE_INT32(can_write, SB16State),
>          VMSTATE_INT32(v2x6, SB16State),
>  
> -        VMSTATE_UINT8(csp_param, SB16State),
> +        VMSTATE_UINT8(csp_param_dummy, SB16State),
>          VMSTATE_UINT8(csp_value, SB16State),
>          VMSTATE_UINT8(csp_mode, SB16State),
>          VMSTATE_UINT8(csp_param, SB16State),

VMSTATE_UNUSED(1) instead?

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 05/11] vga-isa: fix migration by breaking it
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 05/11] vga-isa: fix migration by breaking it Anthony Liguori
@ 2011-03-23  9:54   ` Juan Quintela
  0 siblings, 0 replies; 49+ messages in thread
From: Juan Quintela @ 2011-03-23  9:54 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel

Anthony Liguori <aliguori@us.ibm.com> wrote:
> This is pretty sad.  We use the same section name for vga-isa as we do for
> vga-pci even though we use separate formats.  This breaks the live migration
> protocol because we may misinterpret the vga-isa as a vga-pci device.
>
> vga-isa should use it's own wrapper just like vga-pci does.  That's what we do
> in this patch.
>
> Signed-by-off: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/vga-isa.c |   13 +++++++++++--
>  1 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/hw/vga-isa.c b/hw/vga-isa.c
> index 5f1ef76..eaae2e0 100644
> --- a/hw/vga-isa.c
> +++ b/hw/vga-isa.c
> @@ -72,10 +72,19 @@ static int vga_initfn(ISADevice *dev)
>      return 0;
>  }
>  
> +static const VMStateDescription vmstate_vga_isa = {
> +    .name = "isa-vga",
> +    .version_id = 1,
> +    .fields = (VMStateField []) {
> +        VMSTATE_STRUCT(state, ISAVGAState, 0, vmstate_vga_common, VGACommonState),
> +        VMSTATE_END_OF_LIST(),
> +    },
> +};
> +
>  static ISADeviceInfo vga_info = {
>      .qdev.name     = "isa-vga",
>      .qdev.size     = sizeof(ISAVGAState),
> -    .qdev.vmsd     = &vmstate_vga_common,
> +    .qdev.vmsd     = &vmstate_vga_isa,
>      .qdev.reset     = vga_reset_isa,
>      .qdev.no_user  = 1,
>      .init          = vga_initfn,
> @@ -84,7 +93,7 @@ static ISADeviceInfo vga_info = {
>  /* Register the VMState Description to support VMState introspection */
>  static void init_vmstate_description_0(void)
>  {
> -    register_vmstate_description(&vmstate_vga_common);
> +    register_vmstate_description(&vmstate_vga_isa);
>  }
>  
>  vmstate_init(init_vmstate_description_0);

This was done that way when I ported this device.

This define is also always setup CONFIG_BOCHS_VBE, and at some point it
didn't worked without it.

But this is a different problem that doing the tests.

Later, JUan.

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

* [Qemu-devel] Re: [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names Anthony Liguori
@ 2011-03-23  9:58   ` Juan Quintela
  2011-03-23 12:34     ` Anthony Liguori
  0 siblings, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23  9:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel

Anthony Liguori <aliguori@us.ibm.com> wrote:
> I don't fully understand this hack business but we need field to be unique so..
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/eeprom93xx.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
> index cfa695d..f1d75ec 100644
> --- a/hw/eeprom93xx.c
> +++ b/hw/eeprom93xx.c
> @@ -114,7 +114,7 @@ static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
>  };
>  
>  #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
> -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
> +    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>  
>  static bool is_old_eeprom_version(void *opaque, int version_id)
>  {

After the fact, we need to promote it as "full types".

Basically it is needed when we sent a field with a different size that
we use it on the struct.

if we have

struct FOOState {
       int32_t bar;
....
}

and it is sent as

VMSTATE_INT8(bar, ....)

In this case, I went through the whole device, checed that int8_t was
enough and did the change.

But if we have:

struct FOOState {
       int8_t bar;
....
}

and it is sent as

VMSTATE_INT32(bar, ....)

Then it is not trivial :-(

We change FOOState to int32 or we break migration format.  Here is where
the _HACK suffix appeared.

I thought it was not going to be needed a lot, but there are several
devices that just sent everything over the wire as uint32, independently
of its type.

Later, Juan.

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

* Re: [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
  2011-03-23  2:31   ` Anthony Liguori
  2011-03-23  8:37   ` Stefan Hajnoczi
@ 2011-03-23 10:22   ` Peter Maydell
  2011-03-23 12:42     ` Anthony Liguori
  2011-03-23 14:19     ` Juan Quintela
  2 siblings, 2 replies; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 10:22 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On 23 March 2011 00:16, Anthony Liguori <aliguori@us.ibm.com> wrote:
> +    if (old_version != new_version) {
> +        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
> +                new_version, device, old_version);
> +    }

Might be nice for these "please update" error messages to
include a pointer to a docs file explaining in more detail
how to do that?
(also >80 char line ;-))

> diff --git a/vmstate/schema.json b/vmstate/schema.json
> new file mode 100644
> index 0000000..23483ab
> --- /dev/null
> +++ b/vmstate/schema.json
> @@ -0,0 +1,1176 @@
> +{
> +    "cpu": {
> +        "mcg_cap": "uint64",
> +        "a20_mask": "int32",
> +        "tsc_offset": "uint64",

This schema file appears to be board-specific (or at least
x86-specific) -- shouldn't the cpu/board/whatever name
be in the filename, so we have scope to expand the test
to checking migration issues for other platforms too?

(I don't care much about ARM migration breakages just at the
moment but I suspect that it will be becoming more important
by this time next year...)

Also since this looks like an autogenerated file that's going
to be going into version control maybe it should have a
comment header at the top of the "autogenerated, do not edit
by hand!" type.

-- PMM

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

* Re: [Qemu-devel] Re: [PATCH 04/11] sb16: fix migration quirk
  2011-03-23  9:51   ` [Qemu-devel] " Juan Quintela
@ 2011-03-23 12:16     ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 12:16 UTC (permalink / raw)
  To: quintela; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

On 03/23/2011 04:51 AM, Juan Quintela wrote:
> Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> We seem to migrate the same field twice.  It's been this way since Fabrice
>> committed the original file.  Since semantically, we basically ignore the first
>> value, make this an unused entry.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>>   hw/sb16.c |    3 ++-
>>   1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/sb16.c b/hw/sb16.c
>> index c98546a..1c30e4c 100644
>> --- a/hw/sb16.c
>> +++ b/hw/sb16.c
>> @@ -77,6 +77,7 @@ typedef struct SB16State {
>>
>>       int v2x6;
>>
>> +    uint8_t csp_param_dummy;
>>       uint8_t csp_param;
>>       uint8_t csp_value;
>>       uint8_t csp_mode;
>> @@ -1313,7 +1314,7 @@ static const VMStateDescription vmstate_sb16 = {
>>           VMSTATE_INT32(can_write, SB16State),
>>           VMSTATE_INT32(v2x6, SB16State),
>>
>> -        VMSTATE_UINT8(csp_param, SB16State),
>> +        VMSTATE_UINT8(csp_param_dummy, SB16State),
>>           VMSTATE_UINT8(csp_value, SB16State),
>>           VMSTATE_UINT8(csp_mode, SB16State),
>>           VMSTATE_UINT8(csp_param, SB16State),
> VMSTATE_UNUSED(1) instead?

Ack.  I forgot to update this patch to do that.

Regards,

Anthony Liguori

> Later, Juan.
>

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

* Re: [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions
  2011-03-23  0:16 ` [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions Anthony Liguori
  2011-03-23  9:00   ` Alon Levy
@ 2011-03-23 12:30   ` Peter Maydell
  2011-03-23 12:37     ` Anthony Liguori
  1 sibling, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 12:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On 23 March 2011 00:16, Anthony Liguori <aliguori@us.ibm.com> wrote:
> This is a purely mechanical change.

> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_ac97);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +

> +/* Register the VMState Description to support VMState introspection */
> +static void init_vmstate_description_0(void)
> +{
> +    register_vmstate_description(&vmstate_acpi);
> +}
> +
> +vmstate_init(init_vmstate_description_0);
> +

Do we really need five lines of boilerplate for every device?

(I'm wondering if there's some way you could avoid having
all this for the common case where the vmstate is pointed to
by the DeviceInfo struct, given that we already register
all the devices. Failing that, some sort of macro...)

-- PMM

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

* Re: [Qemu-devel] Re: [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names
  2011-03-23  9:58   ` [Qemu-devel] " Juan Quintela
@ 2011-03-23 12:34     ` Anthony Liguori
  2011-03-23 14:14       ` Juan Quintela
  0 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 12:34 UTC (permalink / raw)
  To: quintela; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

On 03/23/2011 04:58 AM, Juan Quintela wrote:
> Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> I don't fully understand this hack business but we need field to be unique so..
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>>   hw/eeprom93xx.c |    2 +-
>>   1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
>> index cfa695d..f1d75ec 100644
>> --- a/hw/eeprom93xx.c
>> +++ b/hw/eeprom93xx.c
>> @@ -114,7 +114,7 @@ static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
>>   };
>>
>>   #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
>> -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>> +    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>>
>>   static bool is_old_eeprom_version(void *opaque, int version_id)
>>   {
> After the fact, we need to promote it as "full types".
>
> Basically it is needed when we sent a field with a different size that
> we use it on the struct.
>
> if we have
>
> struct FOOState {
>         int32_t bar;
> ....
> }
>
> and it is sent as
>
> VMSTATE_INT8(bar, ....)
>
> In this case, I went through the whole device, checed that int8_t was
> enough and did the change.
>
> But if we have:
>
> struct FOOState {
>         int8_t bar;
> ....
> }
>
> and it is sent as
>
> VMSTATE_INT32(bar, ....)
>
> Then it is not trivial :-(
>
> We change FOOState to int32 or we break migration format.  Here is where
> the _HACK suffix appeared.
>
> I thought it was not going to be needed a lot, but there are several
> devices that just sent everything over the wire as uint32, independently
> of its type.

Could we get away with just doing:

VMSTATE_UNUSED(3),
VMSTATE_UINT8(bar, ...),

That's fully compatible on the wire and seems to be a clearer expression 
of exactly what the problem is.

Regards,

Anthony Liguori

> Later, Juan.
>

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

* Re: [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions
  2011-03-23 12:30   ` Peter Maydell
@ 2011-03-23 12:37     ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 12:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel, Juan Quintela

On 03/23/2011 07:30 AM, Peter Maydell wrote:
> On 23 March 2011 00:16, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> This is a purely mechanical change.
>> +/* Register the VMState Description to support VMState introspection */
>> +static void init_vmstate_description_0(void)
>> +{
>> +    register_vmstate_description(&vmstate_ac97);
>> +}
>> +
>> +vmstate_init(init_vmstate_description_0);
>> +
>> +/* Register the VMState Description to support VMState introspection */
>> +static void init_vmstate_description_0(void)
>> +{
>> +    register_vmstate_description(&vmstate_acpi);
>> +}
>> +
>> +vmstate_init(init_vmstate_description_0);
>> +
> Do we really need five lines of boilerplate for every device?
>
> (I'm wondering if there's some way you could avoid having
> all this for the common case where the vmstate is pointed to
> by the DeviceInfo struct, given that we already register
> all the devices. Failing that, some sort of macro...)

Heh, well that just goes right and head and tremendously simplifies 
everything :-)

There are just a few cases where VMStateDescription is not reachable via 
DeviceInfo so DeviceInfo is definitely the way to go.

Regards,

Anthony Liguori

> -- PMM
>

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

* Re: [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 10:22   ` Peter Maydell
@ 2011-03-23 12:42     ` Anthony Liguori
  2011-03-23 14:17       ` [Qemu-devel] " Juan Quintela
  2011-03-23 14:19     ` Juan Quintela
  1 sibling, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 12:42 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, qemu-devel, Juan Quintela

On 03/23/2011 05:22 AM, Peter Maydell wrote:
> On 23 March 2011 00:16, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> +    if (old_version != new_version) {
>> +        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
>> +                new_version, device, old_version);
>> +    }
> Might be nice for these "please update" error messages to
> include a pointer to a docs file explaining in more detail
> how to do that?
> (also>80 char line ;-))

Ack.

>> diff --git a/vmstate/schema.json b/vmstate/schema.json
>> new file mode 100644
>> index 0000000..23483ab
>> --- /dev/null
>> +++ b/vmstate/schema.json
>> @@ -0,0 +1,1176 @@
>> +{
>> +    "cpu": {
>> +        "mcg_cap": "uint64",
>> +        "a20_mask": "int32",
>> +        "tsc_offset": "uint64",
> This schema file appears to be board-specific (or at least
> x86-specific) -- shouldn't the cpu/board/whatever name
> be in the filename, so we have scope to expand the test
> to checking migration issues for other platforms too?

It's not really.  Every VMStateDescription that is builtin into the tree 
is in the file.

That said, the only target where the CPU is currently described by 
VMStateDescription is target-i386.

Right now the file is generated via i386-softmmu.  There may be a few 
devices left out because they are either not compiled into i386-softmmu 
or are target specific.

We could complicate things further by trying to run against every target 
and then building a union of all target outputs but I'm not sure it's 
worth the effort at this stage.

> (I don't care much about ARM migration breakages just at the
> moment but I suspect that it will be becoming more important
> by this time next year...)
>
> Also since this looks like an autogenerated file that's going
> to be going into version control maybe it should have a
> comment header at the top of the "autogenerated, do not edit
> by hand!" type.

JSON doesn't support comments..  I can add comment parsing to our parser 
though.

Regards,

Anthony Liguori

> -- PMM
>

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

* [Qemu-devel] Re: [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names
  2011-03-23 12:34     ` Anthony Liguori
@ 2011-03-23 14:14       ` Juan Quintela
  2011-03-23 14:33         ` Anthony Liguori
  0 siblings, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 14:14 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 03/23/2011 04:58 AM, Juan Quintela wrote:
>> Anthony Liguori<aliguori@us.ibm.com>  wrote:
>>> I don't fully understand this hack business but we need field to be unique so..
>>>
>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>> ---
>>>   hw/eeprom93xx.c |    2 +-
>>>   1 files changed, 1 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
>>> index cfa695d..f1d75ec 100644
>>> --- a/hw/eeprom93xx.c
>>> +++ b/hw/eeprom93xx.c
>>> @@ -114,7 +114,7 @@ static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
>>>   };
>>>
>>>   #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
>>> -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>>> +    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>>>
>>>   static bool is_old_eeprom_version(void *opaque, int version_id)
>>>   {

> Could we get away with just doing:
>
> VMSTATE_UNUSED(3),
> VMSTATE_UINT8(bar, ...),

Remember that we are "supposed to be" big/little endian safe.

> That's fully compatible on the wire and seems to be a clearer
> expression of exactly what the problem is.

if we are going to break big endian machines, I fully agree.

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 12:42     ` Anthony Liguori
@ 2011-03-23 14:17       ` Juan Quintela
  2011-03-23 14:52         ` Anthony Liguori
  0 siblings, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 14:17 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, qemu-devel, Jan Kiszka

Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 03/23/2011 05:22 AM, Peter Maydell wrote:
>> On 23 March 2011 00:16, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>>> +    if (old_version != new_version) {
>>> +        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
>>> +                new_version, device, old_version);
>>> +    }
>> Might be nice for these "please update" error messages to
>> include a pointer to a docs file explaining in more detail
>> how to do that?
>> (also>80 char line ;-))
>
> Ack.
>
>>> diff --git a/vmstate/schema.json b/vmstate/schema.json
>>> new file mode 100644
>>> index 0000000..23483ab
>>> --- /dev/null
>>> +++ b/vmstate/schema.json
>>> @@ -0,0 +1,1176 @@
>>> +{
>>> +    "cpu": {
>>> +        "mcg_cap": "uint64",
>>> +        "a20_mask": "int32",
>>> +        "tsc_offset": "uint64",
>> This schema file appears to be board-specific (or at least
>> x86-specific) -- shouldn't the cpu/board/whatever name
>> be in the filename, so we have scope to expand the test
>> to checking migration issues for other platforms too?
>
> It's not really.  Every VMStateDescription that is builtin into the
> tree is in the file.
>
> That said, the only target where the CPU is currently described by
> VMStateDescription is target-i386.
>
> Right now the file is generated via i386-softmmu.  There may be a few
> devices left out because they are either not compiled into
> i386-softmmu or are target specific.
>
> We could complicate things further by trying to run against every
> target and then building a union of all target outputs but I'm not
> sure it's worth the effort at this stage.
>
>> (I don't care much about ARM migration breakages just at the
>> moment but I suspect that it will be becoming more important
>> by this time next year...)
>>
>> Also since this looks like an autogenerated file that's going
>> to be going into version control maybe it should have a
>> comment header at the top of the "autogenerated, do not edit
>> by hand!" type.
>
> JSON doesn't support comments..  I can add comment parsing to our
> parser though.

We need to fix the ordering problem.

Whatever schema we have should be good enough to allow:
- describe me this blob that contains the state for this device.

eepro100 at least is missing.  Althought I would vote to just change the
eepro100 "naming" to always use eepro100 or similar, and remove the
current hack of having to change the vmstate->name for each different
device.

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 10:22   ` Peter Maydell
  2011-03-23 12:42     ` Anthony Liguori
@ 2011-03-23 14:19     ` Juan Quintela
  2011-03-23 14:36       ` Peter Maydell
  1 sibling, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 14:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 March 2011 00:16, Anthony Liguori <aliguori@us.ibm.com> wrote:
>> +    if (old_version != new_version) {
>> +        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
>> +                new_version, device, old_version);
>> +    }
>
> Might be nice for these "please update" error messages to
> include a pointer to a docs file explaining in more detail
> how to do that?
> (also >80 char line ;-))
>
>> diff --git a/vmstate/schema.json b/vmstate/schema.json
>> new file mode 100644
>> index 0000000..23483ab
>> --- /dev/null
>> +++ b/vmstate/schema.json
>> @@ -0,0 +1,1176 @@
>> +{
>> +    "cpu": {
>> +        "mcg_cap": "uint64",
>> +        "a20_mask": "int32",
>> +        "tsc_offset": "uint64",
>
> This schema file appears to be board-specific (or at least
> x86-specific) -- shouldn't the cpu/board/whatever name
> be in the filename, so we have scope to expand the test
> to checking migration issues for other platforms too?
>
> (I don't care much about ARM migration breakages just at the
> moment but I suspect that it will be becoming more important
> by this time next year...)
>
> Also since this looks like an autogenerated file that's going
> to be going into version control maybe it should have a
> comment header at the top of the "autogenerated, do not edit
> by hand!" type.

I agree with you.  Just passing another argument to all programs telling
what we are talking about would be much better for this.

And we need (at least) x86_64 & i386 (this ones are supposed to work).
ARM people are sending lots of vmstate changes, I guess/hope that
somebody is trying to get it working.

/me looks at Peter O:-), hint, hint, ...

Any idea if there are images for testing ARM?

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names
  2011-03-23 14:14       ` Juan Quintela
@ 2011-03-23 14:33         ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 14:33 UTC (permalink / raw)
  To: quintela; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

On 03/23/2011 09:14 AM, Juan Quintela wrote:
> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> On 03/23/2011 04:58 AM, Juan Quintela wrote:
>>> Anthony Liguori<aliguori@us.ibm.com>   wrote:
>>>> I don't fully understand this hack business but we need field to be unique so..
>>>>
>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>> ---
>>>>    hw/eeprom93xx.c |    2 +-
>>>>    1 files changed, 1 insertions(+), 1 deletions(-)
>>>>
>>>> diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
>>>> index cfa695d..f1d75ec 100644
>>>> --- a/hw/eeprom93xx.c
>>>> +++ b/hw/eeprom93xx.c
>>>> @@ -114,7 +114,7 @@ static const VMStateInfo vmstate_hack_uint16_from_uint8 = {
>>>>    };
>>>>
>>>>    #define VMSTATE_UINT16_HACK_TEST(_f, _s, _t)                           \
>>>> -    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>>>> +    VMSTATE_SINGLE_TEST_HACK(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t)
>>>>
>>>>    static bool is_old_eeprom_version(void *opaque, int version_id)
>>>>    {
>> Could we get away with just doing:
>>
>> VMSTATE_UNUSED(3),
>> VMSTATE_UINT8(bar, ...),
> Remember that we are "supposed to be" big/little endian safe.

We always send in network byte order (big endian) so this is safe.

>> That's fully compatible on the wire and seems to be a clearer
>> expression of exactly what the problem is.
> if we are going to break big endian machines, I fully agree.

The migration protocol is always big endian, see:

void qemu_put_be32(QEMUFile *f, unsigned int v)
{
     qemu_put_byte(f, v >> 24);
     qemu_put_byte(f, v >> 16);
     qemu_put_byte(f, v >> 8);
     qemu_put_byte(f, v);
}

So this is completely safe.

Regards,

ANthony Liguori

> Later, Juan.

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 14:19     ` Juan Quintela
@ 2011-03-23 14:36       ` Peter Maydell
  2011-03-23 15:13         ` Juan Quintela
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 14:36 UTC (permalink / raw)
  To: quintela; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

On 23 March 2011 14:19, Juan Quintela <quintela@redhat.com> wrote:
> Peter Maydell <peter.maydell@linaro.org> wrote:
> ARM people are sending lots of vmstate changes, I guess/hope that
> somebody is trying to get it working.
>
> /me looks at Peter O:-), hint, hint, ...

Well, the main thing I care about currently (or did back before
Christmas which is when I sent a patchset to add save/restore
to a pile of ARM devices) is simple save-and-restore for debugging
use. The rest is just that patches don't get through code review
unless they get the vmstate stuff right, and I care about not
being rejected :-)

I think it's still the case that there are devices in
some of the ARM devboards with no save/restore support
at all. I would really prefer it if the default for a
device was "I do not support this" with the things like
USB where somebody has audited them as genuinely needing
no save/restore code explicitly marked as "this is OK";
then we could easily determine what needed fixing and
not offer a broken facility to users.

> Any idea if there are images for testing ARM?

There are prebuilt images on Aurelien's website for
ARM and others, which is the simplest thing:
http://www.aurel32.net/info/debian_arm_qemu.php

-- PMM

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 14:17       ` [Qemu-devel] " Juan Quintela
@ 2011-03-23 14:52         ` Anthony Liguori
  2011-03-23 15:00           ` Peter Maydell
  2011-03-23 15:26           ` Juan Quintela
  0 siblings, 2 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 14:52 UTC (permalink / raw)
  To: quintela; +Cc: Peter Maydell, qemu-devel, Jan Kiszka

On 03/23/2011 09:17 AM, Juan Quintela wrote:
> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> On 03/23/2011 05:22 AM, Peter Maydell wrote:
>>> On 23 March 2011 00:16, Anthony Liguori<aliguori@us.ibm.com>   wrote:
>>>> +    if (old_version != new_version) {
>>>> +        g_error("Version %d of device `%s' is available in QEMU, but schema still reports %d, please update schema.\n",
>>>> +                new_version, device, old_version);
>>>> +    }
>>> Might be nice for these "please update" error messages to
>>> include a pointer to a docs file explaining in more detail
>>> how to do that?
>>> (also>80 char line ;-))
>> Ack.
>>
>>>> diff --git a/vmstate/schema.json b/vmstate/schema.json
>>>> new file mode 100644
>>>> index 0000000..23483ab
>>>> --- /dev/null
>>>> +++ b/vmstate/schema.json
>>>> @@ -0,0 +1,1176 @@
>>>> +{
>>>> +    "cpu": {
>>>> +        "mcg_cap": "uint64",
>>>> +        "a20_mask": "int32",
>>>> +        "tsc_offset": "uint64",
>>> This schema file appears to be board-specific (or at least
>>> x86-specific) -- shouldn't the cpu/board/whatever name
>>> be in the filename, so we have scope to expand the test
>>> to checking migration issues for other platforms too?
>> It's not really.  Every VMStateDescription that is builtin into the
>> tree is in the file.
>>
>> That said, the only target where the CPU is currently described by
>> VMStateDescription is target-i386.
>>
>> Right now the file is generated via i386-softmmu.  There may be a few
>> devices left out because they are either not compiled into
>> i386-softmmu or are target specific.
>>
>> We could complicate things further by trying to run against every
>> target and then building a union of all target outputs but I'm not
>> sure it's worth the effort at this stage.
>>
>>> (I don't care much about ARM migration breakages just at the
>>> moment but I suspect that it will be becoming more important
>>> by this time next year...)
>>>
>>> Also since this looks like an autogenerated file that's going
>>> to be going into version control maybe it should have a
>>> comment header at the top of the "autogenerated, do not edit
>>> by hand!" type.
>> JSON doesn't support comments..  I can add comment parsing to our
>> parser though.
> We need to fix the ordering problem.

Dunno what you mean by ordering.

> Whatever schema we have should be good enough to allow:
> - describe me this blob that contains the state for this device.

Schema for VMState is different than what's used for this test case 
here.  I agree, it's a harder problem than just what's being spit out 
here :-)

> eepro100 at least is missing.  Althought I would vote to just change the
> eepro100 "naming" to always use eepro100 or similar, and remove the
> current hack of having to change the vmstate->name for each different
> device.

I just ran into eepro100 and my head nearly exploded.

I set the name to be eepro100-base and then just added that once.  A 
better solution would be to separate out the fields such that we can 
have a bunch of VMStateDescriptions that all use the same fields.

I think we ought to merge VMStateDescription into DeviceInfo.  For 
compatibility, we probably need a vmstate_alias name since the device 
names don't always map 1-1 with the qdev names.  But this should 
eliminate the problem of reusing VMStateDescriptions for multiple devices.

Regards,

Anthony Liguori

> Later, Juan.
>

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 14:52         ` Anthony Liguori
@ 2011-03-23 15:00           ` Peter Maydell
  2011-03-23 15:06             ` Jan Kiszka
  2011-03-23 16:27             ` Anthony Liguori
  2011-03-23 15:26           ` Juan Quintela
  1 sibling, 2 replies; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 15:00 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, quintela

On 23 March 2011 14:52, Anthony Liguori <anthony@codemonkey.ws> wrote:
> I think we ought to merge VMStateDescription into DeviceInfo.  For
> compatibility, we probably need a vmstate_alias name since the device names
> don't always map 1-1 with the qdev names.  But this should eliminate the
> problem of reusing VMStateDescriptions for multiple devices.

That's a feature, not a bug. Consider eg hw/pl110.c -- there
are two different DeviceInfo devices but since the underlying
implementation is the same you definitely don't want to have
two separate VMStateDescription structures to get out of sync.

-- PMM

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 15:00           ` Peter Maydell
@ 2011-03-23 15:06             ` Jan Kiszka
  2011-03-23 16:27             ` Anthony Liguori
  1 sibling, 0 replies; 49+ messages in thread
From: Jan Kiszka @ 2011-03-23 15:06 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel@nongnu.org, quintela@redhat.com

On 2011-03-23 16:00, Peter Maydell wrote:
> On 23 March 2011 14:52, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> I think we ought to merge VMStateDescription into DeviceInfo.  For
>> compatibility, we probably need a vmstate_alias name since the device names
>> don't always map 1-1 with the qdev names.  But this should eliminate the
>> problem of reusing VMStateDescriptions for multiple devices.
> 
> That's a feature, not a bug. Consider eg hw/pl110.c -- there
> are two different DeviceInfo devices but since the underlying
> implementation is the same you definitely don't want to have
> two separate VMStateDescription structures to get out of sync.

Yep. i8254/apic/ioapic vs. (upcoming) i8254-kvm/apic-kvm/ioapic-kvm will
provide further use cases.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 14:36       ` Peter Maydell
@ 2011-03-23 15:13         ` Juan Quintela
  2011-03-23 15:24           ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 15:13 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 March 2011 14:19, Juan Quintela <quintela@redhat.com> wrote:
>> Peter Maydell <peter.maydell@linaro.org> wrote:
>> ARM people are sending lots of vmstate changes, I guess/hope that
>> somebody is trying to get it working.
>>
>> /me looks at Peter O:-), hint, hint, ...
>
> Well, the main thing I care about currently (or did back before
> Christmas which is when I sent a patchset to add save/restore
> to a pile of ARM devices) is simple save-and-restore for debugging
> use. The rest is just that patches don't get through code review
> unless they get the vmstate stuff right, and I care about not
> being rejected :-)
>
> I think it's still the case that there are devices in
> some of the ARM devboards with no save/restore support
> at all. I would really prefer it if the default for a
> device was "I do not support this" with the things like
> USB where somebody has audited them as genuinely needing
> no save/restore code explicitly marked as "this is OK";
> then we could easily determine what needed fixing and
> not offer a broken facility to users.

I agree, but that means (again), review of all devices to change the
defaults.  It is on my ToDo list (but my ToDo list is huge :-(

>> Any idea if there are images for testing ARM?
>
> There are prebuilt images on Aurelien's website for
> ARM and others, which is the simplest thing:
> http://www.aurel32.net/info/debian_arm_qemu.php

That images don't migrate for me at all.  Guest got hung after
migration, at least some state (probably irq's) are not passed
correctly.

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 15:13         ` Juan Quintela
@ 2011-03-23 15:24           ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 15:24 UTC (permalink / raw)
  To: quintela; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel

On 23 March 2011 15:13, Juan Quintela <quintela@redhat.com> wrote:
> Peter Maydell <peter.maydell@linaro.org> wrote:
>> There are prebuilt images on Aurelien's website for
>> ARM and others, which is the simplest thing:
>> http://www.aurel32.net/info/debian_arm_qemu.php
>
> That images don't migrate for me at all.  Guest got hung after
> migration, at least some state (probably irq's) are not passed
> correctly.

Yeah, I said they were probably buggy. The only thing I've
ever tested is vmsave/restore for versatilepb, and that was
a few months ago now.

-- PMM

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 14:52         ` Anthony Liguori
  2011-03-23 15:00           ` Peter Maydell
@ 2011-03-23 15:26           ` Juan Quintela
  2011-03-23 16:14             ` Anthony Liguori
  1 sibling, 1 reply; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 15:26 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, qemu-devel, Jan Kiszka

Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 03/23/2011 09:17 AM, Juan Quintela wrote:
>> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> We need to fix the ordering problem.
>
> Dunno what you mean by ordering.

vmstate:

static const VMStateDescription vmstate_cpu = {
    .name = "cpu",
    .version_id = CPU_SAVE_VERSION,
    .minimum_version_id = 3,
    .minimum_version_id_old = 3,
    .pre_save = cpu_pre_save,
    .post_load = cpu_post_load,
    .fields      = (VMStateField []) {
        VMSTATE_UINTTL_ARRAY(regs, CPUState, CPU_NB_REGS),
        VMSTATE_UINTTL(eip, CPUState),
        VMSTATE_UINTTL(eflags, CPUState),
        VMSTATE_UINT32(hflags, CPUState),
        /* FPU */


vs

dump

    "cpu": {
        "mcg_cap": "uint64", 
        "a20_mask": "int32", 
        "tsc_offset": "uint64", 
        "idt": {
            "flags": "uint32", 
            "limit": "uint32", 
            "selector": "uint32", 
            "base": "uint32", 
            "__version__": 1
        }, 
        "intercept_cr_write": "uint16", 
        "nmi_injected": "uint8", 


You see that they are not in same order, then I can't use the schema to
read an arbitrary savevm image.  I think that ordering should be
preserved, makes schema much, much more useful.


Once told that, I think that doing a big schema is just wrong, we should
do an schema for device (or at least for architecture).  And no
hardcoded names (as they are today).  It is just trivial to run it for
x86_64-softmmu/i386-softmmu (the things that should work nowadays).

That way, downstreams can use it for its own "minimal machines".


>> Whatever schema we have should be good enough to allow:
>> - describe me this blob that contains the state for this device.
>
> Schema for VMState is different than what's used for this test case
> here.  I agree, it's a harder problem than just what's being spit out
> here :-)

It should be the same IMHO, it will not complicate anything here, and
just make it more useful.

>> eepro100 at least is missing.  Althought I would vote to just change the
>> eepro100 "naming" to always use eepro100 or similar, and remove the
>> current hack of having to change the vmstate->name for each different
>> device.
>
> I just ran into eepro100 and my head nearly exploded.

Being there, know the feeling.

> I set the name to be eepro100-base and then just added that once.  A
> better solution would be to separate out the fields such that we can
> have a bunch of VMStateDescriptions that all use the same fields.
>
> I think we ought to merge VMStateDescription into DeviceInfo.  For
> compatibility, we probably need a vmstate_alias name since the device
> names don't always map 1-1 with the qdev names.  But this should
> eliminate the problem of reusing VMStateDescriptions for multiple
> devices.

Agreed with that.

Later, Juan.

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 15:26           ` Juan Quintela
@ 2011-03-23 16:14             ` Anthony Liguori
  2011-03-23 16:44               ` Juan Quintela
  0 siblings, 1 reply; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 16:14 UTC (permalink / raw)
  To: quintela; +Cc: Peter Maydell, qemu-devel, Jan Kiszka

On 03/23/2011 10:26 AM, Juan Quintela wrote:
> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> On 03/23/2011 09:17 AM, Juan Quintela wrote:
>>> Anthony Liguori<anthony@codemonkey.ws>   wrote:
>>> We need to fix the ordering problem.
>> Dunno what you mean by ordering.
> vmstate:
>
> static const VMStateDescription vmstate_cpu = {
>      .name = "cpu",
>      .version_id = CPU_SAVE_VERSION,
>      .minimum_version_id = 3,
>      .minimum_version_id_old = 3,
>      .pre_save = cpu_pre_save,
>      .post_load = cpu_post_load,
>      .fields      = (VMStateField []) {
>          VMSTATE_UINTTL_ARRAY(regs, CPUState, CPU_NB_REGS),
>          VMSTATE_UINTTL(eip, CPUState),
>          VMSTATE_UINTTL(eflags, CPUState),
>          VMSTATE_UINT32(hflags, CPUState),
>          /* FPU */
>
>
> vs
>
> dump
>
>      "cpu": {
>          "mcg_cap": "uint64",
>          "a20_mask": "int32",
>          "tsc_offset": "uint64",
>          "idt": {
>              "flags": "uint32",
>              "limit": "uint32",
>              "selector": "uint32",
>              "base": "uint32",
>              "__version__": 1
>          },
>          "intercept_cr_write": "uint16",
>          "nmi_injected": "uint8",
>
>
> You see that they are not in same order, then I can't use the schema to
> read an arbitrary savevm image.  I think that ordering should be
> preserved, makes schema much, much more useful.

This is *only* for testing right now.  We can enhance it down the road 
if we want to but this is an opaque thing that's only there to enable 
test cases to be written.

>
> Once told that, I think that doing a big schema is just wrong, we should
> do an schema for device (or at least for architecture).  And no
> hardcoded names (as they are today).  It is just trivial to run it for
> x86_64-softmmu/i386-softmmu (the things that should work nowadays).
>
> That way, downstreams can use it for its own "minimal machines".

I agree, we ought to try to make this schema more consumable.  But some 
of that is that the schema needs to describe types in a more meaningful 
way as there's a lot of weird types right now.

>>> Whatever schema we have should be good enough to allow:
>>> - describe me this blob that contains the state for this device.
>> Schema for VMState is different than what's used for this test case
>> here.  I agree, it's a harder problem than just what's being spit out
>> here :-)
> It should be the same IMHO, it will not complicate anything here, and
> just make it more useful.

Yeah, it will tremendously complicate things because QDict's don't 
preserve order.  It's all fixable but why wait to have something that's 
incredibly useful in tree?

>>> eepro100 at least is missing.  Althought I would vote to just change the
>>> eepro100 "naming" to always use eepro100 or similar, and remove the
>>> current hack of having to change the vmstate->name for each different
>>> device.
>> I just ran into eepro100 and my head nearly exploded.
> Being there, know the feeling.
>
>> I set the name to be eepro100-base and then just added that once.  A
>> better solution would be to separate out the fields such that we can
>> have a bunch of VMStateDescriptions that all use the same fields.
>>
>> I think we ought to merge VMStateDescription into DeviceInfo.  For
>> compatibility, we probably need a vmstate_alias name since the device
>> names don't always map 1-1 with the qdev names.  But this should
>> eliminate the problem of reusing VMStateDescriptions for multiple
>> devices.
> Agreed with that.

Once we settle on the unit tests, I can look at writing some scripts to 
do this.

Regards,

Anthony Liguori

> Later, Juan.

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 15:00           ` Peter Maydell
  2011-03-23 15:06             ` Jan Kiszka
@ 2011-03-23 16:27             ` Anthony Liguori
  2011-03-23 16:36               ` Jan Kiszka
  2011-03-23 16:45               ` Peter Maydell
  1 sibling, 2 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 16:27 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, qemu-devel, quintela

On 03/23/2011 10:00 AM, Peter Maydell wrote:
> On 23 March 2011 14:52, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> I think we ought to merge VMStateDescription into DeviceInfo.  For
>> compatibility, we probably need a vmstate_alias name since the device names
>> don't always map 1-1 with the qdev names.  But this should eliminate the
>> problem of reusing VMStateDescriptions for multiple devices.
> That's a feature, not a bug. Consider eg hw/pl110.c -- there
> are two different DeviceInfo devices but since the underlying
> implementation is the same you definitely don't want to have
> two separate VMStateDescription structures to get out of sync.

No, it's a bug.

Migration uses the VMStateDescription name as a section identifier.  The 
section identifiers MUST be unique for a given device.  Otherwise, if 
both devices are present, migration fails miserably.  It also means that 
if the wrong devices are created on the destination, instead of 
predictable failure, you get unpredictable guest corruption.

The Right Way to support what you're describing above is to have a 
single VMStateField array and two VMStateDescriptions.  IOW:

VMStateField pl110_fields[] = {
         VMSTATE_INT32(versatile, pl110_state),
         VMSTATE_UINT32_ARRAY(timing, pl110_state, 4),
         VMSTATE_UINT32(cr, pl110_state),
         VMSTATE_UINT32(upbase, pl110_state),
         VMSTATE_UINT32(lpbase, pl110_state),
         VMSTATE_UINT32(int_status, pl110_state),
         ....
};

VMStateDescription vmstate_pl110 = {
      .name = "pl110",
      ...
      .fields = pl110_fields,
};

VMStateDescription vmstate_pl110_versatile = {
      .name = "pl110-versatile",
      ...
      .fields = pl110_fields,
};

Merging VMStateDescription with DeviceInfo will force this on people 
making it difficult to make this mistake again.

Regards,

Anthony Liguori



> -- PMM
>

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 16:27             ` Anthony Liguori
@ 2011-03-23 16:36               ` Jan Kiszka
  2011-03-23 18:42                 ` Anthony Liguori
  2011-03-23 16:45               ` Peter Maydell
  1 sibling, 1 reply; 49+ messages in thread
From: Jan Kiszka @ 2011-03-23 16:36 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, qemu-devel@nongnu.org, quintela@redhat.com

On 2011-03-23 17:27, Anthony Liguori wrote:
> On 03/23/2011 10:00 AM, Peter Maydell wrote:
>> On 23 March 2011 14:52, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>>> I think we ought to merge VMStateDescription into DeviceInfo.  For
>>> compatibility, we probably need a vmstate_alias name since the device names
>>> don't always map 1-1 with the qdev names.  But this should eliminate the
>>> problem of reusing VMStateDescriptions for multiple devices.
>> That's a feature, not a bug. Consider eg hw/pl110.c -- there
>> are two different DeviceInfo devices but since the underlying
>> implementation is the same you definitely don't want to have
>> two separate VMStateDescription structures to get out of sync.
> 
> No, it's a bug.
> 
> Migration uses the VMStateDescription name as a section identifier.  The 
> section identifiers MUST be unique for a given device.  Otherwise, if 
> both devices are present, migration fails miserably.  It also means that 
> if the wrong devices are created on the destination, instead of 
> predictable failure, you get unpredictable guest corruption.

This is true for incompatible devices, but not for those that are
perfectly exchangeable (like in-kernel vs. user-space irqchip).

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux

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

* [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 16:14             ` Anthony Liguori
@ 2011-03-23 16:44               ` Juan Quintela
  0 siblings, 0 replies; 49+ messages in thread
From: Juan Quintela @ 2011-03-23 16:44 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, qemu-devel, Jan Kiszka

Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 03/23/2011 10:26 AM, Juan Quintela wrote:
>> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>>> On 03/23/2011 09:17 AM, Juan Quintela wrote:
>>>> Anthony Liguori<anthony@codemonkey.ws>   wrote:

>> Once told that, I think that doing a big schema is just wrong, we should
>> do an schema for device (or at least for architecture).  And no
>> hardcoded names (as they are today).  It is just trivial to run it for
>> x86_64-softmmu/i386-softmmu (the things that should work nowadays).
>>
>> That way, downstreams can use it for its own "minimal machines".
>
> I agree, we ought to try to make this schema more consumable.  But
> some of that is that the schema needs to describe types in a more
> meaningful way as there's a lot of weird types right now.

I have no clue about qdicts, but it is as easy as:
- add a new field that gives the "order", if this is not possible
- add a new qdict from order -> name

it is not rockets science.  I am looking at your patch right now, but my
experience with glib, q* and json is inexistant, so I go slowwwwww.

>>>> Whatever schema we have should be good enough to allow:
>>>> - describe me this blob that contains the state for this device.
>>> Schema for VMState is different than what's used for this test case
>>> here.  I agree, it's a harder problem than just what's being spit out
>>> here :-)
>> It should be the same IMHO, it will not complicate anything here, and
>> just make it more useful.
>
> Yeah, it will tremendously complicate things because QDict's don't
> preserve order.  It's all fixable but why wait to have something
> that's incredibly useful in tree?

see above.

>>>> eepro100 at least is missing.  Althought I would vote to just change the
>>>> eepro100 "naming" to always use eepro100 or similar, and remove the
>>>> current hack of having to change the vmstate->name for each different
>>>> device.
>>> I just ran into eepro100 and my head nearly exploded.
>> Being there, know the feeling.
>>
>>> I set the name to be eepro100-base and then just added that once.  A
>>> better solution would be to separate out the fields such that we can
>>> have a bunch of VMStateDescriptions that all use the same fields.
>>>
>>> I think we ought to merge VMStateDescription into DeviceInfo.  For
>>> compatibility, we probably need a vmstate_alias name since the device
>>> names don't always map 1-1 with the qdev names.  But this should
>>> eliminate the problem of reusing VMStateDescriptions for multiple
>>> devices.
>> Agreed with that.
>
> Once we settle on the unit tests, I can look at writing some scripts
> to do this.

I think that we need to improve the code that you sent, but I agree that
we can go by parts.

Later, Juan.

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 16:27             ` Anthony Liguori
  2011-03-23 16:36               ` Jan Kiszka
@ 2011-03-23 16:45               ` Peter Maydell
  2011-03-23 17:01                 ` Anthony Liguori
  1 sibling, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2011-03-23 16:45 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, qemu-devel, quintela

On 23 March 2011 16:27, Anthony Liguori <anthony@codemonkey.ws> wrote:
> Migration uses the VMStateDescription name as a section identifier.  The
> section identifiers MUST be unique for a given device.  Otherwise, if both
> devices are present, migration fails miserably.

So how does it work if you have two devices of the same type
in the system? I'd assumed that the unique identifier would
be one based on the actually instantiated devices.

> It also means that if the
> wrong devices are created on the destination, instead of predictable
> failure, you get unpredictable guest corruption.
>
> The Right Way to support what you're describing above is to have a single
> VMStateField array and two VMStateDescriptions.  IOW:

This doesn't make sense because it's decoupling the information
about minimum version ID etc (in the VMStateDescription) from
the information about which fields are in which version (which
is in the VMStateField array when it's initialised via
VMSTATE_*_V() macros). So although you get to avoid duplicating
all the fields in the arrangement you suggest you still end
up with version_id, minimum_version_id etc being duplicated
and needing to stay in sync.

-- PMM

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 16:45               ` Peter Maydell
@ 2011-03-23 17:01                 ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 17:01 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jan Kiszka, qemu-devel, quintela

On 03/23/2011 11:45 AM, Peter Maydell wrote:
> On 23 March 2011 16:27, Anthony Liguori<anthony@codemonkey.ws>  wrote:
>> Migration uses the VMStateDescription name as a section identifier.  The
>> section identifiers MUST be unique for a given device.  Otherwise, if both
>> devices are present, migration fails miserably.
> So how does it work if you have two devices of the same type
> in the system? I'd assumed that the unique identifier would
> be one based on the actually instantiated devices.

It's a combination of the section name + a device instance ID that has 
some magic behind making it unique and stable.  But instance ID is not 
unique on it's own.

>>   It also means that if the
>> wrong devices are created on the destination, instead of predictable
>> failure, you get unpredictable guest corruption.
>>
>> The Right Way to support what you're describing above is to have a single
>> VMStateField array and two VMStateDescriptions.  IOW:
> This doesn't make sense because it's decoupling the information
> about minimum version ID etc (in the VMStateDescription) from
> the information about which fields are in which version (which
> is in the VMStateField array when it's initialised via
> VMSTATE_*_V() macros). So although you get to avoid duplicating
> all the fields in the arrangement you suggest you still end
> up with version_id, minimum_version_id etc being duplicated
> and needing to stay in sync.

So maybe we just need to remove name from VMStateDescription and force 
it to come from DeviceInfo.

Regards,

Anthony Liguori

> -- PMM
>

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

* Re: [Qemu-devel] Re: [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState
  2011-03-23 16:36               ` Jan Kiszka
@ 2011-03-23 18:42                 ` Anthony Liguori
  0 siblings, 0 replies; 49+ messages in thread
From: Anthony Liguori @ 2011-03-23 18:42 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Peter Maydell, qemu-devel@nongnu.org, quintela@redhat.com

On 03/23/2011 11:36 AM, Jan Kiszka wrote:
>
> This is true for incompatible devices, but not for those that are
> perfectly exchangeable (like in-kernel vs. user-space irqchip).

I view this as the exception that proves the rule.

We should handle cases like this as very special cases.  I've found 
almost close to a dozen cases where we've got devices with conflicting 
names that aren't compatible and so far, none that truly are.

Regards,

Anthony Liguori

> Jan
>

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

end of thread, other threads:[~2011-03-23 18:43 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-23  0:16 [Qemu-devel] [PATCH 00/11] Add live migration unit tests Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 01/11] Add hard build dependency on glib Anthony Liguori
2011-03-23  8:13   ` Stefan Hajnoczi
2011-03-23  8:19     ` Roy Tam
2011-03-23  8:41       ` Stefan Hajnoczi
2011-03-23  8:58         ` Roy Tam
2011-03-23  9:19           ` [Qemu-devel] " Paolo Bonzini
2011-03-23  9:22           ` [Qemu-devel] " Stefan Hajnoczi
2011-03-23  0:16 ` [Qemu-devel] [PATCH 02/11] vmstate: register all VMStateDescriptions Anthony Liguori
2011-03-23  9:00   ` Alon Levy
2011-03-23 12:30   ` Peter Maydell
2011-03-23 12:37     ` Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 03/11] vmstate: for vmstate types that reuse the same field, make sure name is unique Anthony Liguori
2011-03-23  2:29   ` Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 04/11] sb16: fix migration quirk Anthony Liguori
2011-03-23  9:51   ` [Qemu-devel] " Juan Quintela
2011-03-23 12:16     ` Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 05/11] vga-isa: fix migration by breaking it Anthony Liguori
2011-03-23  9:54   ` [Qemu-devel] " Juan Quintela
2011-03-23  0:16 ` [Qemu-devel] [PATCH 06/11] fdc: fix migration of non-ISA fdc devices Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 07/11] eeprom93xx: Use the new hack macro to avoid duplicate field names Anthony Liguori
2011-03-23  9:58   ` [Qemu-devel] " Juan Quintela
2011-03-23 12:34     ` Anthony Liguori
2011-03-23 14:14       ` Juan Quintela
2011-03-23 14:33         ` Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 08/11] fw_cfg: make sure all VMState fields are unique Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 09/11] pckbd: make non-ISA pckbd use a unique name Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 10/11] vl: add a new -vmstate-dump option to write a VMState JSON schema Anthony Liguori
2011-03-23  0:16 ` [Qemu-devel] [PATCH 11/11] test-vmstate: add test case to verify we don't change VMState Anthony Liguori
2011-03-23  2:31   ` Anthony Liguori
2011-03-23  8:37   ` Stefan Hajnoczi
2011-03-23 10:22   ` Peter Maydell
2011-03-23 12:42     ` Anthony Liguori
2011-03-23 14:17       ` [Qemu-devel] " Juan Quintela
2011-03-23 14:52         ` Anthony Liguori
2011-03-23 15:00           ` Peter Maydell
2011-03-23 15:06             ` Jan Kiszka
2011-03-23 16:27             ` Anthony Liguori
2011-03-23 16:36               ` Jan Kiszka
2011-03-23 18:42                 ` Anthony Liguori
2011-03-23 16:45               ` Peter Maydell
2011-03-23 17:01                 ` Anthony Liguori
2011-03-23 15:26           ` Juan Quintela
2011-03-23 16:14             ` Anthony Liguori
2011-03-23 16:44               ` Juan Quintela
2011-03-23 14:19     ` Juan Quintela
2011-03-23 14:36       ` Peter Maydell
2011-03-23 15:13         ` Juan Quintela
2011-03-23 15:24           ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).