mirror of https://github.com/xqemu/xqemu.git
apic: Use apic_id as apic's migration instance_id
instance_id is generated by last_used_id + 1 for a given device type so for QEMU with 3 CPUs instance_id for APICs is a seti of [0, 1, 2] When CPU in the middle is hot-removed and migration started APICs with instance_ids 0 and 2 are transferred in migration stream. However target starts with 2 CPUs and APICs' instance_ids are generated from scratch [0, 1] hence migration fails with error Unknown savevm section or instance 'apic' 2 Fix issue by manually registering APIC's vmsd with apic_id as instance_id, in this case instance_id on target will always match instance_id on source as apic_id is the same for a given cpu instance. Reported-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
parent
9c156f9de5
commit
f6e984443f
|
@ -294,11 +294,14 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_apic_common;
|
||||||
|
|
||||||
static void apic_common_realize(DeviceState *dev, Error **errp)
|
static void apic_common_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
APICCommonState *s = APIC_COMMON(dev);
|
APICCommonState *s = APIC_COMMON(dev);
|
||||||
APICCommonClass *info;
|
APICCommonClass *info;
|
||||||
static DeviceState *vapic;
|
static DeviceState *vapic;
|
||||||
|
int instance_id = s->id;
|
||||||
|
|
||||||
info = APIC_COMMON_GET_CLASS(s);
|
info = APIC_COMMON_GET_CLASS(s);
|
||||||
info->realize(dev, errp);
|
info->realize(dev, errp);
|
||||||
|
@ -313,6 +316,11 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
|
||||||
info->enable_tpr_reporting(s, true);
|
info->enable_tpr_reporting(s, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->legacy_instance_id) {
|
||||||
|
instance_id = -1;
|
||||||
|
}
|
||||||
|
vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common,
|
||||||
|
s, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apic_common_unrealize(DeviceState *dev, Error **errp)
|
static void apic_common_unrealize(DeviceState *dev, Error **errp)
|
||||||
|
@ -320,6 +328,7 @@ static void apic_common_unrealize(DeviceState *dev, Error **errp)
|
||||||
APICCommonState *s = APIC_COMMON(dev);
|
APICCommonState *s = APIC_COMMON(dev);
|
||||||
APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
|
APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
|
||||||
|
|
||||||
|
vmstate_unregister(NULL, &vmstate_apic_common, s);
|
||||||
info->unrealize(dev, errp);
|
info->unrealize(dev, errp);
|
||||||
|
|
||||||
if (apic_report_tpr_access && info->enable_tpr_reporting) {
|
if (apic_report_tpr_access && info->enable_tpr_reporting) {
|
||||||
|
@ -422,6 +431,8 @@ static Property apic_properties_common[] = {
|
||||||
DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14),
|
DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14),
|
||||||
DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT,
|
DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT,
|
||||||
true),
|
true),
|
||||||
|
DEFINE_PROP_BOOL("legacy-instance-id", APICCommonState, legacy_instance_id,
|
||||||
|
false),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -429,7 +440,6 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
dc->vmsd = &vmstate_apic_common;
|
|
||||||
dc->reset = apic_reset_common;
|
dc->reset = apic_reset_common;
|
||||||
dc->props = apic_properties_common;
|
dc->props = apic_properties_common;
|
||||||
dc->realize = apic_common_realize;
|
dc->realize = apic_common_realize;
|
||||||
|
|
|
@ -183,6 +183,7 @@ struct APICCommonState {
|
||||||
uint32_t vapic_control;
|
uint32_t vapic_control;
|
||||||
DeviceState *vapic;
|
DeviceState *vapic;
|
||||||
hwaddr vapic_paddr; /* note: persistence via kvmvapic */
|
hwaddr vapic_paddr; /* note: persistence via kvmvapic */
|
||||||
|
bool legacy_instance_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct VAPICState {
|
typedef struct VAPICState {
|
||||||
|
|
|
@ -382,6 +382,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
||||||
.driver = TYPE_X86_CPU,\
|
.driver = TYPE_X86_CPU,\
|
||||||
.property = "fill-mtrr-mask",\
|
.property = "fill-mtrr-mask",\
|
||||||
.value = "off",\
|
.value = "off",\
|
||||||
|
},\
|
||||||
|
{\
|
||||||
|
.driver = "apic",\
|
||||||
|
.property = "legacy-instance-id",\
|
||||||
|
.value = "on",\
|
||||||
},
|
},
|
||||||
|
|
||||||
#define PC_COMPAT_2_5 \
|
#define PC_COMPAT_2_5 \
|
||||||
|
|
Loading…
Reference in New Issue