aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-04-11 13:24:43 -0300
committerAvi Kivity <avi@qumranet.com>2008-04-13 18:01:23 +0300
commit44631342f80fcb72bbe751c7b25d136921e529c9 (patch)
treee30c35ad3252b70db2c0704de0278ced0dadaac1
parent3a2685c85e790901f5c41be74e16e8492798e6d2 (diff)
Save and load mp state
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> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--hw/pc.c2
-rw-r--r--qemu-kvm-x86.c27
-rw-r--r--qemu-kvm.h2
-rw-r--r--target-i386/cpu.h1
-rw-r--r--vl.c11
5 files changed, 40 insertions, 3 deletions
diff --git a/hw/pc.c b/hw/pc.c
index aa9afeab6..ae87ab9b0 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -750,7 +750,7 @@ CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled)
/* 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);
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 7c344ed10..7cc219d5e 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -277,6 +277,33 @@ void kvm_arch_load_regs(CPUState *env)
perror("kvm_set_msrs FAILED");
}
+void kvm_save_mpstate(CPUState *env)
+{
+#ifdef KVM_CAP_MP_STATE
+ int r;
+ struct kvm_mp_state mp_state;
+
+ r = kvm_get_mpstate(kvm_context, env->cpu_index, &mp_state);
+ if (r < 0)
+ env->mp_state = -1;
+ else
+ env->mp_state = mp_state.mp_state;
+#endif
+}
+
+void kvm_load_mpstate(CPUState *env)
+{
+#ifdef KVM_CAP_MP_STATE
+ struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
+
+ /*
+ * -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, &mp_state);
+#endif
+}
void kvm_arch_save_regs(CPUState *env)
{
diff --git a/qemu-kvm.h b/qemu-kvm.h
index ae5ce1a6b..cae20bcd4 100644
--- a/qemu-kvm.h
+++ b/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);
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 7b0395ea6..a5c7d0ad3 100644
--- a/target-i386/cpu.h
+++ b/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);
diff --git a/vl.c b/vl.c
index 49d9af294..e544f7cdd 100644
--- a/vl.c
+++ b/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, int version_id)
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, int version_id)
}
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;
}