aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>2014-08-28 15:18:57 +0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-11-13 16:13:27 +0100
commitc2c00148ec54f77c9432fec16585834e1d677fda (patch)
treeb9088d3d9d429fcada0cdaa835f366925939c472
parentae67dc72e4f19238941894227d96b6201d71a70a (diff)
apic_common: migrate missing fields
This patch adds missed sipi_vector and wait_for_sipi fields to a new subsection of the vmstate of the apic_common module. Saving and loading of these fields makes migration of the apic state deterministic. Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> [Initialize the field in pre_load and kvm_apic_realize. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--hw/i386/kvm/apic.c3
-rw-r--r--hw/intc/apic_common.c38
2 files changed, 41 insertions, 0 deletions
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index e873b509a5..271e97f86f 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -175,6 +175,9 @@ static void kvm_apic_realize(DeviceState *dev, Error **errp)
{
APICCommonState *s = APIC_COMMON(dev);
+ /* Not used by KVM, which uses the CPU mp_state instead. */
+ s->wait_for_sipi = 0;
+
memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi",
APIC_SPACE_SIZE);
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index ce3d903b13..4e62f25edb 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -324,6 +324,19 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
}
+static int apic_pre_load(void *opaque)
+{
+ APICCommonState *s = APIC_COMMON(opaque);
+
+ /* The default is !cpu_is_bsp(s->cpu), but the common value is 0
+ * so that's what apic_common_sipi_needed checks for. Reset to
+ * the value that is assumed when the apic_sipi subsection is
+ * absent.
+ */
+ s->wait_for_sipi = 0;
+ return 0;
+}
+
static void apic_dispatch_pre_save(void *opaque)
{
APICCommonState *s = APIC_COMMON(opaque);
@@ -345,12 +358,30 @@ static int apic_dispatch_post_load(void *opaque, int version_id)
return 0;
}
+static bool apic_common_sipi_needed(void *opaque)
+{
+ APICCommonState *s = APIC_COMMON(opaque);
+ return s->wait_for_sipi != 0;
+}
+
+static const VMStateDescription vmstate_apic_common_sipi = {
+ .name = "apic_sipi",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(sipi_vector, APICCommonState),
+ VMSTATE_INT32(wait_for_sipi, APICCommonState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_apic_common = {
.name = "apic",
.version_id = 3,
.minimum_version_id = 3,
.minimum_version_id_old = 1,
.load_state_old = apic_load_old,
+ .pre_load = apic_pre_load,
.pre_save = apic_dispatch_pre_save,
.post_load = apic_dispatch_post_load,
.fields = (VMStateField[]) {
@@ -375,6 +406,13 @@ static const VMStateDescription vmstate_apic_common = {
VMSTATE_INT64(timer_expiry,
APICCommonState), /* open-coded timer state */
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection[]) {
+ {
+ .vmsd = &vmstate_apic_common_sipi,
+ .needed = apic_common_sipi_needed,
+ },
+ VMSTATE_END_OF_LIST()
}
};