| Submitter | Christian Borntraeger |
|---|---|
| Date | Nov. 21, 2012, 2:46 p.m. |
| Message ID | <1353509165-26865-4-git-send-email-borntraeger@de.ibm.com> |
| Download | mbox | patch |
| Permalink | /patch/200788/ |
| State | New |
| Headers | show |
Comments
On 11/21/2012 03:46 PM, Christian Borntraeger wrote: > From: Heinz Graalfs<graalfs@linux.vnet.ibm.com> > > This patch adds the necessary life migration pieces to the sclp code. Juan, could you please review and note whether it's possible to use VMSTATE for this? :) Alex > > Signed-off-by: Heinz Graalfs<graalfs@linux.vnet.ibm.com> > Signed-off-by: Christian Borntraeger<borntraeger@de.ibm.com> > --- > hw/s390x/event-facility.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ > hw/s390x/event-facility.h | 3 +++ > hw/s390x/sclpconsole.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ > hw/s390x/sclpquiesce.c | 18 ++++++++++++++++++ > 4 files changed, 113 insertions(+) > > diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c > index 9367660..47a1bab 100644 > --- a/hw/s390x/event-facility.c > +++ b/hw/s390x/event-facility.c > @@ -312,6 +312,49 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) > } > } > > +static void event_facility_save(QEMUFile *f, void *opaque) > +{ > + S390SCLPDevice *sdev = opaque; > + BusChild *kid; > + SCLPEvent *event; > + SCLPEventClass *event_class; > + > + qemu_put_be32(f, sdev->ef->receive_mask); > + > + QTAILQ_FOREACH(kid,&sdev->ef->sbus.qbus.children, sibling) { > + DeviceState *qdev = kid->child; > + event = DO_UPCAST(SCLPEvent, qdev, qdev); > + event_class = SCLP_EVENT_GET_CLASS(event); > + if (event_class->save) { > + event_class->save(f, event); > + } > + } > +} > + > +static int event_facility_load(QEMUFile *f, void *opaque, int version_id) > +{ > + S390SCLPDevice *sdev = opaque; > + int rc = 0; > + BusChild *kid; > + SCLPEvent *event; > + SCLPEventClass *event_class; > + > + sdev->ef->receive_mask = qemu_get_be32(f); > + > + QTAILQ_FOREACH(kid,&sdev->ef->sbus.qbus.children, sibling) { > + DeviceState *qdev = kid->child; > + event = DO_UPCAST(SCLPEvent, qdev, qdev); > + event_class = SCLP_EVENT_GET_CLASS(event); > + if (event_class->load) { > + rc = event_class->load(f, event, version_id); > + if (rc) { > + break; > + } > + } > + } > + return rc; > +} > + > static int init_event_facility(S390SCLPDevice *sdev) > { > SCLPEventFacility *event_facility; > @@ -334,6 +377,9 @@ static int init_event_facility(S390SCLPDevice *sdev) > } > qdev_init_nofail(quiesce); > > + register_savevm(&sdev->busdev.qdev, "event-facility", -1, 0, > + event_facility_save, event_facility_load, sdev); > + > return 0; > } > > diff --git a/hw/s390x/event-facility.h b/hw/s390x/event-facility.h > index 30af0a7..4405022 100644 > --- a/hw/s390x/event-facility.h > +++ b/hw/s390x/event-facility.h > @@ -91,6 +91,9 @@ typedef struct SCLPEventClass { > /* returns the supported event type */ > int (*event_type)(void); > > + /* live migration */ > + int (*load)(QEMUFile *f, void *opaque, int version_id); > + void (*save)(QEMUFile *f, void *opaque); > } SCLPEventClass; > > #endif > diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c > index 0ec5623..96168a1 100644 > --- a/hw/s390x/sclpconsole.c > +++ b/hw/s390x/sclpconsole.c > @@ -243,6 +243,50 @@ static void trigger_ascii_console_data(void *env, int n, int level) > /* qemu object creation and initialization functions */ > > /* tell character layer our call-back functions */ > + > +static void console_save(QEMUFile *f, void *opaque) > +{ > + SCLPConsole *scon = opaque; > + > + if (!scon->iov) { > + return; > + } > + > + qemu_put_be16(f, scon->event.event_pending ? 1 : 0); > + qemu_put_be32(f, scon->iov_data_len); > + qemu_put_be32(f, scon->iov_sclp_rest); > + qemu_put_be32(f, scon->iov_sclp - scon->iov); > + qemu_put_be32(f, scon->iov_bs - scon->iov); > + if (scon->event.event_pending) { > + qemu_put_buffer(f, scon->iov, SIZE_BUFFER_VT220); > + } > +} > + > +static int console_load(QEMUFile *f, void *opaque, int version_id) > +{ > + SCLPConsole *scon = opaque; > + int l; > + > + if (!scon->iov) { > + scon->iov = g_malloc0(SIZE_BUFFER_VT220); > + } > + > + scon->event.event_pending = qemu_get_be16(f) ? true : false; > + scon->iov_data_len = qemu_get_be32(f); > + scon->iov_sclp_rest = qemu_get_be32(f); > + scon->iov_bs = scon->iov + qemu_get_be32(f); > + scon->iov_sclp = scon->iov + qemu_get_be32(f); > + if (scon->event.event_pending) { > + l = qemu_get_buffer(f, scon->iov, SIZE_BUFFER_VT220); > + if (l != SIZE_BUFFER_VT220) { > + error_report("Failed to restore SCLP console buffer."); > + return -1; > + } > + } > + > + return 0; > +} > + > static int console_init(SCLPEvent *event) > { > static bool console_available; > @@ -288,6 +332,8 @@ static void console_class_init(ObjectClass *klass, void *data) > ec->event_type = event_type; > ec->read_event_data = read_event_data; > ec->write_event_data = write_event_data; > + ec->load = console_load; > + ec->save = console_save; > } > > static TypeInfo sclp_console_info = { > diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c > index 9a773b8..e12fb7c 100644 > --- a/hw/s390x/sclpquiesce.c > +++ b/hw/s390x/sclpquiesce.c > @@ -65,6 +65,22 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, > return 1; > } > > +static void quiesce_save(QEMUFile *f, void *opaque) > +{ > + SCLPEvent *event = opaque; > + > + qemu_put_be16(f, event->event_pending ? 1 : 0); > +} > + > +static int quiesce_load(QEMUFile *f, void *opaque, int version_id) > +{ > + SCLPEvent *event = opaque; > + > + event->event_pending = qemu_get_be16(f) ? true : false; > + > + return 0; > +} > + > typedef struct QuiesceNotifier QuiesceNotifier; > > static struct QuiesceNotifier { > @@ -105,6 +121,8 @@ static void quiesce_class_init(ObjectClass *klass, void *data) > k->event_type = event_type; > k->read_event_data = read_event_data; > k->write_event_data = NULL; > + k->load = quiesce_load; > + k->save = quiesce_save; > } > > static TypeInfo sclp_quiesce_info = {
Patch
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 9367660..47a1bab 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -312,6 +312,49 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } +static void event_facility_save(QEMUFile *f, void *opaque) +{ + S390SCLPDevice *sdev = opaque; + BusChild *kid; + SCLPEvent *event; + SCLPEventClass *event_class; + + qemu_put_be32(f, sdev->ef->receive_mask); + + QTAILQ_FOREACH(kid, &sdev->ef->sbus.qbus.children, sibling) { + DeviceState *qdev = kid->child; + event = DO_UPCAST(SCLPEvent, qdev, qdev); + event_class = SCLP_EVENT_GET_CLASS(event); + if (event_class->save) { + event_class->save(f, event); + } + } +} + +static int event_facility_load(QEMUFile *f, void *opaque, int version_id) +{ + S390SCLPDevice *sdev = opaque; + int rc = 0; + BusChild *kid; + SCLPEvent *event; + SCLPEventClass *event_class; + + sdev->ef->receive_mask = qemu_get_be32(f); + + QTAILQ_FOREACH(kid, &sdev->ef->sbus.qbus.children, sibling) { + DeviceState *qdev = kid->child; + event = DO_UPCAST(SCLPEvent, qdev, qdev); + event_class = SCLP_EVENT_GET_CLASS(event); + if (event_class->load) { + rc = event_class->load(f, event, version_id); + if (rc) { + break; + } + } + } + return rc; +} + static int init_event_facility(S390SCLPDevice *sdev) { SCLPEventFacility *event_facility; @@ -334,6 +377,9 @@ static int init_event_facility(S390SCLPDevice *sdev) } qdev_init_nofail(quiesce); + register_savevm(&sdev->busdev.qdev, "event-facility", -1, 0, + event_facility_save, event_facility_load, sdev); + return 0; } diff --git a/hw/s390x/event-facility.h b/hw/s390x/event-facility.h index 30af0a7..4405022 100644 --- a/hw/s390x/event-facility.h +++ b/hw/s390x/event-facility.h @@ -91,6 +91,9 @@ typedef struct SCLPEventClass { /* returns the supported event type */ int (*event_type)(void); + /* live migration */ + int (*load)(QEMUFile *f, void *opaque, int version_id); + void (*save)(QEMUFile *f, void *opaque); } SCLPEventClass; #endif diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c index 0ec5623..96168a1 100644 --- a/hw/s390x/sclpconsole.c +++ b/hw/s390x/sclpconsole.c @@ -243,6 +243,50 @@ static void trigger_ascii_console_data(void *env, int n, int level) /* qemu object creation and initialization functions */ /* tell character layer our call-back functions */ + +static void console_save(QEMUFile *f, void *opaque) +{ + SCLPConsole *scon = opaque; + + if (!scon->iov) { + return; + } + + qemu_put_be16(f, scon->event.event_pending ? 1 : 0); + qemu_put_be32(f, scon->iov_data_len); + qemu_put_be32(f, scon->iov_sclp_rest); + qemu_put_be32(f, scon->iov_sclp - scon->iov); + qemu_put_be32(f, scon->iov_bs - scon->iov); + if (scon->event.event_pending) { + qemu_put_buffer(f, scon->iov, SIZE_BUFFER_VT220); + } +} + +static int console_load(QEMUFile *f, void *opaque, int version_id) +{ + SCLPConsole *scon = opaque; + int l; + + if (!scon->iov) { + scon->iov = g_malloc0(SIZE_BUFFER_VT220); + } + + scon->event.event_pending = qemu_get_be16(f) ? true : false; + scon->iov_data_len = qemu_get_be32(f); + scon->iov_sclp_rest = qemu_get_be32(f); + scon->iov_bs = scon->iov + qemu_get_be32(f); + scon->iov_sclp = scon->iov + qemu_get_be32(f); + if (scon->event.event_pending) { + l = qemu_get_buffer(f, scon->iov, SIZE_BUFFER_VT220); + if (l != SIZE_BUFFER_VT220) { + error_report("Failed to restore SCLP console buffer."); + return -1; + } + } + + return 0; +} + static int console_init(SCLPEvent *event) { static bool console_available; @@ -288,6 +332,8 @@ static void console_class_init(ObjectClass *klass, void *data) ec->event_type = event_type; ec->read_event_data = read_event_data; ec->write_event_data = write_event_data; + ec->load = console_load; + ec->save = console_save; } static TypeInfo sclp_console_info = { diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 9a773b8..e12fb7c 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -65,6 +65,22 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, return 1; } +static void quiesce_save(QEMUFile *f, void *opaque) +{ + SCLPEvent *event = opaque; + + qemu_put_be16(f, event->event_pending ? 1 : 0); +} + +static int quiesce_load(QEMUFile *f, void *opaque, int version_id) +{ + SCLPEvent *event = opaque; + + event->event_pending = qemu_get_be16(f) ? true : false; + + return 0; +} + typedef struct QuiesceNotifier QuiesceNotifier; static struct QuiesceNotifier { @@ -105,6 +121,8 @@ static void quiesce_class_init(ObjectClass *klass, void *data) k->event_type = event_type; k->read_event_data = read_event_data; k->write_event_data = NULL; + k->load = quiesce_load; + k->save = quiesce_save; } static TypeInfo sclp_quiesce_info = {