[patch 3/4] QEMU/KVM: save and load mp state

Marcelo Tosatti
2008-04-07T20:30:48Z

[-- Attachment #1: use-mpstate-ioctls --]
[-- Type: text/plain, Size: 4409 bytes --]

Use the new interface to save and restore MP_STATE for all vcpu's.

Increase version_id for cpu_load/cpu_save.

Fixes SMP migration.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

Index: marcelo/git/kvm-userspace.io/qemu/qemu-kvm-x86.c
===================================================================
--- marcelo.orig/git/kvm-userspace.io/qemu/qemu-kvm-x86.c
+++ marcelo/git/kvm-userspace.io/qemu/qemu-kvm-x86.c
@@ -277,6 +277,24 @@ void kvm_arch_load_regs(CPUState *env)
perror("kvm_set_msrs FAILED");
}

+void kvm_save_mpstate(CPUState *env)
+{
+ int r;
+
+ r = kvm_get_mpstate(kvm_context, env->cpu_index, &env->mp_state);
+ if (r == -1)
+ env->mp_state = r;
+}
+
+void kvm_load_mpstate(CPUState *env)
+{
+ /*
+ * -1 indicates that the host did not support GET_MP_STATE ioctl,
+ * so don't touch it.
+ */
+ if (env->mp_state != -1)
+ kvm_set_mpstate(kvm_context, env->cpu_index, &env->mp_state);
+}

void kvm_arch_save_regs(CPUState *env)
{
Index: marcelo/git/kvm-userspace.io/qemu/qemu-kvm.h
===================================================================
--- marcelo.orig/git/kvm-userspace.io/qemu/qemu-kvm.h
+++ marcelo/git/kvm-userspace.io/qemu/qemu-kvm.h
@@ -18,6 +18,8 @@ int kvm_init_ap(void);
void kvm_qemu_destroy(void);
void kvm_load_registers(CPUState *env);
void kvm_save_registers(CPUState *env);
+void kvm_load_mpstate(CPUState *env);
+void kvm_save_mpstate(CPUState *env);
int kvm_cpu_exec(CPUState *env);
int kvm_update_debugger(CPUState *env);
int kvm_qemu_init_env(CPUState *env);
Index: marcelo/git/kvm-userspace.io/qemu/target-i386/cpu.h
===================================================================
--- marcelo.orig/git/kvm-userspace.io/qemu/target-i386/cpu.h
+++ marcelo/git/kvm-userspace.io/qemu/target-i386/cpu.h
@@ -599,6 +599,7 @@ typedef struct CPUX86State {
/* in order to simplify APIC support, we leave this pointer to the
user */
struct APICState *apic_state;
+ int mp_state;
} CPUX86State;

CPUX86State *cpu_x86_init(const char *cpu_model);
Index: marcelo/git/kvm-userspace.io/qemu/vl.c
===================================================================
--- marcelo.orig/git/kvm-userspace.io/qemu/vl.c
+++ marcelo/git/kvm-userspace.io/qemu/vl.c
@@ -6655,8 +6655,10 @@ void cpu_save(QEMUFile *f, void *opaque)
uint32_t hflags;
int i;

- if (kvm_enabled())
+ if (kvm_enabled()) {
kvm_save_registers(env);
+ kvm_save_mpstate(env);
+ }

for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
@@ -6748,6 +6750,7 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_be32s(f, &env->kvm_interrupt_bitmap[i]);
}
qemu_put_be64s(f, &env->tsc);
+ qemu_put_be32s(f, &env->mp_state);
}
}

@@ -6782,7 +6785,7 @@ int cpu_load(QEMUFile *f, void *opaque,
uint32_t hflags;
uint16_t fpus, fpuc, fptag, fpregs_format;

- if (version_id != 3 && version_id != 4)
+ if (version_id < 3 || version_id > 5)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
qemu_get_betls(f, &env->regs[i]);
@@ -6900,6 +6903,10 @@ int cpu_load(QEMUFile *f, void *opaque,
}
qemu_get_be64s(f, &env->tsc);
kvm_load_registers(env);
+ if (version_id >= 5) {
+ qemu_get_be32s(f, &env->mp_state);
+ kvm_load_mpstate(env);
+ }
}
return 0;
}
Index: marcelo/git/kvm-userspace.io/qemu/hw/pc.c
===================================================================
--- marcelo.orig/git/kvm-userspace.io/qemu/hw/pc.c
+++ marcelo/git/kvm-userspace.io/qemu/hw/pc.c
@@ -750,7 +750,7 @@ CPUState *pc_new_cpu(int cpu, const char
/* XXX: enable it in all cases */
env->cpuid_features |= CPUID_APIC;
}
- register_savevm("cpu", cpu, 4, cpu_save, cpu_load, env);
+ register_savevm("cpu", cpu, 5, cpu_save, cpu_load, env);
qemu_register_reset(main_cpu_reset, env);
if (pci_enabled) {
apic_init(env);