From: Paolo Bonzini <pbonzini@redhat.com>
To: Alex Bligh <alex@alex.org.uk>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: Amit Shah <amit.shah@redhat.com>, Cole Robinson <crobinso@redhat.com>
Subject: Re: [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm
Date: Sat, 26 Jul 2014 09:38:21 +0200 [thread overview]
Message-ID: <53D35AED.3020603@redhat.com> (raw)
In-Reply-To: <F4F256A6-06DC-4EB4-A2F1-A4B7C128E561@alex.org.uk>
Il 25/07/2014 18:01, Alex Bligh ha scritto:
> ping: anyone got any views on this one?
Just wait for 2.1 to get out of the door. :)
Paolo
> On 22 Jul 2014, at 19:43, Alex Bligh <alex@alex.org.uk> wrote:
>
>> Add a machine type pc-1.0-qemu-kvm for live migrate compatibility
>> with qemu-kvm version 1.0.
>>
>> Signed-off-by: Alex Bligh <alex@alex.org.uk>
>> ---
>> hw/acpi/piix4.c | 49 ++++++++++++++++++++++++++++++++++++++++++++--
>> hw/i386/pc_piix.c | 31 +++++++++++++++++++++++++++++
>> hw/timer/i8254_common.c | 41 ++++++++++++++++++++++++++++++++++++++
>> include/hw/acpi/piix4.h | 1 +
>> include/hw/timer/i8254.h | 2 ++
>> 5 files changed, 122 insertions(+), 2 deletions(-)
>>
>> This RFC patch adds inbound migrate capability from qemu-kvm version
>> 1.0. The main ideas are those set out in Cole Robinson's patch here:
>> http://pkgs.fedoraproject.org/cgit/qemu.git/tree/0001-Fix-migration-from-qemu-kvm.patch?h=f20
>> however, rather than patching statically (and breaking inbound
>> migration on existing machine types), I have added a new machine
>> type (pc-1.0-qemu-kvm) without affecting any other machine types.
>>
>> This requires 'hot patching' the VMStateDescription in a couple of
>> places, which in turn is less than obvious as there may be (indeed
>> are for i8259) derived classes. Whilst pretty nausea-inducing, this
>> approach has the benefit of being entirely self-contained.
>>
>> I developed this on qemu 2.0 but have forward ported it (trivially)
>> to master. My testing has been on a VM live-migrated-to-file from
>> Ubuntu Precise qemu-kvm 1.0. Testing has been light to date (i.e.
>> can I migrate it inbound with -S without anything complaining).
>>
>> I have not (yet) brought forward the qxl rom size (and possibly
>> video ram) changes in Cole's patches as I'd prefer an assessment
>> of whether this is the right approach first.
>>
>> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
>> index b72b34e..708db79 100644
>> --- a/hw/acpi/piix4.c
>> +++ b/hw/acpi/piix4.c
>> @@ -267,8 +267,9 @@ static const VMStateDescription vmstate_memhp_state = {
>> };
>>
>> /* qemu-kvm 1.2 uses version 3 but advertised as 2
>> - * To support incoming qemu-kvm 1.2 migration, change version_id
>> - * and minimum_version_id to 2 below (which breaks migration from
>> + * To support incoming qemu-kvm 1.2 migration, we support
>> + * via a command line option a change to minimum_version_id
>> + * of 2 in a _compat structure (which breaks migration from
>> * qemu 1.2).
>> *
>> */
>> @@ -307,6 +308,34 @@ static const VMStateDescription vmstate_acpi = {
>> }
>> };
>>
>> +static const VMStateDescription vmstate_acpi_compat = {
>> + .name = "piix4_pm",
>> + .version_id = 3,
>> + .minimum_version_id = 2,
>> + .minimum_version_id_old = 1,
>> + .load_state_old = acpi_load_old,
>> + .post_load = vmstate_acpi_post_load,
>> + .fields = (VMStateField[]) {
>> + VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
>> + VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
>> + VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
>> + VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
>> + VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
>> + VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
>> + VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
>> + VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
>> + VMSTATE_STRUCT_TEST(
>> + acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT],
>> + PIIX4PMState,
>> + vmstate_test_no_use_acpi_pci_hotplug,
>> + 2, vmstate_pci_status,
>> + struct AcpiPciHpPciStatus),
>> + VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
>> + vmstate_test_use_acpi_pci_hotplug),
>> + VMSTATE_END_OF_LIST()
>> + }
>> +};
>> +
>> static void piix4_reset(void *opaque)
>> {
>> PIIX4PMState *s = opaque;
>> @@ -619,6 +648,22 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
>> adevc->ospm_status = piix4_ospm_status;
>> }
>>
>> +void piix4_pm_class_fix_compat(void)
>> +{
>> + GSList *el, *devices = object_class_get_list(TYPE_DEVICE, false);
>> + /*
>> + * Change the vmstate field in this class and any derived classes
>> + * if not overriden. As no other classes should be using this
>> + * vmstate, we can simply iterate the class list
>> + */
>> + for (el = devices; el; el = el->next) {
>> + DeviceClass *dc = el->data;
>> + if (dc->vmsd == &vmstate_acpi) {
>> + dc->vmsd = &vmstate_acpi_compat;
>> + }
>> + }
>> +}
>> +
>> static const TypeInfo piix4_pm_info = {
>> .name = TYPE_PIIX4_PM,
>> .parent = TYPE_PCI_DEVICE,
>> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
>> index 7081c08..e400ea6 100644
>> --- a/hw/i386/pc_piix.c
>> +++ b/hw/i386/pc_piix.c
>> @@ -49,6 +49,8 @@
>> #include "hw/acpi/acpi.h"
>> #include "cpu.h"
>> #include "qemu/error-report.h"
>> +#include "hw/acpi/piix4.h"
>> +#include "hw/timer/i8254.h"
>> #ifdef CONFIG_XEN
>> # include <xen/hvm/hvm_info_table.h>
>> #endif
>> @@ -386,6 +388,15 @@ static void pc_init_pci_1_2(MachineState *machine)
>> pc_init_pci(machine);
>> }
>>
>> +/* PC machine init function for qemu-kvm 1.0 */
>> +static void pc_init_pci_1_2_qemu_kvm(MachineState *machine)
>> +{
>> + piix4_pm_class_fix_compat();
>> + pit_common_class_fix_compat();
>> + pc_compat_1_2(machine);
>> + pc_init_pci(machine);
>> +}
>> +
>> /* PC init function for pc-0.10 to pc-0.13 */
>> static void pc_init_pci_no_kvmclock(MachineState *machine)
>> {
>> @@ -644,6 +655,25 @@ static QEMUMachine pc_machine_v1_0 = {
>> .hw_version = "1.0",
>> };
>>
>> +#define PC_COMPAT_1_0_QEMU_KVM \
>> + PC_COMPAT_1_0,\
>> + {\
>> + .driver = "cirrus-vga",\
>> + .property = "vgamem_mb",\
>> + .value = stringify(16),\
>> + }
>> +
>> +static QEMUMachine pc_machine_v1_0_qemu_kvm = {
>> + PC_I440FX_1_2_MACHINE_OPTIONS,
>> + .name = "pc-1.0-qemu-kvm",
>> + .init = pc_init_pci_1_2_qemu_kvm,
>> + .compat_props = (GlobalProperty[]) {
>> + PC_COMPAT_1_0_QEMU_KVM,
>> + { /* end of list */ }
>> + },
>> + .hw_version = "1.0",
>> +};
>> +
>> #define PC_COMPAT_0_15 \
>> PC_COMPAT_1_0
>>
>> @@ -886,6 +916,7 @@ static void pc_machine_init(void)
>> qemu_register_pc_machine(&pc_machine_v1_2);
>> qemu_register_pc_machine(&pc_machine_v1_1);
>> qemu_register_pc_machine(&pc_machine_v1_0);
>> + qemu_register_pc_machine(&pc_machine_v1_0_qemu_kvm);
>> qemu_register_pc_machine(&pc_machine_v0_15);
>> qemu_register_pc_machine(&pc_machine_v0_14);
>> qemu_register_pc_machine(&pc_machine_v0_13);
>> diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
>> index 07345f6..511ea05 100644
>> --- a/hw/timer/i8254_common.c
>> +++ b/hw/timer/i8254_common.c
>> @@ -275,6 +275,29 @@ static const VMStateDescription vmstate_pit_common = {
>> }
>> };
>>
>> +static const VMStateDescription vmstate_pit_common_compat = {
>> + .name = "i8254",
>> + .version_id = 3,
>> + .minimum_version_id = 2,
>> + .minimum_version_id_old = 1,
>> + .load_state_old = pit_load_old,
>> + .pre_save = pit_dispatch_pre_save,
>> + .post_load = pit_dispatch_post_load,
>> + .fields = (VMStateField[]) {
>> + /* qemu-kvm version_id=2 had 'flags' here which is equivalent
>> + * This fixes incoming migration from qemu-kvm 1.0, but breaks
>> + * incoming migration from qemu < 1.1
>> + */
>> + /* VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), */
>> + VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState),
>> + VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
>> + vmstate_pit_channel, PITChannelState),
>> + VMSTATE_INT64(channels[0].next_transition_time,
>> + PITCommonState), /* formerly irq_timer */
>> + VMSTATE_END_OF_LIST()
>> + }
>> +};
>> +
>> static void pit_common_class_init(ObjectClass *klass, void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> @@ -289,6 +312,24 @@ static void pit_common_class_init(ObjectClass *klass, void *data)
>> dc->cannot_instantiate_with_device_add_yet = true;
>> }
>>
>> +void pit_common_class_fix_compat(void)
>> +{
>> + GSList *el, *devices = object_class_get_list(TYPE_DEVICE, false);
>> + /*
>> + * Change the vmstate field in this class and any derived classes
>> + * if not overriden. As no other classes should be using this
>> + * vmstate, we can simply iterate the class list
>> + */
>> + for (el = devices; el; el = el->next) {
>> + DeviceClass *dc = el->data;
>> + if (dc->vmsd == &vmstate_pit_common) {
>> + dc->vmsd = &vmstate_pit_common_compat;
>> + }
>> + }
>> +
>> + g_slist_free(devices);
>> +}
>> +
>> static const TypeInfo pit_common_type = {
>> .name = TYPE_PIT_COMMON,
>> .parent = TYPE_ISA_DEVICE,
>> diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h
>> index 65e6fd7..811d88f 100644
>> --- a/include/hw/acpi/piix4.h
>> +++ b/include/hw/acpi/piix4.h
>> @@ -4,5 +4,6 @@
>> #include "qemu/typedefs.h"
>>
>> Object *piix4_pm_find(void);
>> +void piix4_pm_class_fix_compat(void);
>>
>> #endif
>> diff --git a/include/hw/timer/i8254.h b/include/hw/timer/i8254.h
>> index 4349033..0126424 100644
>> --- a/include/hw/timer/i8254.h
>> +++ b/include/hw/timer/i8254.h
>> @@ -72,4 +72,6 @@ static inline ISADevice *kvm_pit_init(ISABus *bus, int base)
>> void pit_set_gate(ISADevice *dev, int channel, int val);
>> void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info);
>>
>> +void pit_common_class_fix_compat(void);
>> +
>> #endif /* !HW_I8254_H */
>> --
>> 1.7.9.5
>>
>>
>>
>
next prev parent reply other threads:[~2014-07-26 7:38 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-22 18:43 [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm Alex Bligh
2014-07-25 16:01 ` Alex Bligh
2014-07-26 7:38 ` Paolo Bonzini [this message]
2014-07-27 13:09 ` Alex Bligh
2014-07-27 14:10 ` Andreas Färber
2014-07-27 17:04 ` Alex Bligh
2014-07-27 21:03 ` Alex Bligh
2014-07-29 4:16 ` Serge Hallyn
2014-07-29 7:31 ` Alex Bligh
2014-07-29 13:03 ` Serge E. Hallyn
2014-07-29 13:15 ` Alex Bligh
2014-07-29 13:21 ` Paolo Bonzini
2014-07-29 13:27 ` Serge Hallyn
2014-07-29 13:35 ` Paolo Bonzini
2014-07-29 13:39 ` Alex Bligh
2014-07-29 13:42 ` Paolo Bonzini
2014-07-29 13:56 ` Alex Bligh
2014-07-29 14:00 ` Paolo Bonzini
2014-07-29 15:05 ` Alex Bligh
2014-07-29 13:41 ` Serge Hallyn
2014-07-29 13:38 ` Alex Bligh
2014-07-29 13:41 ` Serge Hallyn
2014-08-04 13:34 ` Michael S. Tsirkin
2014-08-04 15:08 ` Serge Hallyn
2014-08-04 15:26 ` Michael S. Tsirkin
2014-08-04 15:38 ` Serge Hallyn
2014-08-04 15:47 ` Alex Bligh
2014-08-04 16:13 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53D35AED.3020603@redhat.com \
--to=pbonzini@redhat.com \
--cc=alex@alex.org.uk \
--cc=amit.shah@redhat.com \
--cc=crobinso@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.