Message ID | 20231005113027.1827078-2-marcandre.lureau@redhat.com |
---|---|
State | New |
Headers | show |
Series | WIP: ramfb: migration support | expand |
On 10/5/23 13:30, marcandre.lureau@redhat.com wrote: > From: Marc-André Lureau <marcandre.lureau@redhat.com> > > Implementing RAMFB migration is quite straightforward. One caveat is to > treat the whole RAMFBCfg as a blob, since that's what is exposed to the > guest directly. This avoid having to fiddle with endianness issues if we > were to migrate fields individually as integers. > > The devices using RAMFB will have to include ramfb_vmstate in their > migration description. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> > --- > include/hw/display/ramfb.h | 4 ++++ > hw/display/ramfb.c | 19 +++++++++++++++++++ > 2 files changed, 23 insertions(+) > > diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h > index b33a2c467b..a7e0019144 100644 > --- a/include/hw/display/ramfb.h > +++ b/include/hw/display/ramfb.h > @@ -1,11 +1,15 @@ > #ifndef RAMFB_H > #define RAMFB_H > > +#include "migration/vmstate.h" > + > /* ramfb.c */ > typedef struct RAMFBState RAMFBState; > void ramfb_display_update(QemuConsole *con, RAMFBState *s); > RAMFBState *ramfb_setup(Error **errp); > > +extern const VMStateDescription ramfb_vmstate; > + > /* ramfb-standalone.c */ > #define TYPE_RAMFB_DEVICE "ramfb" > > diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c > index c2b002d534..477ef7272a 100644 > --- a/hw/display/ramfb.c > +++ b/hw/display/ramfb.c > @@ -28,6 +28,8 @@ struct QEMU_PACKED RAMFBCfg { > uint32_t stride; > }; > > +typedef struct RAMFBCfg RAMFBCfg; > + > struct RAMFBState { > DisplaySurface *ds; > uint32_t width, height; > @@ -116,6 +118,23 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) > dpy_gfx_update_full(con); > } > > +static int ramfb_post_load(void *opaque, int version_id) > +{ > + ramfb_fw_cfg_write(opaque, 0, 0); > + return 0; > +} > + > +const VMStateDescription ramfb_vmstate = { > + .name = "ramfb", > + .version_id = 1, > + .minimum_version_id = 1, > + .post_load = ramfb_post_load, > + .fields = (VMStateField[]) { > + VMSTATE_BUFFER_UNSAFE(cfg, RAMFBState, 0, sizeof(RAMFBCfg)), > + VMSTATE_END_OF_LIST() > + } > +}; > + > RAMFBState *ramfb_setup(Error **errp) > { > FWCfgState *fw_cfg = fw_cfg_find(); Identical to v3, which I reviewed, so: Reviewed-by: Laszlo Ersek <lersek@redhat.com>
diff --git a/include/hw/display/ramfb.h b/include/hw/display/ramfb.h index b33a2c467b..a7e0019144 100644 --- a/include/hw/display/ramfb.h +++ b/include/hw/display/ramfb.h @@ -1,11 +1,15 @@ #ifndef RAMFB_H #define RAMFB_H +#include "migration/vmstate.h" + /* ramfb.c */ typedef struct RAMFBState RAMFBState; void ramfb_display_update(QemuConsole *con, RAMFBState *s); RAMFBState *ramfb_setup(Error **errp); +extern const VMStateDescription ramfb_vmstate; + /* ramfb-standalone.c */ #define TYPE_RAMFB_DEVICE "ramfb" diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index c2b002d534..477ef7272a 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -28,6 +28,8 @@ struct QEMU_PACKED RAMFBCfg { uint32_t stride; }; +typedef struct RAMFBCfg RAMFBCfg; + struct RAMFBState { DisplaySurface *ds; uint32_t width, height; @@ -116,6 +118,23 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) dpy_gfx_update_full(con); } +static int ramfb_post_load(void *opaque, int version_id) +{ + ramfb_fw_cfg_write(opaque, 0, 0); + return 0; +} + +const VMStateDescription ramfb_vmstate = { + .name = "ramfb", + .version_id = 1, + .minimum_version_id = 1, + .post_load = ramfb_post_load, + .fields = (VMStateField[]) { + VMSTATE_BUFFER_UNSAFE(cfg, RAMFBState, 0, sizeof(RAMFBCfg)), + VMSTATE_END_OF_LIST() + } +}; + RAMFBState *ramfb_setup(Error **errp) { FWCfgState *fw_cfg = fw_cfg_find();