From 54c6de864fb6286ce8e9035f10f3193d2caf0897 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 18 Dec 2015 10:06:14 +0100 Subject: [PATCH 01/16] hw/ppc/spapr_rtc: Remove bad class_size value class_size = sizeof(XICSStateClass) does not make much sense in the RTC code and likely was just a copy-n-paste error. Let's simply remove it. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/spapr_rtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index 34b27db709..b591a8ee23 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -200,7 +200,6 @@ static const TypeInfo spapr_rtc_info = { .name = TYPE_SPAPR_RTC, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(sPAPRRTCState), - .class_size = sizeof(XICSStateClass), .class_init = spapr_rtc_class_init, }; From 7d94a30b549281d4d780fb9a5cca3dae378329d4 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Fri, 13 Nov 2015 18:13:07 -0800 Subject: [PATCH 02/16] target-ppc: Define kvmppc_read_int_dt() Extract code from the function kvmppc_read_int_cpu_dt() that actually reads the file into a separate function, so it can be called from other places. Signed-off-by: Sukadev Bhattiprolu Signed-off-by: David Gibson --- target-ppc/kvm.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index ac70f0897b..9940a90462 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1838,13 +1838,8 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len) return 0; } -/* Read a CPU node property from the host device tree that's a single - * integer (32-bit or 64-bit). Returns 0 if anything goes wrong - * (can't find or open the property, or doesn't understand the - * format) */ -static uint64_t kvmppc_read_int_cpu_dt(const char *propname) +static uint64_t kvmppc_read_int_dt(const char *filename) { - char buf[PATH_MAX], *tmp; union { uint32_t v32; uint64_t v64; @@ -1852,14 +1847,7 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname) FILE *f; int len; - if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { - return -1; - } - - tmp = g_strdup_printf("%s/%s", buf, propname); - - f = fopen(tmp, "rb"); - g_free(tmp); + f = fopen(filename, "rb"); if (!f) { return -1; } @@ -1877,6 +1865,26 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname) return 0; } +/* Read a CPU node property from the host device tree that's a single + * integer (32-bit or 64-bit). Returns 0 if anything goes wrong + * (can't find or open the property, or doesn't understand the + * format) */ +static uint64_t kvmppc_read_int_cpu_dt(const char *propname) +{ + char buf[PATH_MAX], *tmp; + uint64_t val; + + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { + return -1; + } + + tmp = g_strdup_printf("%s/%s", buf, propname); + val = kvmppc_read_int_dt(tmp); + g_free(tmp); + + return val; +} + uint64_t kvmppc_get_clockfreq(void) { return kvmppc_read_int_cpu_dt("clock-frequency"); From 3dc0a66d26bfc3820ab46aaf245cabf26fcf1eb4 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Mon, 9 Nov 2015 17:47:17 +1100 Subject: [PATCH 03/16] spapr: Add /system-id Section B.6.2.1 Root Node Properties of PAPR specification defines a set of properties which shall be present in the device tree root, one of these properties is "system-id" which "should be unique across all systems and all manufacturers". Since UUID is meant to be unique, it makes sense to use it as "system-id". This adds "system-id" property to the device tree root when not empty. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/ppc/spapr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6bfb908da7..29a16b7451 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -375,6 +375,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, qemu_uuid[14], qemu_uuid[15]); _FDT((fdt_property_string(fdt, "vm,uuid", buf))); + if (qemu_uuid_set) { + _FDT((fdt_property_string(fdt, "system-id", buf))); + } g_free(buf); if (qemu_get_vm_name()) { From aec39c5349acc4b33711288abbbaf747e21b04b7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 30 Nov 2015 16:36:49 +1100 Subject: [PATCH 04/16] pseries: Remove redundant setting of mc->name for pseries-2.5 machine 98cec76 "machine: Set MachineClass::name automatically" removed the setting of mc->name for the pseries machine types, since it can be derived automatically from the type names constructed with MACHINE_TYPE_NAME(). Unfortunately fb0fc8f "spapr: Create pseries-2.5 machine" went in later and brought one of them back. This removes it again. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 29a16b7451..a69856f55a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2440,7 +2440,6 @@ static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); - mc->name = "pseries-2.5"; mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; mc->alias = "pseries"; mc->is_default = 1; From 1c5f29bbc8dac5f5d109a4aaa761e0dbb9eeea8d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 3 Dec 2015 17:34:10 +1100 Subject: [PATCH 05/16] pseries: Rearrange versioned machine type code hw/ppc/spapr.c has a number of definitions related to the various versioned machine types ("pseries-2.1" .. "pseries-2.5") it defines. These are mostly arranged by type of function first, then machine version second, and it's not consistent about whether it goes in increasing or decreasing version order. This rearranges the code to keep all the definitions for a particular machine version together, and arrange then consistently in order most recent to least recent. This brings us closer to matching the way PC does things, and makes later cleanups easier to follow. Apart from adding some comments marking each section, this is a pure mechanical rearrangement with no semantic changes. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 204 ++++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 94 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a69856f55a..c126e10fa4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2301,9 +2301,53 @@ static const TypeInfo spapr_machine_info = { }, }; +/* + * pseries-2.5 + */ +static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); + + mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; + mc->alias = "pseries"; + mc->is_default = 1; + smc->dr_lmb_enabled = true; +} + +static const TypeInfo spapr_machine_2_5_info = { + .name = MACHINE_TYPE_NAME("pseries-2.5"), + .parent = TYPE_SPAPR_MACHINE, + .class_init = spapr_machine_2_5_class_init, +}; + +/* + * pseries-2.4 + */ #define SPAPR_COMPAT_2_4 \ HW_COMPAT_2_4 +static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) +{ + static GlobalProperty compat_props[] = { + SPAPR_COMPAT_2_4 + { /* end of list */ } + }; + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4"; + mc->compat_props = compat_props; +} + +static const TypeInfo spapr_machine_2_4_info = { + .name = MACHINE_TYPE_NAME("pseries-2.4"), + .parent = TYPE_SPAPR_MACHINE, + .class_init = spapr_machine_2_4_class_init, +}; + +/* + * pseries-2.3 + */ #define SPAPR_COMPAT_2_3 \ SPAPR_COMPAT_2_4 \ HW_COMPAT_2_3 \ @@ -2313,6 +2357,41 @@ static const TypeInfo spapr_machine_info = { .value = "off",\ }, +static void spapr_compat_2_3(Object *obj) +{ + savevm_skip_section_footers(); + global_state_set_optional(); +} + +static void spapr_machine_2_3_instance_init(Object *obj) +{ + spapr_compat_2_3(obj); + spapr_machine_initfn(obj); +} + +static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) +{ + static GlobalProperty compat_props[] = { + SPAPR_COMPAT_2_3 + { /* end of list */ } + }; + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3"; + mc->compat_props = compat_props; +} + +static const TypeInfo spapr_machine_2_3_info = { + .name = MACHINE_TYPE_NAME("pseries-2.3"), + .parent = TYPE_SPAPR_MACHINE, + .class_init = spapr_machine_2_3_class_init, + .instance_init = spapr_machine_2_3_instance_init, +}; + +/* + * pseries-2.2 + */ + #define SPAPR_COMPAT_2_2 \ SPAPR_COMPAT_2_3 \ HW_COMPAT_2_2 \ @@ -2322,38 +2401,48 @@ static const TypeInfo spapr_machine_info = { .value = "0x20000000",\ }, -#define SPAPR_COMPAT_2_1 \ - SPAPR_COMPAT_2_2 \ - HW_COMPAT_2_1 - -static void spapr_compat_2_3(Object *obj) -{ - savevm_skip_section_footers(); - global_state_set_optional(); -} - static void spapr_compat_2_2(Object *obj) { spapr_compat_2_3(obj); } -static void spapr_compat_2_1(Object *obj) -{ - spapr_compat_2_2(obj); -} - -static void spapr_machine_2_3_instance_init(Object *obj) -{ - spapr_compat_2_3(obj); - spapr_machine_initfn(obj); -} - static void spapr_machine_2_2_instance_init(Object *obj) { spapr_compat_2_2(obj); spapr_machine_initfn(obj); } +static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) +{ + static GlobalProperty compat_props[] = { + SPAPR_COMPAT_2_2 + { /* end of list */ } + }; + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2"; + mc->compat_props = compat_props; +} + +static const TypeInfo spapr_machine_2_2_info = { + .name = MACHINE_TYPE_NAME("pseries-2.2"), + .parent = TYPE_SPAPR_MACHINE, + .class_init = spapr_machine_2_2_class_init, + .instance_init = spapr_machine_2_2_instance_init, +}; + +/* + * pseries-2.1 + */ +#define SPAPR_COMPAT_2_1 \ + SPAPR_COMPAT_2_2 \ + HW_COMPAT_2_1 + +static void spapr_compat_2_1(Object *obj) +{ + spapr_compat_2_2(obj); +} + static void spapr_machine_2_1_instance_init(Object *obj) { spapr_compat_2_1(obj); @@ -2379,79 +2468,6 @@ static const TypeInfo spapr_machine_2_1_info = { .instance_init = spapr_machine_2_1_instance_init, }; -static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) -{ - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_2 - { /* end of list */ } - }; - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2"; - mc->compat_props = compat_props; -} - -static const TypeInfo spapr_machine_2_2_info = { - .name = MACHINE_TYPE_NAME("pseries-2.2"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_2_class_init, - .instance_init = spapr_machine_2_2_instance_init, -}; - -static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) -{ - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_3 - { /* end of list */ } - }; - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3"; - mc->compat_props = compat_props; -} - -static const TypeInfo spapr_machine_2_3_info = { - .name = MACHINE_TYPE_NAME("pseries-2.3"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_3_class_init, - .instance_init = spapr_machine_2_3_instance_init, -}; - -static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) -{ - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_4 - { /* end of list */ } - }; - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4"; - mc->compat_props = compat_props; -} - -static const TypeInfo spapr_machine_2_4_info = { - .name = MACHINE_TYPE_NAME("pseries-2.4"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_4_class_init, -}; - -static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); - - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; - mc->alias = "pseries"; - mc->is_default = 1; - smc->dr_lmb_enabled = true; -} - -static const TypeInfo spapr_machine_2_5_info = { - .name = MACHINE_TYPE_NAME("pseries-2.5"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_5_class_init, -}; - static void spapr_machine_register_types(void) { type_register_static(&spapr_machine_info); From 64f0f70a00ec62f10a1fd333a3a3a6bf513fc1a0 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 3 Dec 2015 17:34:20 +1100 Subject: [PATCH 06/16] pseries: Remove redundant calls to spapr_machine_initfn() The instance_init() functions for several of the pseries-x.y versioned machine types explicitly call spapr_machine_initfn(). But that's the instance_init function for the common parent of all those machine types, so will already have been called beforehand by the QOM infrastructure. Remove the redundant calls. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c126e10fa4..c7c65179c6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2366,7 +2366,6 @@ static void spapr_compat_2_3(Object *obj) static void spapr_machine_2_3_instance_init(Object *obj) { spapr_compat_2_3(obj); - spapr_machine_initfn(obj); } static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) @@ -2409,7 +2408,6 @@ static void spapr_compat_2_2(Object *obj) static void spapr_machine_2_2_instance_init(Object *obj) { spapr_compat_2_2(obj); - spapr_machine_initfn(obj); } static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) @@ -2446,7 +2444,6 @@ static void spapr_compat_2_1(Object *obj) static void spapr_machine_2_1_instance_init(Object *obj) { spapr_compat_2_1(obj); - spapr_machine_initfn(obj); } static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) From 0eb9054c6040f7216be99c23793f001d52765ce9 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 7 Dec 2015 14:29:35 +1100 Subject: [PATCH 07/16] pseries: Remove versions from mc->desc Currently, the versioned spapr machine types put the machine type version into the description string. PC does not do this, using just the name itself to distinguish. Doing the same lets us move setting the description into the common base class, simplifying the code slightly. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c7c65179c6..b08d338954 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2265,6 +2265,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) NMIClass *nc = NMI_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); + mc->desc = "pSeries Logical Partition (PAPR compliant)"; mc->init = ppc_spapr_init; mc->reset = ppc_spapr_reset; mc->block_default_type = IF_SCSI; @@ -2309,7 +2310,6 @@ static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.5"; mc->alias = "pseries"; mc->is_default = 1; smc->dr_lmb_enabled = true; @@ -2335,7 +2335,6 @@ static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) }; MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.4"; mc->compat_props = compat_props; } @@ -2376,7 +2375,6 @@ static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) }; MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3"; mc->compat_props = compat_props; } @@ -2418,7 +2416,6 @@ static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) }; MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2"; mc->compat_props = compat_props; } @@ -2454,7 +2451,6 @@ static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { /* end of list */ } }; - mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1"; mc->compat_props = compat_props; } From 877f8931b99e2377a180fd43a1e5fc2b707e9c52 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 3 Dec 2015 17:34:38 +1100 Subject: [PATCH 08/16] Move SET_MACHINE_COMPAT macro to boards.h pc.h defines a SET_MACHINE_COMPAT macro to make setting up compat_props for the various PC machine versions less verbose. There's nothing inherently PC specific about it, though, so move it to boards.h where other versioned machine types (like pseries-*) can use it. While we're doing that, change it's indentation to be a bit more regular. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Eduardo Habkost Reviewed-by: Alexey Kardashevskiy --- include/hw/boards.h | 9 +++++++++ include/hw/i386/pc.h | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/hw/boards.h b/include/hw/boards.h index 051db5ed25..0f30959e2e 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -157,4 +157,13 @@ struct MachineState { } \ machine_init(machine_initfn##_register_types) +#define SET_MACHINE_COMPAT(m, COMPAT) \ + do { \ + static GlobalProperty props[] = { \ + COMPAT \ + { /* end of list */ } \ + }; \ + (m)->compat_props = props; \ + } while (0) + #endif diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index b0d6283b25..2e0d05ec07 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -855,13 +855,5 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); } \ machine_init(pc_machine_init_##suffix) -#define SET_MACHINE_COMPAT(m, COMPAT) do { \ - static GlobalProperty props[] = { \ - COMPAT \ - { /* end of list */ } \ - }; \ - (m)->compat_props = props; \ -} while (0) - extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id); #endif From f949b4e5f5f8ce51d89d22567741c27fdcb0c106 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 3 Dec 2015 17:47:22 +1100 Subject: [PATCH 09/16] pseries: Use SET_MACHINE_COMPAT To make the spapr_machine_*_class_init() functions a little less bulky. Signed-off-by: David Gibson Reviewed-by: Thomas Huth Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b08d338954..3078e6063c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2329,13 +2329,9 @@ static const TypeInfo spapr_machine_2_5_info = { static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) { - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_4 - { /* end of list */ } - }; MachineClass *mc = MACHINE_CLASS(oc); - mc->compat_props = compat_props; + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4); } static const TypeInfo spapr_machine_2_4_info = { @@ -2369,13 +2365,9 @@ static void spapr_machine_2_3_instance_init(Object *obj) static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) { - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_3 - { /* end of list */ } - }; MachineClass *mc = MACHINE_CLASS(oc); - mc->compat_props = compat_props; + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3); } static const TypeInfo spapr_machine_2_3_info = { @@ -2410,13 +2402,9 @@ static void spapr_machine_2_2_instance_init(Object *obj) static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) { - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_2 - { /* end of list */ } - }; MachineClass *mc = MACHINE_CLASS(oc); - mc->compat_props = compat_props; + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2); } static const TypeInfo spapr_machine_2_2_info = { @@ -2446,12 +2434,8 @@ static void spapr_machine_2_1_instance_init(Object *obj) static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - static GlobalProperty compat_props[] = { - SPAPR_COMPAT_2_1 - { /* end of list */ } - }; - mc->compat_props = compat_props; + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); } static const TypeInfo spapr_machine_2_1_info = { From 5013c5474658c1adea6d5448979dfe399b27e194 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 7 Dec 2015 14:23:20 +1100 Subject: [PATCH 10/16] pseries: DEFINE_SPAPR_MACHINE At the moment all the class_init functions and TypeInfo structures for the various versioned pseries machine types are open-coded. As more versions are created this is getting increasingly clumsy. This patch borrows the approach used in PC, using a DEFINE_SPAPR_MACHINE() macro to construct most of the boilerplate from simpler 'class_options' and 'instance_options' functions. This patch makes a small semantic change - the versioned machine types are now registered through machine_init() instead of type_init(). Since the new way is how PC already did it, I'm assuming that's correct. Signed-off-by: David Gibson Reviewed-by: Sam Bobroff Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 119 ++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 70 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3078e6063c..4f645f3ca6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2302,24 +2302,47 @@ static const TypeInfo spapr_machine_info = { }, }; +#define DEFINE_SPAPR_MACHINE(suffix, verstr) \ + static void spapr_machine_##suffix##_class_init(ObjectClass *oc, \ + void *data) \ + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + spapr_machine_##suffix##_class_options(mc); \ + } \ + static void spapr_machine_##suffix##_instance_init(Object *obj) \ + { \ + MachineState *machine = MACHINE(obj); \ + spapr_machine_##suffix##_instance_options(machine); \ + } \ + static const TypeInfo spapr_machine_##suffix##_info = { \ + .name = MACHINE_TYPE_NAME("pseries-" verstr), \ + .parent = TYPE_SPAPR_MACHINE, \ + .class_init = spapr_machine_##suffix##_class_init, \ + .instance_init = spapr_machine_##suffix##_instance_init, \ + }; \ + static void spapr_machine_register_##suffix(void) \ + { \ + type_register(&spapr_machine_##suffix##_info); \ + } \ + machine_init(spapr_machine_register_##suffix) + /* * pseries-2.5 */ -static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data) +static void spapr_machine_2_5_instance_options(MachineState *machine) { - MachineClass *mc = MACHINE_CLASS(oc); - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc); +} + +static void spapr_machine_2_5_class_options(MachineClass *mc) +{ + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); mc->alias = "pseries"; mc->is_default = 1; smc->dr_lmb_enabled = true; } -static const TypeInfo spapr_machine_2_5_info = { - .name = MACHINE_TYPE_NAME("pseries-2.5"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_5_class_init, -}; +DEFINE_SPAPR_MACHINE(2_5, "2.5"); /* * pseries-2.4 @@ -2327,18 +2350,17 @@ static const TypeInfo spapr_machine_2_5_info = { #define SPAPR_COMPAT_2_4 \ HW_COMPAT_2_4 -static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data) +static void spapr_machine_2_4_instance_options(MachineState *machine) { - MachineClass *mc = MACHINE_CLASS(oc); + spapr_machine_2_5_instance_options(machine); +} +static void spapr_machine_2_4_class_options(MachineClass *mc) +{ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4); } -static const TypeInfo spapr_machine_2_4_info = { - .name = MACHINE_TYPE_NAME("pseries-2.4"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_4_class_init, -}; +DEFINE_SPAPR_MACHINE(2_4, "2.4"); /* * pseries-2.3 @@ -2352,30 +2374,18 @@ static const TypeInfo spapr_machine_2_4_info = { .value = "off",\ }, -static void spapr_compat_2_3(Object *obj) +static void spapr_machine_2_3_instance_options(MachineState *machine) { + spapr_machine_2_4_instance_options(machine); savevm_skip_section_footers(); global_state_set_optional(); } -static void spapr_machine_2_3_instance_init(Object *obj) +static void spapr_machine_2_3_class_options(MachineClass *mc) { - spapr_compat_2_3(obj); -} - -static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3); } - -static const TypeInfo spapr_machine_2_3_info = { - .name = MACHINE_TYPE_NAME("pseries-2.3"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_3_class_init, - .instance_init = spapr_machine_2_3_instance_init, -}; +DEFINE_SPAPR_MACHINE(2_3, "2.3"); /* * pseries-2.2 @@ -2390,29 +2400,16 @@ static const TypeInfo spapr_machine_2_3_info = { .value = "0x20000000",\ }, -static void spapr_compat_2_2(Object *obj) +static void spapr_machine_2_2_instance_options(MachineState *machine) { - spapr_compat_2_3(obj); + spapr_machine_2_3_instance_options(machine); } -static void spapr_machine_2_2_instance_init(Object *obj) +static void spapr_machine_2_2_class_options(MachineClass *mc) { - spapr_compat_2_2(obj); -} - -static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2); } - -static const TypeInfo spapr_machine_2_2_info = { - .name = MACHINE_TYPE_NAME("pseries-2.2"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_2_class_init, - .instance_init = spapr_machine_2_2_instance_init, -}; +DEFINE_SPAPR_MACHINE(2_2, "2.2"); /* * pseries-2.1 @@ -2421,38 +2418,20 @@ static const TypeInfo spapr_machine_2_2_info = { SPAPR_COMPAT_2_2 \ HW_COMPAT_2_1 -static void spapr_compat_2_1(Object *obj) +static void spapr_machine_2_1_instance_options(MachineState *machine) { - spapr_compat_2_2(obj); + spapr_machine_2_2_instance_options(machine); } -static void spapr_machine_2_1_instance_init(Object *obj) +static void spapr_machine_2_1_class_options(MachineClass *mc) { - spapr_compat_2_1(obj); -} - -static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); } - -static const TypeInfo spapr_machine_2_1_info = { - .name = MACHINE_TYPE_NAME("pseries-2.1"), - .parent = TYPE_SPAPR_MACHINE, - .class_init = spapr_machine_2_1_class_init, - .instance_init = spapr_machine_2_1_instance_init, -}; +DEFINE_SPAPR_MACHINE(2_1, "2.1"); static void spapr_machine_register_types(void) { type_register_static(&spapr_machine_info); - type_register_static(&spapr_machine_2_1_info); - type_register_static(&spapr_machine_2_2_info); - type_register_static(&spapr_machine_2_3_info); - type_register_static(&spapr_machine_2_4_info); - type_register_static(&spapr_machine_2_5_info); } type_init(spapr_machine_register_types) From fc9f38c3c0f42b7e98957b646976ee5b63f23806 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 7 Dec 2015 14:27:21 +1100 Subject: [PATCH 11/16] pseries: Restructure class_options functions Currently each of the *_class_options() functions for the pseries-2.1 .. pseries-2.5 machine types are standalone. This will become harder to maintain as new versions are added. This patch restructures them similarly to x86 where each function calls the one from the next version, then overrides anything necessary for compatibility with the specific version and older. The default behaviour - that for the most recent machine are set up in the base class initializer spapr_machine_class_init(). Previously it had some things set up to default to older behaviour with the more recent machines overriding it. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4f645f3ca6..5af3d132ed 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2266,6 +2266,12 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); mc->desc = "pSeries Logical Partition (PAPR compliant)"; + + /* + * We set up the default / latest behaviour here. The class_init + * functions for the specific versioned machine types can override + * these details for backwards compatibility + */ mc->init = ppc_spapr_init; mc->reset = ppc_spapr_reset; mc->block_default_type = IF_SCSI; @@ -2281,7 +2287,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) hc->unplug = spapr_machine_device_unplug; mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id; - smc->dr_lmb_enabled = false; + smc->dr_lmb_enabled = true; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; } @@ -2335,11 +2341,9 @@ static void spapr_machine_2_5_instance_options(MachineState *machine) static void spapr_machine_2_5_class_options(MachineClass *mc) { - sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); - + /* Defaults for the latest behaviour inherited from the base class */ mc->alias = "pseries"; mc->is_default = 1; - smc->dr_lmb_enabled = true; } DEFINE_SPAPR_MACHINE(2_5, "2.5"); @@ -2357,6 +2361,12 @@ static void spapr_machine_2_4_instance_options(MachineState *machine) static void spapr_machine_2_4_class_options(MachineClass *mc) { + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + + spapr_machine_2_5_class_options(mc); + mc->alias = NULL; + mc->is_default = 0; + smc->dr_lmb_enabled = false; SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4); } @@ -2383,6 +2393,7 @@ static void spapr_machine_2_3_instance_options(MachineState *machine) static void spapr_machine_2_3_class_options(MachineClass *mc) { + spapr_machine_2_4_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3); } DEFINE_SPAPR_MACHINE(2_3, "2.3"); @@ -2407,6 +2418,7 @@ static void spapr_machine_2_2_instance_options(MachineState *machine) static void spapr_machine_2_2_class_options(MachineClass *mc) { + spapr_machine_2_3_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2); } DEFINE_SPAPR_MACHINE(2_2, "2.2"); @@ -2425,6 +2437,7 @@ static void spapr_machine_2_1_instance_options(MachineState *machine) static void spapr_machine_2_1_class_options(MachineClass *mc) { + spapr_machine_2_2_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); } DEFINE_SPAPR_MACHINE(2_1, "2.1"); From fccbc785003f4575a3f22a4d230f9aaa1327788e Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 7 Dec 2015 14:25:50 +1100 Subject: [PATCH 12/16] pseries: Improve setting of default machine version This tweaks the way the default machine version is controlled, so that there will be a bit less churn when each new version is introduced. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5af3d132ed..8b8eb188b7 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2308,12 +2308,16 @@ static const TypeInfo spapr_machine_info = { }, }; -#define DEFINE_SPAPR_MACHINE(suffix, verstr) \ +#define DEFINE_SPAPR_MACHINE(suffix, verstr, latest) \ static void spapr_machine_##suffix##_class_init(ObjectClass *oc, \ void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ spapr_machine_##suffix##_class_options(mc); \ + if (latest) { \ + mc->alias = "pseries"; \ + mc->is_default = 1; \ + } \ } \ static void spapr_machine_##suffix##_instance_init(Object *obj) \ { \ @@ -2342,11 +2346,9 @@ static void spapr_machine_2_5_instance_options(MachineState *machine) static void spapr_machine_2_5_class_options(MachineClass *mc) { /* Defaults for the latest behaviour inherited from the base class */ - mc->alias = "pseries"; - mc->is_default = 1; } -DEFINE_SPAPR_MACHINE(2_5, "2.5"); +DEFINE_SPAPR_MACHINE(2_5, "2.5", true); /* * pseries-2.4 @@ -2364,13 +2366,11 @@ static void spapr_machine_2_4_class_options(MachineClass *mc) sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); spapr_machine_2_5_class_options(mc); - mc->alias = NULL; - mc->is_default = 0; smc->dr_lmb_enabled = false; SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4); } -DEFINE_SPAPR_MACHINE(2_4, "2.4"); +DEFINE_SPAPR_MACHINE(2_4, "2.4", false); /* * pseries-2.3 @@ -2396,7 +2396,7 @@ static void spapr_machine_2_3_class_options(MachineClass *mc) spapr_machine_2_4_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3); } -DEFINE_SPAPR_MACHINE(2_3, "2.3"); +DEFINE_SPAPR_MACHINE(2_3, "2.3", false); /* * pseries-2.2 @@ -2421,7 +2421,7 @@ static void spapr_machine_2_2_class_options(MachineClass *mc) spapr_machine_2_3_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2); } -DEFINE_SPAPR_MACHINE(2_2, "2.2"); +DEFINE_SPAPR_MACHINE(2_2, "2.2", false); /* * pseries-2.1 @@ -2440,7 +2440,7 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) spapr_machine_2_2_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); } -DEFINE_SPAPR_MACHINE(2_1, "2.1"); +DEFINE_SPAPR_MACHINE(2_1, "2.1", false); static void spapr_machine_register_types(void) { From 4b23699c828d19360d6ca5b74036573decb62194 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 7 Dec 2015 14:28:15 +1100 Subject: [PATCH 13/16] pseries: Add pseries-2.6 machine type Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- hw/ppc/spapr.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 8b8eb188b7..7f6b118bfb 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2336,19 +2336,37 @@ static const TypeInfo spapr_machine_info = { } \ machine_init(spapr_machine_register_##suffix) +/* + * pseries-2.6 + */ +static void spapr_machine_2_6_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_6_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(2_6, "2.6", true); + /* * pseries-2.5 */ +#define SPAPR_COMPAT_2_5 \ + HW_COMPAT_2_5 + static void spapr_machine_2_5_instance_options(MachineState *machine) { } static void spapr_machine_2_5_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_2_6_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_5); } -DEFINE_SPAPR_MACHINE(2_5, "2.5", true); +DEFINE_SPAPR_MACHINE(2_5, "2.5", false); /* * pseries-2.4 From 57040d451315320b7d27cf543a03a883913d45fb Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 9 Dec 2015 13:34:13 +0100 Subject: [PATCH 14/16] hw/ppc/spapr: Use XHCI as host controller for new spapr machines The OHCI has some bugs and performance issues, so for newer machines it's preferable to use XHCI instead. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- hw/ppc/spapr.c | 9 ++++++++- include/hw/ppc/spapr.h | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 7f6b118bfb..580b75da9c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1917,7 +1917,11 @@ static void ppc_spapr_init(MachineState *machine) } if (machine->usb) { - pci_create_simple(phb->bus, -1, "pci-ohci"); + if (smc->use_ohci_by_default) { + pci_create_simple(phb->bus, -1, "pci-ohci"); + } else { + pci_create_simple(phb->bus, -1, "nec-usb-xhci"); + } if (spapr->has_graphics) { USBBus *usb_bus = usb_bus_find(-1); @@ -2362,7 +2366,10 @@ static void spapr_machine_2_5_instance_options(MachineState *machine) static void spapr_machine_2_5_class_options(MachineClass *mc) { + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + spapr_machine_2_6_class_options(mc); + smc->use_ohci_by_default = true; SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_5); } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 5baa90683b..53af76a93c 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -35,7 +35,8 @@ struct sPAPRMachineClass { MachineClass parent_class; /*< public >*/ - bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ + bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ + bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ }; /** From 215e209846d37a2e4b3e2de1f901e808837480dd Mon Sep 17 00:00:00 2001 From: Cao jin Date: Wed, 23 Dec 2015 19:30:12 +0800 Subject: [PATCH 15/16] spapr vio: fix to incomplete QOMify Signed-off-by: Cao jin Signed-off-by: David Gibson --- hw/ppc/spapr_vio.c | 12 +++++------- include/hw/ppc/spapr_vio.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index c51eb8e244..46f3b8d3ef 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -388,7 +388,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr, static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev) { - VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); + VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus); BusChild *kid; VIOsPAPRDevice *other; @@ -449,7 +449,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) } } else { /* Need to assign an address */ - VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); + VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus); do { dev->reg = bus->next_reg++; @@ -523,13 +523,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void) DeviceState *dev; /* Create bridge device */ - dev = qdev_create(NULL, "spapr-vio-bridge"); + dev = qdev_create(NULL, TYPE_SPAPR_VIO_BRIDGE); qdev_init_nofail(dev); /* Create bus on bridge device */ - qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio"); - bus = DO_UPCAST(VIOsPAPRBus, bus, qbus); + bus = SPAPR_VIO_BUS(qbus); bus->next_reg = 0x71000000; /* hcall-vio */ @@ -567,9 +566,8 @@ static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) } static const TypeInfo spapr_vio_bridge_info = { - .name = "spapr-vio-bridge", + .name = TYPE_SPAPR_VIO_BRIDGE, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SysBusDevice), .class_init = spapr_vio_bridge_class_init, }; diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 2299a5405a..c9733e7552 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -34,7 +34,7 @@ #define TYPE_SPAPR_VIO_BUS "spapr-vio-bus" #define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS) -struct VIOsPAPRDevice; +#define TYPE_SPAPR_VIO_BRIDGE "spapr-vio-bridge" typedef struct VIOsPAPR_CRQ { uint64_t qladdr; From 87bbdd9cafe58ce50d462307394d51af98d50d74 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 28 Dec 2015 17:38:26 +1100 Subject: [PATCH 16/16] hw/ppc/spapr: fix spapr->kvm_type leak Cc: David Gibson Cc: Alexander Graf Cc: qemu-ppc@nongnu.org Signed-off-by: Li Zhijian [fixed return type of spapr_machine_finalizefn()] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 580b75da9c..414e0f9b7a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2108,6 +2108,13 @@ static void spapr_machine_initfn(Object *obj) NULL); } +static void spapr_machine_finalizefn(Object *obj) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + g_free(spapr->kvm_type); +} + static void ppc_cpu_do_nmi_on_cpu(void *arg) { CPUState *cs = arg; @@ -2302,6 +2309,7 @@ static const TypeInfo spapr_machine_info = { .abstract = true, .instance_size = sizeof(sPAPRMachineState), .instance_init = spapr_machine_initfn, + .instance_finalize = spapr_machine_finalizefn, .class_size = sizeof(sPAPRMachineClass), .class_init = spapr_machine_class_init, .interfaces = (InterfaceInfo[]) {