diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-04-11 13:24:43 -0300 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-13 18:01:23 +0300 |
commit | 44631342f80fcb72bbe751c7b25d136921e529c9 (patch) | |
tree | e30c35ad3252b70db2c0704de0278ced0dadaac1 | |
parent | 3a2685c85e790901f5c41be74e16e8492798e6d2 (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.c | 2 | ||||
-rw-r--r-- | qemu-kvm-x86.c | 27 | ||||
-rw-r--r-- | qemu-kvm.h | 2 | ||||
-rw-r--r-- | target-i386/cpu.h | 1 | ||||
-rw-r--r-- | vl.c | 11 |
5 files changed, 40 insertions, 3 deletions
@@ -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); @@ -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; } |