Define vmstate_register_init to statically declare that a vmstate object should be registered during qemu initialization, specifically, in the call to vmstate_register_init_all. This is needed to register objects that are not Objects (and hence cannot use the DeviceClass vmsd hook), without requiring that qemu call an object-specific initialization function.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/migration/vmstate.h | 18 ++++++++++++++++++ migration/savevm.c | 32 ++++++++++++++++++++++++++++++++ system/vl.c | 3 +++ 3 files changed, 53 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 3d71b34..8cb3d2b 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -1255,6 +1255,24 @@ static inline int vmstate_register(VMStateIf *obj, int instance_id, } /** + * vmstate_register_init() - statically declare a VMSD to be registered when + * QEMU calls vmstate_register_init_all. This is useful for registering + * objects that are not Objects (and hence cannot use the DeviceClass vmsd + * hook). + */ +#define vmstate_register_init(_obj, _id, _vmsd, _opaque) \ +static void __attribute__((constructor)) vmstate_register_ ## _vmsd(void) \ +{ \ + vmstate_register_init_add(_obj, _id, &_vmsd, _opaque); \ +} + +void vmstate_register_init_add(VMStateIf *obj, int instance_id, + const VMStateDescription *vmsd, void *opaque); + +void vmstate_register_init_all(void); + + +/** * vmstate_replace_hack_for_ppc() - ppc used to abuse vmstate_register * * Don't even think about using this function in new code. diff --git a/migration/savevm.c b/migration/savevm.c index cd2eabe..ec48da9 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -957,6 +957,38 @@ err: return -1; } +typedef struct VMStateInit { + VMStateIf *obj; + int instance_id; + const VMStateDescription *vmsd; + void *opaque; + QLIST_ENTRY(VMStateInit) next; +} VMStateInit; + +static QLIST_HEAD(, VMStateInit) vmstate_inits; + +void vmstate_register_init_add(VMStateIf *obj, int instance_id, + const VMStateDescription *vmsd, void *opaque) +{ + VMStateInit *v = g_new0(VMStateInit, 1); + + v->obj = obj; + v->instance_id = instance_id; + v->vmsd = vmsd; + v->opaque = opaque; + QLIST_INSERT_HEAD(&vmstate_inits, v, next); +} + +void vmstate_register_init_all(void) +{ + VMStateInit *v, *tmp; + + QLIST_FOREACH_SAFE(v, &vmstate_inits, next, tmp) { + vmstate_register(v->obj, v->instance_id, v->vmsd, v->opaque); + QLIST_REMOVE(v, next); + } +} + void vmstate_unregister(VMStateIf *obj, const VMStateDescription *vmsd, void *opaque) { diff --git a/system/vl.c b/system/vl.c index c644222..7797206 100644 --- a/system/vl.c +++ b/system/vl.c @@ -78,6 +78,7 @@ #include "hw/i386/pc.h" #include "migration/misc.h" #include "migration/snapshot.h" +#include "migration/vmstate.h" #include "sysemu/tpm.h" #include "sysemu/dma.h" #include "hw/audio/soundhw.h" @@ -3663,6 +3664,8 @@ void qemu_init(int argc, char **argv) qemu_create_machine(machine_opts_dict); + vmstate_register_init_all(); + suspend_mux_open(); qemu_disable_default_devices(); -- 1.8.3.1